From a8ce265e51dfbb6cf47d21eb707349a25f9b3c30 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Wed, 30 Nov 2022 23:56:27 +0300 Subject: [PATCH 01/45] Add poetry --- .drone.yml | 149 --- .github/workflows/tests.yml | 204 ++++ .github/workflows/tox.yml | 157 --- .pre-commit-config.yaml | 6 +- README.rst | 11 +- aiomisc/compat.py | 3 +- aiomisc/version.py | 4 +- .gray => gray.conf | 2 +- poetry.lock | 2102 +++++++++++++++++++++++++++++++++++ pylama.ini | 9 + pylava.ini | 6 - pyproject.toml | 102 ++ requirements.dev.txt | 24 - setup.cfg | 17 - setup.py | 92 -- tox.ini | 112 +- 16 files changed, 2435 insertions(+), 565 deletions(-) delete mode 100644 .drone.yml create mode 100644 .github/workflows/tests.yml delete mode 100644 .github/workflows/tox.yml rename .gray => gray.conf (71%) create mode 100644 poetry.lock create mode 100644 pylama.ini delete mode 100644 pylava.ini create mode 100644 pyproject.toml delete mode 100644 requirements.dev.txt delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index e4c02c7b..00000000 --- a/.drone.yml +++ /dev/null @@ -1,149 +0,0 @@ ---- -kind: pipeline -name: default - - -steps: - - name: pylava - image: snakepacker/python:all - pull: always - commands: - - tox - environment: - TOXENV: pylava - - - name: checkdoc - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: checkdoc - - - name: python 3.5 - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: py35 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.6 - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: py36 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.7 - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: py37 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.7 uvloop - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: uvloop37 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.8 - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: py38 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.8 uvloop - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: uvloop38 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.9 - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: py39 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.9 uvloop - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: uvloop39 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: python 3.6 contextvars - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: contextvars36 - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - - - name: RPC example - image: snakepacker/python:all - depends_on: - - linter - pull: always - commands: - - tox - environment: - TOXENV: rpc - COVERALLS_REPO_TOKEN: - from_secret: COVERALLS_TOKEN - ---- -kind: signature -hmac: ad7b3be9cc94ae4ac82a5c28c1a48bc82dab11a51d502d66d150e2fe76cc9680 - -... diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..b62afc37 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,204 @@ +name: tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + pylama: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup python3.10 + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - run: python -m pip install poetry + - run: poetry install + - run: poetry run pylama + env: + FORCE_COLOR: 1 + mypy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup python3.10 + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - run: python -m pip install poetry + - run: poetry install + - run: poetry run mypy + env: + FORCE_COLOR: 1 + "docs examples": + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup python3.10 + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - run: python -m pip install poetry + - run: poetry install + - run: poetry run pytest -svv docs/source + env: + FORCE_COLOR: 1 + + "tests on linux": + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + python: + - '3.7' + - '3.8' + - '3.9' + - '3.10' + - '3.11' + steps: + - uses: actions/checkout@v2 + - name: Setup python${{ matrix.python }} + uses: actions/setup-python@v2 + with: + python-version: "${{ matrix.python }}" + - run: python -m pip install poetry + - run: poetry install --with=uvloop + - run: >- + poetry run pytest + -vv + --cov=aiomisc + --cov=aiomisc_log + --cov=aiomisc_pytest + --cov=aiomisc_worker + --cov-report=term-missing + --doctest-modules + --aiomisc-test-timeout=120 + tests + env: + FORCE_COLOR: 1 + - run: poetry run coveralls + env: + COVERALLS_PARALLEL: 'true' + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + "tests on macos": + runs-on: macos-latest + + strategy: + fail-fast: false + + matrix: + python: + - '3.9' + - '3.10' + - '3.11' + steps: + - uses: actions/checkout@v2 + - name: Setup python${{ matrix.python }} + uses: actions/setup-python@v2 + with: + python-version: "${{ matrix.python }}" + - run: python -m pip install poetry + - run: poetry install + - run: poetry install --without=uvloop + - run: >- + poetry run pytest + -vv + --cov=aiomisc + --cov=aiomisc_log + --cov=aiomisc_pytest + --cov=aiomisc_worker + --cov-report=term-missing + --doctest-modules + --aiomisc-test-timeout=120 + tests + env: + FORCE_COLOR: 1 + - run: poetry run coveralls + env: + COVERALLS_PARALLEL: 'true' + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + "tests on windows": + runs-on: windows-latest + + strategy: + fail-fast: false + + matrix: + python: + - '3.9' + - '3.10' + - '3.11' + steps: + - uses: actions/checkout@v2 + - name: Setup python${{ matrix.python }} + uses: actions/setup-python@v2 + with: + python-version: "${{ matrix.python }}" + - run: python -m pip install poetry + - run: poetry install --without=uvloop + - run: >- + poetry run pytest + -vv + --cov=aiomisc + --cov=aiomisc_log + --cov=aiomisc_pytest + --cov=aiomisc_worker + --cov-report=term-missing + --doctest-modules + --aiomisc-test-timeout=120 + tests + env: + FORCE_COLOR: 1 + - run: poetry run coveralls + env: + COVERALLS_PARALLEL: 'true' + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + "tests rpc example": + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + example: + - 'rpc' + - 'rpc_udp' + steps: + - uses: actions/checkout@v2 + - name: Setup python3.10 + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - run: python -m pip install poetry + - run: poetry install --with=uvloop + - run: pip install msgspec~=0.9.1 + - run: >- + cd examples/${{ matrix.example }} && + poetry run pytest -v --doctest-modules tests.py + env: + FORCE_COLOR: 1 + + finish: + needs: + - "tests on linux" + - "tests on macos" + - "tests on windows" + - "tests rpc example" + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml deleted file mode 100644 index 1a0c7ef4..00000000 --- a/.github/workflows/tox.yml +++ /dev/null @@ -1,157 +0,0 @@ -# This workflow will install Python dependencies, run tests and lint with a single version of Python -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - -name: tox - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - lint: - - runs-on: ubuntu-latest - - strategy: - matrix: - linter: - - pylava - - checkdoc - - mypy - - pydoc - - steps: - - - uses: actions/checkout@v2 - - - name: Setup python3.10 - uses: actions/setup-python@v2 - with: - python-version: "3.10" - - - name: Install tox - run: python -m pip install tox - - - name: Prepare tox env - run: tox --notest - env: - TOXENV: ${{ matrix.linter }} - - - name: Run ${{ matrix.linter }} - run: tox - env: - FORCE_COLOR: 1 - TOXENV: ${{ matrix.linter }} - - tests: - needs: lint - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - - matrix: - include: - - python: '3.7' - toxenv: py37 - os: ubuntu-latest - - python: '3.8' - toxenv: py38 - os: ubuntu-latest - - python: '3.9' - toxenv: py39 - os: ubuntu-latest - - python: '3.10' - toxenv: py310 - os: ubuntu-latest - - python: '3.11' - toxenv: py311 - os: ubuntu-latest - - python: '3.10' - toxenv: rpc - os: ubuntu-latest - - python: '3.10' - toxenv: rpc_udp - os: ubuntu-latest - - python: '3.7' - toxenv: uvloop37 - os: ubuntu-latest - - python: '3.8' - toxenv: uvloop38 - os: ubuntu-latest - - python: '3.9' - toxenv: uvloop39 - os: ubuntu-latest - -# TODO: Fix builds and enable it -# - python: '3.7' -# toxenv: py37 -# os: macos-latest -# - python: '3.8' -# toxenv: py38 -# os: macos-latest -# - python: '3.9' -# toxenv: py39 -# os: macos-latest -# - python: '3.8' -# toxenv: rpc -# os: macos-latest -# - python: '3.8' -# toxenv: rpc_udp -# os: macos-latest -# - python: '3.7' -# toxenv: uvloop37 -# os: macos-latest -# - python: '3.8' -# toxenv: uvloop38 -# os: macos-latest -# - python: '3.9' -# toxenv: uvloop39 -# os: macos-latest - -# - python: '3.7' -# toxenv: py37 -# os: windows-latest -# - python: '3.8' -# toxenv: py38 -# os: windows-latest - - python: '3.9' - toxenv: py39 - os: windows-latest - - steps: - - uses: actions/checkout@v2 - - - name: Setup python${{ matrix.python }} - uses: actions/setup-python@v2 - with: - python-version: "${{ matrix.python }}" - - - name: Install tox - run: python -m pip install tox - - - name: Prepare tox env - run: tox --notest - env: - TOXENV: ${{ matrix.toxenv }} - - - name: Run tox - run: tox - env: - COVERALLS_PARALLEL: 'true' - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - FORCE_COLOR: 1 - TOXENV: ${{ matrix.toxenv }} - - finish: - needs: tests - runs-on: ubuntu-latest - steps: - - name: Coveralls Finished - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.github_token }} - parallel-finished: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63f5b8fc..821fecde 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,9 +17,9 @@ repos: - repo: local hooks: - - id: pylava - name: Check codestyle with Pylava - entry: pylava + - id: pylama + name: Check codestyle with Pylama + entry: pylama language: system types: [ python ] diff --git a/README.rst b/README.rst index b64c061e..1631da70 100644 --- a/README.rst +++ b/README.rst @@ -90,14 +90,11 @@ For setting up developer environment just type .. code-block:: - make develop + # install development dependencies + $ poetry install - . .venv/bin/activate - - # run pre-commit before commit your changes - pre-commit - - # or run: pre-commit install for adding pre-commit hook + # Install pre-commit git hook + $ poetry run pre-commit install .. _Semantic Versioning: http://semver.org/ diff --git a/aiomisc/compat.py b/aiomisc/compat.py index cc52b71f..32e0fe30 100644 --- a/aiomisc/compat.py +++ b/aiomisc/compat.py @@ -28,8 +28,9 @@ def loop(self) -> asyncio.AbstractEventLoop: return self._loop # type: ignore +event_loop_policy: asyncio.AbstractEventLoopPolicy try: - import uvloop # type: ignore + import uvloop event_loop_policy = uvloop.EventLoopPolicy() except ImportError: event_loop_policy = asyncio.DefaultEventLoopPolicy() diff --git a/aiomisc/version.py b/aiomisc/version.py index 62520737..f9128abc 100644 --- a/aiomisc/version.py +++ b/aiomisc/version.py @@ -1,5 +1,5 @@ """ This file is automatically generated by distutils. """ # Follow PEP-0396 rationale -version_info = (16, 2, 7, "g9525317") -__version__ = "16.2.7" +version_info = (16, 2, 11, "gda272c7") +__version__ = "16.2.11" diff --git a/.gray b/gray.conf similarity index 71% rename from .gray rename to gray.conf index 938209bd..1887c6a4 100644 --- a/.gray +++ b/gray.conf @@ -1,3 +1,3 @@ formatters = add-trailing-comma,isort,unify -min-python-version = 3.3 +min-python-version = 3.7 log-level = error diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..26847558 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,2102 @@ +[[package]] +name = "aiocontextvars" +version = "0.2.2" +description = "Asyncio support for PEP-567 contextvars backport." +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "aiohttp" +version = "3.8.3" +description = "Async http client/server framework (asyncio)" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +aiosignal = ">=1.1.2" +async-timeout = ">=4.0.0a3,<5.0" +asynctest = {version = "0.13.0", markers = "python_version < \"3.8\""} +attrs = ">=17.3.0" +charset-normalizer = ">=2.0,<3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns", "cchardet"] + +[[package]] +name = "aiohttp-asgi" +version = "0.4.0" +description = "Adapter to running ASGI applications on aiohttp" +category = "dev" +optional = false +python-versions = ">3.6.*, <4" + +[package.dependencies] +aiohttp = "<4" + +[package.extras] +develop = ["coverage (!=4.3)", "coveralls", "fastapi", "pylava", "pytest", "pytest-aiohttp", "pytest-cov", "tox (>=2.4)"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "alabaster" +version = "0.7.12" +description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "anyio" +version = "3.6.2" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"] +trio = ["trio (>=0.16,<0.22)"] + +[[package]] +name = "async-timeout" +version = "4.0.2" +description = "Timeout context manager for asyncio programs" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} + +[[package]] +name = "asynctest" +version = "0.13.0" +description = "Enhance the standard unittest package with features for testing asyncio libraries" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "attrs" +version = "22.1.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] + +[[package]] +name = "autoflake" +version = "1.4" +description = "Removes unused imports and unused variables" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pyflakes = ">=1.1.0" + +[[package]] +name = "babel" +version = "2.11.0" +description = "Internationalization utilities" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pytz = ">=2015.7" + +[[package]] +name = "certifi" +version = "2022.9.24" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "cfgv" +version = "3.3.1" +description = "Validate configuration and produce human readable error messages." +category = "dev" +optional = false +python-versions = ">=3.6.1" + +[[package]] +name = "charset-normalizer" +version = "2.1.1" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" +optional = false +python-versions = ">=3.6.0" + +[package.extras] +unicode-backport = ["unicodedata2"] + +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[[package]] +name = "collective-checkdocs" +version = "0.2" +description = "Distutils command to view and validate restructured text in package's long_description" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +docutils = "*" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" + +[[package]] +name = "colorlog" +version = "6.7.0" +description = "Add colours to the output of Python's logging module." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +development = ["black", "flake8", "mypy", "pytest", "types-colorama"] + +[[package]] +name = "commonmark" +version = "0.9.1" +description = "Python parser for the CommonMark Markdown spec" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] + +[[package]] +name = "coverage" +version = "6.5.0" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "coveralls" +version = "3.3.1" +description = "Show coverage stats online via coveralls.io" +category = "dev" +optional = false +python-versions = ">= 3.5" + +[package.dependencies] +coverage = ">=4.1,<6.0.0 || >6.1,<6.1.1 || >6.1.1,<7.0" +docopt = ">=0.6.1" +requests = ">=1.0.0" + +[package.extras] +yaml = ["PyYAML (>=3.10)"] + +[[package]] +name = "croniter" +version = "1.3.8" +description = "croniter provides iteration for datetime object with cron like format" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +python-dateutil = "*" + +[[package]] +name = "distlib" +version = "0.3.6" +description = "Distribution utilities" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "docopt" +version = "0.6.2" +description = "Pythonic argument parser, that will make you smile" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "docutils" +version = "0.19" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "exceptiongroup" +version = "1.0.4" +description = "Backport of PEP 654 (exception groups)" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "fastapi" +version = "0.88.0" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" +starlette = "0.22.0" + +[package.extras] +all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +dev = ["pre-commit (>=2.17.0,<3.0.0)", "ruff (==0.0.138)", "uvicorn[standard] (>=0.12.0,<0.19.0)"] +doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer[all] (>=0.6.1,<0.7.0)"] +test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==22.10.0)", "coverage[toml] (>=6.5.0,<7.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<=1.4.41)", "types-orjson (==3.6.2)", "types-ujson (==5.5.0)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"] + +[[package]] +name = "filelock" +version = "3.8.0" +description = "A platform independent file lock." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"] +testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"] + +[[package]] +name = "freezegun" +version = "1.0.0" +description = "Let your Python tests travel through time" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +python-dateutil = ">=2.7" + +[[package]] +name = "frozenlist" +version = "1.3.3" +description = "A list-like structure which implements collections.abc.MutableSequence" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "identify" +version = "2.5.9" +description = "File identification library for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +license = ["ukkonen"] + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "importlib-metadata" +version = "5.1.0" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +perf = ["ipython"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] + +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "livereload" +version = "2.6.3" +description = "Python LiveReload is an awesome tool for web developers" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +six = "*" +tornado = {version = "*", markers = "python_version > \"2.7\""} + +[[package]] +name = "markupsafe" +version = "2.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "multidict" +version = "6.0.2" +description = "multidict implementation" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "mypy" +version = "0.991" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "nodeenv" +version = "1.7.0" +description = "Node.js virtual environment builder" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" + +[package.dependencies] +setuptools = "*" + +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + +[[package]] +name = "platformdirs" +version = "2.5.4" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] +test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] + +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pre-commit" +version = "2.20.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +toml = "*" +virtualenv = ">=20.0.8" + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pycodestyle" +version = "2.10.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pydantic" +version = "1.10.2" +description = "Data validation and settings management using python type hints" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +typing-extensions = ">=4.1.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pydocstyle" +version = "6.1.1" +description = "Python docstring style checker" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +snowballstemmer = "*" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "pyflakes" +version = "3.0.1" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pygments" +version = "2.13.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pylama" +version = "8.4.1" +description = "Code audit tool for python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +mccabe = ">=0.7.0" +pycodestyle = ">=2.9.1" +pydocstyle = ">=6.1.1" +pyflakes = ">=2.5.0" + +[package.extras] +all = ["eradicate", "mypy", "pylint", "radon", "vulture"] +eradicate = ["eradicate"] +mypy = ["mypy"] +pylint = ["pylint"] +radon = ["radon"] +tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "pytest (>=7.1.2)", "pytest-mypy", "radon (>=5.1.0)", "toml", "types-setuptools", "types-toml", "vulture"] +toml = ["toml (>=0.10.2)"] +vulture = ["vulture"] + +[[package]] +name = "pyparsing" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "dev" +optional = false +python-versions = ">=3.6.8" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pytest" +version = "7.2.0" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.0.0" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pytest-freezegun" +version = "0.4.2" +description = "Wrap tests with fixtures in freeze_time" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +freezegun = ">0.3" +pytest = ">=3.0.0" + +[[package]] +name = "pytest-rst" +version = "0.0.7" +description = "Test code from RST documents with pytest" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +docutils = "*" +py = "*" +pygments = "*" +pytest = "*" + +[[package]] +name = "pytest-subtests" +version = "0.9.0" +description = "unittest subTest() support and subtests fixture" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +pytest = ">=7.0" + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2022.6" +description = "World timezone definitions, modern and historical" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "raven" +version = "6.10.0" +description = "Raven is a client for Sentry (https://getsentry.com)" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +flask = ["Flask (>=0.8)", "blinker (>=1.1)"] +tests = ["Flask (>=0.8)", "Flask-Login (>=0.2.0)", "ZConfig", "aiohttp", "anyjson", "blinker (>=1.1)", "blinker (>=1.1)", "bottle", "celery (>=2.5)", "coverage (<4)", "exam (>=0.5.2)", "flake8 (==3.5.0)", "logbook", "mock", "nose", "pytest (>=3.2.0,<3.3.0)", "pytest-cov (==2.5.1)", "pytest-flake8 (==1.0.0)", "pytest-pythonpath (==0.7.2)", "pytest-timeout (==1.2.1)", "pytest-xdist (==1.18.2)", "pytz", "requests", "sanic (>=0.7.0)", "tornado (>=4.1,<5.0)", "tox", "webob", "webtest", "wheel"] + +[[package]] +name = "requests" +version = "2.28.1" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=3.7, <4" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rich" +version = "12.6.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "dev" +optional = false +python-versions = ">=3.6.3,<4.0.0" + +[package.dependencies] +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] + +[[package]] +name = "setproctitle" +version = "1.3.2" +description = "A Python module to customize the process title" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "setuptools" +version = "65.6.3" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "sphinx" +version = "5.3.0" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.20" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.12" +requests = ">=2.5.0" +snowballstemmer = ">=2.0" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] + +[[package]] +name = "sphinx-autobuild" +version = "2021.3.14" +description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = "*" +livereload = "*" +sphinx = "*" + +[package.extras] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "sphinx-intl" +version = "2.0.1" +description = "Sphinx utility that make it easy to translate and to apply translation." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +babel = "*" +click = "*" +setuptools = "*" +sphinx = "*" + +[package.extras] +test = ["mock", "pytest"] +transifex = ["transifex_client (>=0.11)"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "starlette" +version = "0.22.0" +description = "The little ASGI library that shines." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +anyio = ">=3.4.0,<5" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] + +[[package]] +name = "timeout-decorator" +version = "0.5.0" +description = "Timeout decorator" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "tornado" +version = "6.2" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "dev" +optional = false +python-versions = ">= 3.7" + +[[package]] +name = "tox" +version = "3.27.1" +description = "tox is a generic virtualenv management and test command line tool" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} +filelock = ">=3.0.0" +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +packaging = ">=14" +pluggy = ">=0.12.0" +py = ">=1.4.17" +six = ">=1.14.0" +tomli = {version = ">=2.0.1", markers = "python_version >= \"3.7\" and python_version < \"3.11\""} +virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" + +[package.extras] +docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] +testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)"] + +[[package]] +name = "typed-ast" +version = "1.5.4" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "types-croniter" +version = "1.3.2" +description = "Typing stubs for croniter" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "types-setuptools" +version = "65.6.0.1" +description = "Typing stubs for setuptools" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "typing-extensions" +version = "4.4.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "urllib3" +version = "1.26.13" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "uvloop" +version = "0.17.0" +description = "Fast implementation of asyncio event loop on top of libuv" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)", "pytest (>=3.6.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] + +[[package]] +name = "virtualenv" +version = "20.17.0" +description = "Virtual Python Environment builder" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +distlib = ">=0.3.6,<1" +filelock = ">=3.4.1,<4" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.8\""} +platformdirs = ">=2.4,<3" + +[package.extras] +docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] +testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] + +[[package]] +name = "yarl" +version = "1.8.1" +description = "Yet another URL library" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} + +[[package]] +name = "zipp" +version = "3.11.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[extras] +aiohttp = [] +asgi = [] +carbon = [] +cron = [] +raven = [] +uvloop = [] + +[metadata] +lock-version = "1.1" +python-versions = "^3.7" +content-hash = "d242beb6df1c2be0c0782359af78f593035ae253135bfd9b6d3c52b008b11869" + +[metadata.files] +aiocontextvars = [ + {file = "aiocontextvars-0.2.2-py2.py3-none-any.whl", hash = "sha256:885daf8261818767d8f7cbd79f9d4482d118f024b6586ef6e67980236a27bfa3"}, + {file = "aiocontextvars-0.2.2.tar.gz", hash = "sha256:f027372dc48641f683c559f247bd84962becaacdc9ba711d583c3871fb5652aa"}, +] +aiohttp = [ + {file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ba71c9b4dcbb16212f334126cc3d8beb6af377f6703d9dc2d9fb3874fd667ee9"}, + {file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d24b8bb40d5c61ef2d9b6a8f4528c2f17f1c5d2d31fed62ec860f6006142e83e"}, + {file = "aiohttp-3.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f88df3a83cf9df566f171adba39d5bd52814ac0b94778d2448652fc77f9eb491"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97decbb3372d4b69e4d4c8117f44632551c692bb1361b356a02b97b69e18a62"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:309aa21c1d54b8ef0723181d430347d7452daaff93e8e2363db8e75c72c2fb2d"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad5383a67514e8e76906a06741febd9126fc7c7ff0f599d6fcce3e82b80d026f"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20acae4f268317bb975671e375493dbdbc67cddb5f6c71eebdb85b34444ac46b"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05a3c31c6d7cd08c149e50dc7aa2568317f5844acd745621983380597f027a18"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d6f76310355e9fae637c3162936e9504b4767d5c52ca268331e2756e54fd4ca5"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:256deb4b29fe5e47893fa32e1de2d73c3afe7407738bd3c63829874661d4822d"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5c59fcd80b9049b49acd29bd3598cada4afc8d8d69bd4160cd613246912535d7"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:059a91e88f2c00fe40aed9031b3606c3f311414f86a90d696dd982e7aec48142"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2feebbb6074cdbd1ac276dbd737b40e890a1361b3cc30b74ac2f5e24aab41f7b"}, + {file = "aiohttp-3.8.3-cp310-cp310-win32.whl", hash = "sha256:5bf651afd22d5f0c4be16cf39d0482ea494f5c88f03e75e5fef3a85177fecdeb"}, + {file = "aiohttp-3.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:653acc3880459f82a65e27bd6526e47ddf19e643457d36a2250b85b41a564715"}, + {file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:86fc24e58ecb32aee09f864cb11bb91bc4c1086615001647dbfc4dc8c32f4008"}, + {file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75e14eac916f024305db517e00a9252714fce0abcb10ad327fb6dcdc0d060f1d"}, + {file = "aiohttp-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d1fde0f44029e02d02d3993ad55ce93ead9bb9b15c6b7ccd580f90bd7e3de476"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab94426ddb1ecc6a0b601d832d5d9d421820989b8caa929114811369673235c"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89d2e02167fa95172c017732ed7725bc8523c598757f08d13c5acca308e1a061"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02f9a2c72fc95d59b881cf38a4b2be9381b9527f9d328771e90f72ac76f31ad8"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7149272fb5834fc186328e2c1fa01dda3e1fa940ce18fded6d412e8f2cf76d"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:512bd5ab136b8dc0ffe3fdf2dfb0c4b4f49c8577f6cae55dca862cd37a4564e2"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7018ecc5fe97027214556afbc7c502fbd718d0740e87eb1217b17efd05b3d276"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88c70ed9da9963d5496d38320160e8eb7e5f1886f9290475a881db12f351ab5d"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:da22885266bbfb3f78218dc40205fed2671909fbd0720aedba39b4515c038091"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:e65bc19919c910127c06759a63747ebe14f386cda573d95bcc62b427ca1afc73"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:08c78317e950e0762c2983f4dd58dc5e6c9ff75c8a0efeae299d363d439c8e34"}, + {file = "aiohttp-3.8.3-cp311-cp311-win32.whl", hash = "sha256:45d88b016c849d74ebc6f2b6e8bc17cabf26e7e40c0661ddd8fae4c00f015697"}, + {file = "aiohttp-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:96372fc29471646b9b106ee918c8eeb4cca423fcbf9a34daa1b93767a88a2290"}, + {file = "aiohttp-3.8.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c971bf3786b5fad82ce5ad570dc6ee420f5b12527157929e830f51c55dc8af77"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff25f48fc8e623d95eca0670b8cc1469a83783c924a602e0fbd47363bb54aaca"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e381581b37db1db7597b62a2e6b8b57c3deec95d93b6d6407c5b61ddc98aca6d"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db19d60d846283ee275d0416e2a23493f4e6b6028825b51290ac05afc87a6f97"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25892c92bee6d9449ffac82c2fe257f3a6f297792cdb18ad784737d61e7a9a85"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:398701865e7a9565d49189f6c90868efaca21be65c725fc87fc305906be915da"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4a4fbc769ea9b6bd97f4ad0b430a6807f92f0e5eb020f1e42ece59f3ecfc4585"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:b29bfd650ed8e148f9c515474a6ef0ba1090b7a8faeee26b74a8ff3b33617502"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:1e56b9cafcd6531bab5d9b2e890bb4937f4165109fe98e2b98ef0dcfcb06ee9d"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ec40170327d4a404b0d91855d41bfe1fe4b699222b2b93e3d833a27330a87a6d"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2df5f139233060578d8c2c975128fb231a89ca0a462b35d4b5fcf7c501ebdbe1"}, + {file = "aiohttp-3.8.3-cp36-cp36m-win32.whl", hash = "sha256:f973157ffeab5459eefe7b97a804987876dd0a55570b8fa56b4e1954bf11329b"}, + {file = "aiohttp-3.8.3-cp36-cp36m-win_amd64.whl", hash = "sha256:437399385f2abcd634865705bdc180c8314124b98299d54fe1d4c8990f2f9494"}, + {file = "aiohttp-3.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:09e28f572b21642128ef31f4e8372adb6888846f32fecb288c8b0457597ba61a"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f3553510abdbec67c043ca85727396ceed1272eef029b050677046d3387be8d"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e168a7560b7c61342ae0412997b069753f27ac4862ec7867eff74f0fe4ea2ad9"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db4c979b0b3e0fa7e9e69ecd11b2b3174c6963cebadeecfb7ad24532ffcdd11a"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e164e0a98e92d06da343d17d4e9c4da4654f4a4588a20d6c73548a29f176abe2"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a78079d9a39ca9ca99a8b0ac2fdc0c4d25fc80c8a8a82e5c8211509c523363"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:21b30885a63c3f4ff5b77a5d6caf008b037cb521a5f33eab445dc566f6d092cc"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4b0f30372cef3fdc262f33d06e7b411cd59058ce9174ef159ad938c4a34a89da"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:8135fa153a20d82ffb64f70a1b5c2738684afa197839b34cc3e3c72fa88d302c"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ad61a9639792fd790523ba072c0555cd6be5a0baf03a49a5dd8cfcf20d56df48"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978b046ca728073070e9abc074b6299ebf3501e8dee5e26efacb13cec2b2dea0"}, + {file = "aiohttp-3.8.3-cp37-cp37m-win32.whl", hash = "sha256:0d2c6d8c6872df4a6ec37d2ede71eff62395b9e337b4e18efd2177de883a5033"}, + {file = "aiohttp-3.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:21d69797eb951f155026651f7e9362877334508d39c2fc37bd04ff55b2007091"}, + {file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ca9af5f8f5812d475c5259393f52d712f6d5f0d7fdad9acdb1107dd9e3cb7eb"}, + {file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d90043c1882067f1bd26196d5d2db9aa6d268def3293ed5fb317e13c9413ea4"}, + {file = "aiohttp-3.8.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d737fc67b9a970f3234754974531dc9afeea11c70791dcb7db53b0cf81b79784"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebf909ea0a3fc9596e40d55d8000702a85e27fd578ff41a5500f68f20fd32e6c"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5835f258ca9f7c455493a57ee707b76d2d9634d84d5d7f62e77be984ea80b849"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da37dcfbf4b7f45d80ee386a5f81122501ec75672f475da34784196690762f4b"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f44875f2804bc0511a69ce44a9595d5944837a62caecc8490bbdb0e18b1342"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:527b3b87b24844ea7865284aabfab08eb0faf599b385b03c2aa91fc6edd6e4b6"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5ba88df9aa5e2f806650fcbeedbe4f6e8736e92fc0e73b0400538fd25a4dd96"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e7b8813be97cab8cb52b1375f41f8e6804f6507fe4660152e8ca5c48f0436017"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2dea10edfa1a54098703cb7acaa665c07b4e7568472a47f4e64e6319d3821ccf"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:713d22cd9643ba9025d33c4af43943c7a1eb8547729228de18d3e02e278472b6"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2d252771fc85e0cf8da0b823157962d70639e63cb9b578b1dec9868dd1f4f937"}, + {file = "aiohttp-3.8.3-cp38-cp38-win32.whl", hash = "sha256:66bd5f950344fb2b3dbdd421aaa4e84f4411a1a13fca3aeb2bcbe667f80c9f76"}, + {file = "aiohttp-3.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:84b14f36e85295fe69c6b9789b51a0903b774046d5f7df538176516c3e422446"}, + {file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16c121ba0b1ec2b44b73e3a8a171c4f999b33929cd2397124a8c7fcfc8cd9e06"}, + {file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8d6aaa4e7155afaf994d7924eb290abbe81a6905b303d8cb61310a2aba1c68ba"}, + {file = "aiohttp-3.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43046a319664a04b146f81b40e1545d4c8ac7b7dd04c47e40bf09f65f2437346"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599418aaaf88a6d02a8c515e656f6faf3d10618d3dd95866eb4436520096c84b"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a2964319d359f494f16011e23434f6f8ef0434acd3cf154a6b7bec511e2fb7"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73a4131962e6d91109bca6536416aa067cf6c4efb871975df734f8d2fd821b37"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598adde339d2cf7d67beaccda3f2ce7c57b3b412702f29c946708f69cf8222aa"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75880ed07be39beff1881d81e4a907cafb802f306efd6d2d15f2b3c69935f6fb"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0239da9fbafd9ff82fd67c16704a7d1bccf0d107a300e790587ad05547681c8"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4e3a23ec214e95c9fe85a58470b660efe6534b83e6cbe38b3ed52b053d7cb6ad"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:47841407cc89a4b80b0c52276f3cc8138bbbfba4b179ee3acbd7d77ae33f7ac4"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:54d107c89a3ebcd13228278d68f1436d3f33f2dd2af5415e3feaeb1156e1a62c"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c37c5cce780349d4d51739ae682dec63573847a2a8dcb44381b174c3d9c8d403"}, + {file = "aiohttp-3.8.3-cp39-cp39-win32.whl", hash = "sha256:f178d2aadf0166be4df834c4953da2d7eef24719e8aec9a65289483eeea9d618"}, + {file = "aiohttp-3.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:88e5be56c231981428f4f506c68b6a46fa25c4123a2e86d156c58a8369d31ab7"}, + {file = "aiohttp-3.8.3.tar.gz", hash = "sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269"}, +] +aiohttp-asgi = [ + {file = "aiohttp-asgi-0.4.0.tar.gz", hash = "sha256:0ee1bfb7fc844f307fd0b6d28d6929772809d99c16cb74260d5f4b6b6db306e2"}, + {file = "aiohttp_asgi-0.4.0-py3-none-any.whl", hash = "sha256:e0637e8cf02c42db117bae2bdc75e15db43c270ed3f3bf4e0e261e4e4ed50642"}, +] +aiosignal = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] +anyio = [ + {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, + {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, +] +async-timeout = [ + {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, + {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, +] +asynctest = [ + {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, + {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, +] +attrs = [ + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, +] +autoflake = [ + {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, +] +babel = [ + {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, + {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, +] +certifi = [ + {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, + {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, +] +cfgv = [ + {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, + {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, + {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, +] +click = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] +collective-checkdocs = [ + {file = "collective.checkdocs-0.2.zip", hash = "sha256:3a5328257c5224bc72753820c182910d7fb336bc1dba5e09113d48566655e46e"}, +] +colorama = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] +colorlog = [ + {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, + {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, +] +commonmark = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] +coverage = [ + {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, + {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, + {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, + {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, + {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, + {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, + {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, + {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, + {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, + {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, + {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, + {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, + {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, + {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, + {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, + {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, +] +coveralls = [ + {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"}, + {file = "coveralls-3.3.1.tar.gz", hash = "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea"}, +] +croniter = [ + {file = "croniter-1.3.8-py2.py3-none-any.whl", hash = "sha256:d6ed8386d5f4bbb29419dc1b65c4909c04a2322bd15ec0dc5b2877bfa1b75c7a"}, + {file = "croniter-1.3.8.tar.gz", hash = "sha256:32a5ec04e97ec0837bcdf013767abd2e71cceeefd3c2e14c804098ce51ad6cd9"}, +] +distlib = [ + {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, + {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, +] +docopt = [ + {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, +] +docutils = [ + {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, + {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, +] +exceptiongroup = [ + {file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"}, + {file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"}, +] +fastapi = [ + {file = "fastapi-0.88.0-py3-none-any.whl", hash = "sha256:263b718bb384422fe3d042ffc9a0c8dece5e034ab6586ff034f6b4b1667c3eee"}, + {file = "fastapi-0.88.0.tar.gz", hash = "sha256:915bf304180a0e7c5605ec81097b7d4cd8826ff87a02bb198e336fb9f3b5ff02"}, +] +filelock = [ + {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"}, + {file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"}, +] +freezegun = [ + {file = "freezegun-1.0.0-py2.py3-none-any.whl", hash = "sha256:02b35de52f4699a78f6ac4518e4cd3390dddc43b0aeb978335a8f270a2d9668b"}, + {file = "freezegun-1.0.0.tar.gz", hash = "sha256:1cf08e441f913ff5e59b19cc065a8faa9dd1ddc442eaf0375294f344581a0643"}, +] +frozenlist = [ + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, + {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, + {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, + {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, + {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, + {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, + {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, + {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, + {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, + {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, + {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, +] +identify = [ + {file = "identify-2.5.9-py2.py3-none-any.whl", hash = "sha256:a390fb696e164dbddb047a0db26e57972ae52fbd037ae68797e5ae2f4492485d"}, + {file = "identify-2.5.9.tar.gz", hash = "sha256:906036344ca769539610436e40a684e170c3648b552194980bb7b617a8daeb9f"}, +] +idna = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] +imagesize = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] +importlib-metadata = [ + {file = "importlib_metadata-5.1.0-py3-none-any.whl", hash = "sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313"}, + {file = "importlib_metadata-5.1.0.tar.gz", hash = "sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b"}, +] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] +jinja2 = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] +livereload = [ + {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, +] +markupsafe = [ + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, +] +mccabe = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] +multidict = [ + {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"}, + {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"}, + {file = "multidict-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389"}, + {file = "multidict-6.0.2-cp310-cp310-win32.whl", hash = "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293"}, + {file = "multidict-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658"}, + {file = "multidict-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15"}, + {file = "multidict-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc"}, + {file = "multidict-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a"}, + {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60"}, + {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86"}, + {file = "multidict-6.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d"}, + {file = "multidict-6.0.2-cp38-cp38-win32.whl", hash = "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57"}, + {file = "multidict-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96"}, + {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c"}, + {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e"}, + {file = "multidict-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937"}, + {file = "multidict-6.0.2-cp39-cp39-win32.whl", hash = "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a"}, + {file = "multidict-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae"}, + {file = "multidict-6.0.2.tar.gz", hash = "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013"}, +] +mypy = [ + {file = "mypy-0.991-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7d17e0a9707d0772f4a7b878f04b4fd11f6f5bcb9b3813975a9b13c9332153ab"}, + {file = "mypy-0.991-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0714258640194d75677e86c786e80ccf294972cc76885d3ebbb560f11db0003d"}, + {file = "mypy-0.991-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c8f3be99e8a8bd403caa8c03be619544bc2c77a7093685dcf308c6b109426c6"}, + {file = "mypy-0.991-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9ec663ed6c8f15f4ae9d3c04c989b744436c16d26580eaa760ae9dd5d662eb"}, + {file = "mypy-0.991-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4307270436fd7694b41f913eb09210faff27ea4979ecbcd849e57d2da2f65305"}, + {file = "mypy-0.991-cp310-cp310-win_amd64.whl", hash = "sha256:901c2c269c616e6cb0998b33d4adbb4a6af0ac4ce5cd078afd7bc95830e62c1c"}, + {file = "mypy-0.991-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d13674f3fb73805ba0c45eb6c0c3053d218aa1f7abead6e446d474529aafc372"}, + {file = "mypy-0.991-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c8cd4fb70e8584ca1ed5805cbc7c017a3d1a29fb450621089ffed3e99d1857f"}, + {file = "mypy-0.991-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:209ee89fbb0deed518605edddd234af80506aec932ad28d73c08f1400ef80a33"}, + {file = "mypy-0.991-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37bd02ebf9d10e05b00d71302d2c2e6ca333e6c2a8584a98c00e038db8121f05"}, + {file = "mypy-0.991-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:26efb2fcc6b67e4d5a55561f39176821d2adf88f2745ddc72751b7890f3194ad"}, + {file = "mypy-0.991-cp311-cp311-win_amd64.whl", hash = "sha256:3a700330b567114b673cf8ee7388e949f843b356a73b5ab22dd7cff4742a5297"}, + {file = "mypy-0.991-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1f7d1a520373e2272b10796c3ff721ea1a0712288cafaa95931e66aa15798813"}, + {file = "mypy-0.991-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:641411733b127c3e0dab94c45af15fea99e4468f99ac88b39efb1ad677da5711"}, + {file = "mypy-0.991-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3d80e36b7d7a9259b740be6d8d906221789b0d836201af4234093cae89ced0cd"}, + {file = "mypy-0.991-cp37-cp37m-win_amd64.whl", hash = "sha256:e62ebaad93be3ad1a828a11e90f0e76f15449371ffeecca4a0a0b9adc99abcef"}, + {file = "mypy-0.991-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b86ce2c1866a748c0f6faca5232059f881cda6dda2a893b9a8373353cfe3715a"}, + {file = "mypy-0.991-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac6e503823143464538efda0e8e356d871557ef60ccd38f8824a4257acc18d93"}, + {file = "mypy-0.991-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0cca5adf694af539aeaa6ac633a7afe9bbd760df9d31be55ab780b77ab5ae8bf"}, + {file = "mypy-0.991-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12c56bf73cdab116df96e4ff39610b92a348cc99a1307e1da3c3768bbb5b135"}, + {file = "mypy-0.991-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:652b651d42f155033a1967739788c436491b577b6a44e4c39fb340d0ee7f0d70"}, + {file = "mypy-0.991-cp38-cp38-win_amd64.whl", hash = "sha256:4175593dc25d9da12f7de8de873a33f9b2b8bdb4e827a7cae952e5b1a342e243"}, + {file = "mypy-0.991-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:98e781cd35c0acf33eb0295e8b9c55cdbef64fcb35f6d3aa2186f289bed6e80d"}, + {file = "mypy-0.991-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6d7464bac72a85cb3491c7e92b5b62f3dcccb8af26826257760a552a5e244aa5"}, + {file = "mypy-0.991-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c9166b3f81a10cdf9b49f2d594b21b31adadb3d5e9db9b834866c3258b695be3"}, + {file = "mypy-0.991-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8472f736a5bfb159a5e36740847808f6f5b659960115ff29c7cecec1741c648"}, + {file = "mypy-0.991-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e80e758243b97b618cdf22004beb09e8a2de1af481382e4d84bc52152d1c476"}, + {file = "mypy-0.991-cp39-cp39-win_amd64.whl", hash = "sha256:74e259b5c19f70d35fcc1ad3d56499065c601dfe94ff67ae48b85596b9ec1461"}, + {file = "mypy-0.991-py3-none-any.whl", hash = "sha256:de32edc9b0a7e67c2775e574cb061a537660e51210fbf6006b0b36ea695ae9bb"}, + {file = "mypy-0.991.tar.gz", hash = "sha256:3c0165ba8f354a6d9881809ef29f1a9318a236a6d81c690094c5df32107bde06"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +nodeenv = [ + {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, + {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, +] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] +platformdirs = [ + {file = "platformdirs-2.5.4-py3-none-any.whl", hash = "sha256:af0276409f9a02373d540bf8480021a048711d572745aef4b7842dad245eba10"}, + {file = "platformdirs-2.5.4.tar.gz", hash = "sha256:1006647646d80f16130f052404c6b901e80ee4ed6bef6792e1f238a8969106f7"}, +] +pluggy = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] +pre-commit = [ + {file = "pre_commit-2.20.0-py2.py3-none-any.whl", hash = "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7"}, + {file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"}, +] +py = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] +pycodestyle = [ + {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, + {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, +] +pydantic = [ + {file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"}, + {file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"}, + {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"}, + {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559"}, + {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"}, + {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c"}, + {file = "pydantic-1.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644"}, + {file = "pydantic-1.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f"}, + {file = "pydantic-1.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a"}, + {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525"}, + {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283"}, + {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42"}, + {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52"}, + {file = "pydantic-1.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c"}, + {file = "pydantic-1.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5"}, + {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c"}, + {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254"}, + {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5"}, + {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d"}, + {file = "pydantic-1.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2"}, + {file = "pydantic-1.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13"}, + {file = "pydantic-1.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116"}, + {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624"}, + {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1"}, + {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9"}, + {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965"}, + {file = "pydantic-1.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e"}, + {file = "pydantic-1.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488"}, + {file = "pydantic-1.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41"}, + {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b"}, + {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe"}, + {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d"}, + {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda"}, + {file = "pydantic-1.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6"}, + {file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"}, + {file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"}, +] +pydocstyle = [ + {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, + {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, +] +pyflakes = [ + {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, + {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, +] +pygments = [ + {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, + {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, +] +pylama = [ + {file = "pylama-8.4.1-py3-none-any.whl", hash = "sha256:5bbdbf5b620aba7206d688ed9fc917ecd3d73e15ec1a89647037a09fa3a86e60"}, + {file = "pylama-8.4.1.tar.gz", hash = "sha256:2d4f7aecfb5b7466216d48610c7d6bad1c3990c29cdd392ad08259b161e486f6"}, +] +pyparsing = [ + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, +] +pytest = [ + {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, + {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, +] +pytest-cov = [ + {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, + {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, +] +pytest-freezegun = [ + {file = "pytest-freezegun-0.4.2.zip", hash = "sha256:19c82d5633751bf3ec92caa481fb5cffaac1787bd485f0df6436fd6242176949"}, + {file = "pytest_freezegun-0.4.2-py2.py3-none-any.whl", hash = "sha256:5318a6bfb8ba4b709c8471c94d0033113877b3ee02da5bfcd917c1889cde99a7"}, +] +pytest-rst = [ + {file = "pytest-rst-0.0.7.tar.gz", hash = "sha256:2b34aa9d41ce8dce3e685e6f40dff432804962ffec49d3d37565f2dbad4014d5"}, +] +pytest-subtests = [ + {file = "pytest-subtests-0.9.0.tar.gz", hash = "sha256:c0317cd5f6a5eb3e957e89dbe4fc3322a9afddba2db8414355ed2a2cb91a844e"}, + {file = "pytest_subtests-0.9.0-py3-none-any.whl", hash = "sha256:f5f616b92c13405909d210569d6d3914db6fe156333ff5426534f97d5b447861"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] +pytz = [ + {file = "pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, + {file = "pytz-2022.6.tar.gz", hash = "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2"}, +] +pyyaml = [ + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] +raven = [ + {file = "raven-6.10.0-py2.py3-none-any.whl", hash = "sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4"}, + {file = "raven-6.10.0.tar.gz", hash = "sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54"}, +] +requests = [ + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, +] +rich = [ + {file = "rich-12.6.0-py3-none-any.whl", hash = "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e"}, + {file = "rich-12.6.0.tar.gz", hash = "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0"}, +] +setproctitle = [ + {file = "setproctitle-1.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:288943dec88e178bb2fd868adf491197cc0fc8b6810416b1c6775e686bab87fe"}, + {file = "setproctitle-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:630f6fe5e24a619ccf970c78e084319ee8be5be253ecc9b5b216b0f474f5ef18"}, + {file = "setproctitle-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c877691b90026670e5a70adfbcc735460a9f4c274d35ec5e8a43ce3f8443005"}, + {file = "setproctitle-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a55fe05f15c10e8c705038777656fe45e3bd676d49ad9ac8370b75c66dd7cd7"}, + {file = "setproctitle-1.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab45146c71ca6592c9cc8b354a2cc9cc4843c33efcbe1d245d7d37ce9696552d"}, + {file = "setproctitle-1.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00c9d5c541a2713ba0e657e0303bf96ddddc412ef4761676adc35df35d7c246"}, + {file = "setproctitle-1.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:265ecbe2c6eafe82e104f994ddd7c811520acdd0647b73f65c24f51374cf9494"}, + {file = "setproctitle-1.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c2c46200656280a064073447ebd363937562debef329482fd7e570c8d498f806"}, + {file = "setproctitle-1.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:fa2f50678f04fda7a75d0fe5dd02bbdd3b13cbe6ed4cf626e4472a7ccf47ae94"}, + {file = "setproctitle-1.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f2719a398e1a2c01c2a63bf30377a34d0b6ef61946ab9cf4d550733af8f1ef1"}, + {file = "setproctitle-1.3.2-cp310-cp310-win32.whl", hash = "sha256:e425be62524dc0c593985da794ee73eb8a17abb10fe692ee43bb39e201d7a099"}, + {file = "setproctitle-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:e85e50b9c67854f89635a86247412f3ad66b132a4d8534ac017547197c88f27d"}, + {file = "setproctitle-1.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:92c626edc66169a1b09e9541b9c0c9f10488447d8a2b1d87c8f0672e771bc927"}, + {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:710e16fa3bade3b026907e4a5e841124983620046166f355bbb84be364bf2a02"}, + {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f29b75e86260b0ab59adb12661ef9f113d2f93a59951373eb6d68a852b13e83"}, + {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c8d9650154afaa86a44ff195b7b10d683c73509d085339d174e394a22cccbb9"}, + {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0452282258dfcc01697026a8841258dd2057c4438b43914b611bccbcd048f10"}, + {file = "setproctitle-1.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e49ae693306d7624015f31cb3e82708916759d592c2e5f72a35c8f4cc8aef258"}, + {file = "setproctitle-1.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1ff863a20d1ff6ba2c24e22436a3daa3cd80be1dfb26891aae73f61b54b04aca"}, + {file = "setproctitle-1.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:55ce1e9925ce1765865442ede9dca0ba9bde10593fcd570b1f0fa25d3ec6b31c"}, + {file = "setproctitle-1.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7fe9df7aeb8c64db6c34fc3b13271a363475d77bc157d3f00275a53910cb1989"}, + {file = "setproctitle-1.3.2-cp37-cp37m-win32.whl", hash = "sha256:e5c50e164cd2459bc5137c15288a9ef57160fd5cbf293265ea3c45efe7870865"}, + {file = "setproctitle-1.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a499fff50387c1520c085a07578a000123f519e5f3eee61dd68e1d301659651f"}, + {file = "setproctitle-1.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b932c3041aa924163f4aab970c2f0e6b4d9d773f4d50326e0ea1cd69240e5c5"}, + {file = "setproctitle-1.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4bfc89bd33ebb8e4c0e9846a09b1f5a4a86f5cb7a317e75cc42fee1131b4f4f"}, + {file = "setproctitle-1.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcd3cf4286a60fdc95451d8d14e0389a6b4f5cebe02c7f2609325eb016535963"}, + {file = "setproctitle-1.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fb4f769c02f63fac90989711a3fee83919f47ae9afd4758ced5d86596318c65"}, + {file = "setproctitle-1.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5194b4969f82ea842a4f6af2f82cd16ebdc3f1771fb2771796e6add9835c1973"}, + {file = "setproctitle-1.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cde41857a644b7353a0060b5f94f7ba7cf593ebde5a1094da1be581ac9a31"}, + {file = "setproctitle-1.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9124bedd8006b0e04d4e8a71a0945da9b67e7a4ab88fdad7b1440dc5b6122c42"}, + {file = "setproctitle-1.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8a09d570b39517de10ee5b718730e171251ce63bbb890c430c725c8c53d4484"}, + {file = "setproctitle-1.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:8ff3c8cb26afaed25e8bca7b9dd0c1e36de71f35a3a0706b5c0d5172587a3827"}, + {file = "setproctitle-1.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:589be87172b238f839e19f146b9ea47c71e413e951ef0dc6db4218ddacf3c202"}, + {file = "setproctitle-1.3.2-cp38-cp38-win32.whl", hash = "sha256:4749a2b0c9ac52f864d13cee94546606f92b981b50e46226f7f830a56a9dc8e1"}, + {file = "setproctitle-1.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:e43f315c68aa61cbdef522a2272c5a5b9b8fd03c301d3167b5e1343ef50c676c"}, + {file = "setproctitle-1.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:de3a540cd1817ede31f530d20e6a4935bbc1b145fd8f8cf393903b1e02f1ae76"}, + {file = "setproctitle-1.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4058564195b975ddc3f0462375c533cce310ccdd41b80ac9aed641c296c3eff4"}, + {file = "setproctitle-1.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c5d5dad7c28bdd1ec4187d818e43796f58a845aa892bb4481587010dc4d362b"}, + {file = "setproctitle-1.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffc61a388a5834a97953d6444a2888c24a05f2e333f9ed49f977a87bb1ad4761"}, + {file = "setproctitle-1.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fa1a0fbee72b47dc339c87c890d3c03a72ea65c061ade3204f285582f2da30f"}, + {file = "setproctitle-1.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8a988c7220c002c45347430993830666e55bc350179d91fcee0feafe64e1d4"}, + {file = "setproctitle-1.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bae283e85fc084b18ffeb92e061ff7ac5af9e183c9d1345c93e178c3e5069cbe"}, + {file = "setproctitle-1.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fed18e44711c5af4b681c2b3b18f85e6f0f1b2370a28854c645d636d5305ccd8"}, + {file = "setproctitle-1.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:b34baef93bfb20a8ecb930e395ccd2ae3268050d8cf4fe187de5e2bd806fd796"}, + {file = "setproctitle-1.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7f0bed90a216ef28b9d227d8d73e28a8c9b88c0f48a082d13ab3fa83c581488f"}, + {file = "setproctitle-1.3.2-cp39-cp39-win32.whl", hash = "sha256:4d8938249a7cea45ab7e1e48b77685d0f2bab1ebfa9dde23e94ab97968996a7c"}, + {file = "setproctitle-1.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:a47d97a75fd2d10c37410b180f67a5835cb1d8fdea2648fd7f359d4277f180b9"}, + {file = "setproctitle-1.3.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:dad42e676c5261eb50fdb16bdf3e2771cf8f99a79ef69ba88729aeb3472d8575"}, + {file = "setproctitle-1.3.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c91b9bc8985d00239f7dc08a49927a7ca1ca8a6af2c3890feec3ed9665b6f91e"}, + {file = "setproctitle-1.3.2-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8579a43eafd246e285eb3a5b939e7158073d5087aacdd2308f23200eac2458b"}, + {file = "setproctitle-1.3.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:2fbd8187948284293f43533c150cd69a0e4192c83c377da837dbcd29f6b83084"}, + {file = "setproctitle-1.3.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:faec934cfe5fd6ac1151c02e67156c3f526e82f96b24d550b5d51efa4a5527c6"}, + {file = "setproctitle-1.3.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1aafc91cbdacc9e5fe712c52077369168e6b6c346f3a9d51bf600b53eae56bb"}, + {file = "setproctitle-1.3.2-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b617f12c9be61e8f4b2857be4a4319754756845dbbbd9c3718f468bbb1e17bcb"}, + {file = "setproctitle-1.3.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b2c9cb2705fc84cb8798f1ba74194f4c080aaef19d9dae843591c09b97678e98"}, + {file = "setproctitle-1.3.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a149a5f7f2c5a065d4e63cb0d7a4b6d3b66e6e80f12e3f8827c4f63974cbf122"}, + {file = "setproctitle-1.3.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e3ac25bfc4a0f29d2409650c7532d5ddfdbf29f16f8a256fc31c47d0dc05172"}, + {file = "setproctitle-1.3.2-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65d884e22037b23fa25b2baf1a3316602ed5c5971eb3e9d771a38c3a69ce6e13"}, + {file = "setproctitle-1.3.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7aa0aac1711fadffc1d51e9d00a3bea61f68443d6ac0241a224e4d622489d665"}, + {file = "setproctitle-1.3.2.tar.gz", hash = "sha256:b9fb97907c830d260fa0658ed58afd48a86b2b88aac521135c352ff7fd3477fd"}, +] +setuptools = [ + {file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"}, + {file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"}, +] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] +sniffio = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] +snowballstemmer = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] +sphinx = [ + {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"}, + {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"}, +] +sphinx-autobuild = [ + {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, + {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, +] +sphinx-intl = [ + {file = "sphinx-intl-2.0.1.tar.gz", hash = "sha256:b25a6ec169347909e8d983eefe2d8adecb3edc2f27760db79b965c69950638b4"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, + {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] +starlette = [ + {file = "starlette-0.22.0-py3-none-any.whl", hash = "sha256:b5eda991ad5f0ee5d8ce4c4540202a573bb6691ecd0c712262d0bc85cf8f2c50"}, + {file = "starlette-0.22.0.tar.gz", hash = "sha256:b092cbc365bea34dd6840b42861bdabb2f507f8671e642e8272d2442e08ea4ff"}, +] +timeout-decorator = [ + {file = "timeout-decorator-0.5.0.tar.gz", hash = "sha256:6a2f2f58db1c5b24a2cc79de6345760377ad8bdc13813f5265f6c3e63d16b3d7"}, +] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +tornado = [ + {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"}, + {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"}, + {file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"}, + {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, + {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, +] +tox = [ + {file = "tox-3.27.1-py2.py3-none-any.whl", hash = "sha256:f52ca66eae115fcfef0e77ef81fd107133d295c97c52df337adedb8dfac6ab84"}, + {file = "tox-3.27.1.tar.gz", hash = "sha256:b2a920e35a668cc06942ffd1cf3a4fb221a4d909ca72191fb6d84b0b18a7be04"}, +] +typed-ast = [ + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, +] +types-croniter = [ + {file = "types-croniter-1.3.2.tar.gz", hash = "sha256:e96e9c855247f294fb88cc1363a5eb93fd1df5943fe85dda29179285e00deabc"}, + {file = "types_croniter-1.3.2-py3-none-any.whl", hash = "sha256:f529295f94aff6da82222739bbcdeed7fe98de9fe38597f04071d2a1b980ee06"}, +] +types-setuptools = [ + {file = "types-setuptools-65.6.0.1.tar.gz", hash = "sha256:a03cf72f336929c9405f485dd90baef31a401776675f785f69a5a519f0b099ca"}, + {file = "types_setuptools-65.6.0.1-py3-none-any.whl", hash = "sha256:c957599502195ab98e90f0560466fa963f6a23373905e6d4e1772dbfaf1e44b7"}, +] +typing-extensions = [ + {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, + {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, +] +urllib3 = [ + {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, + {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, +] +uvloop = [ + {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718"}, + {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c"}, + {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d"}, + {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff3d00b70ce95adce264462c930fbaecb29718ba6563db354608f37e49e09024"}, + {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a5abddb3558d3f0a78949c750644a67be31e47936042d4f6c888dd6f3c95f4aa"}, + {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8efcadc5a0003d3a6e887ccc1fb44dec25594f117a94e3127954c05cf144d811"}, + {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3378eb62c63bf336ae2070599e49089005771cc651c8769aaad72d1bd9385a7c"}, + {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6aafa5a78b9e62493539456f8b646f85abc7093dd997f4976bb105537cf2635e"}, + {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c686a47d57ca910a2572fddfe9912819880b8765e2f01dc0dd12a9bf8573e539"}, + {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:864e1197139d651a76c81757db5eb199db8866e13acb0dfe96e6fc5d1cf45fc4"}, + {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2a6149e1defac0faf505406259561bc14b034cdf1d4711a3ddcdfbaa8d825a05"}, + {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6708f30db9117f115eadc4f125c2a10c1a50d711461699a0cbfaa45b9a78e376"}, + {file = "uvloop-0.17.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:23609ca361a7fc587031429fa25ad2ed7242941adec948f9d10c045bfecab06b"}, + {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2deae0b0fb00a6af41fe60a675cec079615b01d68beb4cc7b722424406b126a8"}, + {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45cea33b208971e87a31c17622e4b440cac231766ec11e5d22c76fab3bf9df62"}, + {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9b09e0f0ac29eee0451d71798878eae5a4e6a91aa275e114037b27f7db72702d"}, + {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dbbaf9da2ee98ee2531e0c780455f2841e4675ff580ecf93fe5c48fe733b5667"}, + {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a4aee22ece20958888eedbad20e4dbb03c37533e010fb824161b4f05e641f738"}, + {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:307958f9fc5c8bb01fad752d1345168c0abc5d62c1b72a4a8c6c06f042b45b20"}, + {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ebeeec6a6641d0adb2ea71dcfb76017602ee2bfd8213e3fcc18d8f699c5104f"}, + {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1436c8673c1563422213ac6907789ecb2b070f5939b9cbff9ef7113f2b531595"}, + {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8887d675a64cfc59f4ecd34382e5b4f0ef4ae1da37ed665adba0c2badf0d6578"}, + {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3db8de10ed684995a7f34a001f15b374c230f7655ae840964d51496e2f8a8474"}, + {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d37dccc7ae63e61f7b96ee2e19c40f153ba6ce730d8ba4d3b4e9738c1dccc1b"}, + {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cbbe908fda687e39afd6ea2a2f14c2c3e43f2ca88e3a11964b297822358d0e6c"}, + {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d97672dc709fa4447ab83276f344a165075fd9f366a97b712bdd3fee05efae8"}, + {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1e507c9ee39c61bfddd79714e4f85900656db1aec4d40c6de55648e85c2799c"}, + {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c092a2c1e736086d59ac8e41f9c98f26bbf9b9222a76f21af9dfe949b99b2eb9"}, + {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded"}, + {file = "uvloop-0.17.0.tar.gz", hash = "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1"}, +] +virtualenv = [ + {file = "virtualenv-20.17.0-py3-none-any.whl", hash = "sha256:40a7e06a98728fd5769e1af6fd1a706005b4bb7e16176a272ed4292473180389"}, + {file = "virtualenv-20.17.0.tar.gz", hash = "sha256:7d6a8d55b2f73b617f684ee40fd85740f062e1f2e379412cb1879c7136f05902"}, +] +yarl = [ + {file = "yarl-1.8.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28"}, + {file = "yarl-1.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3"}, + {file = "yarl-1.8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880"}, + {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40"}, + {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b"}, + {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497"}, + {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a"}, + {file = "yarl-1.8.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f"}, + {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd"}, + {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957"}, + {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28"}, + {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843"}, + {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453"}, + {file = "yarl-1.8.1-cp310-cp310-win32.whl", hash = "sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272"}, + {file = "yarl-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0"}, + {file = "yarl-1.8.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035"}, + {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc"}, + {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b"}, + {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231"}, + {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda"}, + {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507"}, + {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee"}, + {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0"}, + {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d"}, + {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd"}, + {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780"}, + {file = "yarl-1.8.1-cp37-cp37m-win32.whl", hash = "sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07"}, + {file = "yarl-1.8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802"}, + {file = "yarl-1.8.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a"}, + {file = "yarl-1.8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1"}, + {file = "yarl-1.8.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548"}, + {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461"}, + {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe"}, + {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae"}, + {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc"}, + {file = "yarl-1.8.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae"}, + {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546"}, + {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead"}, + {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4"}, + {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e"}, + {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae"}, + {file = "yarl-1.8.1-cp38-cp38-win32.whl", hash = "sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0"}, + {file = "yarl-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4"}, + {file = "yarl-1.8.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936"}, + {file = "yarl-1.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350"}, + {file = "yarl-1.8.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357"}, + {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b"}, + {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54"}, + {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb"}, + {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c"}, + {file = "yarl-1.8.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6"}, + {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64"}, + {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae"}, + {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3"}, + {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0"}, + {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e"}, + {file = "yarl-1.8.1-cp39-cp39-win32.whl", hash = "sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6"}, + {file = "yarl-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be"}, + {file = "yarl-1.8.1.tar.gz", hash = "sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf"}, +] +zipp = [ + {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, + {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, +] diff --git a/pylama.ini b/pylama.ini new file mode 100644 index 00000000..32434b79 --- /dev/null +++ b/pylama.ini @@ -0,0 +1,9 @@ +[pylama] +linters = mccabe,pycodestyle,pyflakes +skip = *env*,.tox*,*build*,.*,env/*,.venv/* +ignore = C901 + +[pylama:pycodestyle] +max_line_length = 80 +show-pep8 = True +show-source = True diff --git a/pylava.ini b/pylava.ini deleted file mode 100644 index 64703726..00000000 --- a/pylava.ini +++ /dev/null @@ -1,6 +0,0 @@ -[pylava] -ignore=C901,E252 -skip = *env*,.tox*,*build*,.* - -[pylava:pycodestyle] -max_line_length = 80 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..e969f99e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,102 @@ +[tool.poetry] +name = "aiomisc" +version = "16.2.11" +description = "aiomisc - miscellaneous utils for asyncio" +authors = ["Dmitry Orlov "] +readme = "README.rst" +license = "MIT" +homepage = "https://github.com/aiokitchen/aiomisc" +classifiers = [ + "Framework :: Pytest", + "ntended Audience :: Developers", + "Natural Language :: Russian", + "Operating System :: MacOS", + "Operating System :: POSIX", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: Implementation :: CPython", +] +packages = [ + { include = "aiomisc" }, + { include = "aiomisc_log" }, + { include = "aiomisc_pytest" }, + { include = "aiomisc_worker" }, +] + +[tool.poetry.urls] +"Source" = "https://github.com/aiokitchen/aiomisc" +"Tracker" = "https://github.com/aiokitchen/aiomisc/issues" +"Changelog" = "https://github.com/aiokitchen/aiomisc/blob/master/CHANGELOG.md" +"Documentation" = "https://aiomisc.readthedocs.io/en/latest/" + +[tool.poetry.dependencies] +python = "^3.7" +colorlog = "^6.0" + +[tool.poetry.group.dev.dependencies] +aiocontextvars = "0.2.2" +aiohttp = "<4" +aiohttp-asgi = "^0.4.0" +async-timeout = "^4.0.2" +autoflake = "1.4" +coveralls = "^3.3.1" +croniter = "^1.3.8" +fastapi = "^0.88.0" +freezegun = "<1.1" +mypy = "^0.991" +pre-commit = "^2.20.0" +pylama = "^8.4.1" +pytest = "^7.2.0" +pytest-cov = "^4.0.0" +pytest-freezegun = "^0.4.2" +pytest-rst = ">=0.0.7" +pytest-subtests = "^0.9.0" +rich = "^12.6" +setproctitle = "^1.3" +sphinx = ">=3.5.1" +sphinx-autobuild = "^2021.3.14" +sphinx-intl = "^2.0" +timeout-decorator = "^0.5.0" +types-croniter = "^1.3" +collective-checkdocs = "^0.2" +tox = "^3.27.1" +types-setuptools = "^65.6.0.1" +raven = "^6.10.0" + +[tool.poetry.group.uvloop.dependencies] +uvloop = "^0.17.0" + +[tool.poetry.plugins.pytest11] +aiomisc = "aiomisc_pytest.pytest_plugin" + +[tool.poetry.extras] +aiohttp = ["aiohttp"] +asgi = ["aiohttp-asgi"] +carbon = ["aiocarbon~=0.15"] +raven = ["aiohttp', 'raven"] +uvloop = ["uvloop>=0.14,<1"] +cron = ["croniter~=1.3.8"] + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.mypy] +check_untyped_defs = true +disallow_any_generics = false +disallow_incomplete_defs = true +disallow_subclassing_any = true +disallow_untyped_calls = true +disallow_untyped_decorators = true +disallow_untyped_defs = true +follow_imports = "silent" +no_implicit_reexport = true +strict_optional = true +warn_redundant_casts = true +warn_unused_configs = true +warn_unused_ignores = true +files = "aiomisc, aiomisc_log, aiomisc_worker" diff --git a/requirements.dev.txt b/requirements.dev.txt deleted file mode 100644 index baef9c0d..00000000 --- a/requirements.dev.txt +++ /dev/null @@ -1,24 +0,0 @@ -aiocontextvars==0.2.2 -aiohttp-asgi -aiohttp<4 -async-timeout -coveralls -croniter~=0.3.34 -fastapi -freezegun<1.1 -mypy==0.991 -pylava -pytest -pytest-cov~=3.0 -pytest-freezegun~=0.4.2 -pytest-rst>=0.0.7 -pytest-subtests -raven-aiohttp -rich -setproctitle -sphinx-autobuild -sphinx-intl -sphinx>=3.5.1 -timeout-decorator -tox>=2.4 -types-croniter diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index e773e2f3..00000000 --- a/setup.cfg +++ /dev/null @@ -1,17 +0,0 @@ -[mypy] -check_untyped_defs = True -disallow_any_generics = False -disallow_incomplete_defs = True -disallow_subclassing_any = True -disallow_untyped_calls = True -disallow_untyped_decorators = True -disallow_untyped_defs = True -follow_imports = silent -no_implicit_reexport = True -strict_optional = True -warn_redundant_casts = True -warn_unused_configs = True -warn_unused_ignores = True - -[mypy-tests.*] -ignore_errors = True diff --git a/setup.py b/setup.py deleted file mode 100644 index c7ea6e29..00000000 --- a/setup.py +++ /dev/null @@ -1,92 +0,0 @@ -import os -import platform - -from setuptools import setup, find_packages - - -from importlib.machinery import SourceFileLoader - - -module_name = 'aiomisc' - -try: - version = SourceFileLoader( - module_name, - os.path.join(module_name, 'version.py') - ).load_module() - - version_info = version.version_info -except FileNotFoundError: - version_info = (0, 0, 0) - - -__version__ = '{}.{}.{}'.format(*version_info) - - -def load_requirements(fname): - """ load requirements from a pip requirements file """ - with open(fname) as f: - line_iter = (line.strip() for line in f.readlines()) - return [line for line in line_iter if line and line[0] != '#'] - - -requirements = ["colorlog"] - -if platform.system() == "Linux": - requirements.append("logging-journald~=0.6.2") - - -setup( - name=module_name, - version=__version__, - author='Dmitry Orlov', - author_email='me@mosquito.su', - license='MIT', - description='aiomisc - miscellaneous utils for asyncio', - long_description=open("README.rst").read(), - platforms="all", - classifiers=[ - "Framework :: Pytest", - 'Intended Audience :: Developers', - 'Natural Language :: Russian', - 'Operating System :: MacOS', - 'Operating System :: POSIX', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: Implementation :: CPython', - ], - packages=find_packages(exclude=['tests*']), - package_data={ - "aiomisc": ["py.typed"], - "aiomisc_log": ["py.typed"], - "aiomisc_pytest": ["py.typed"], - "aiomisc_worker": ["py.typed"], - }, - install_requires=requirements, - extras_require={ - 'aiohttp': ['aiohttp'], - 'asgi': ['aiohttp-asgi'], - 'carbon': ['aiocarbon~=0.15'], - 'develop': load_requirements('requirements.dev.txt'), - 'raven': ['aiohttp', 'raven'], - 'uvloop': ['uvloop>=0.14,<1'], - 'cron': ['croniter~=0.3.34'], - }, - entry_points={ - "pytest11": ["aiomisc = aiomisc_pytest.pytest_plugin"] - }, - python_requires=">=3.7, <4", - url='https://github.com/aiokitchen/aiomisc', - project_urls={ - "Source": "https://github.com/aiokitchen/aiomisc", - "Tracker": "https://github.com/aiokitchen/aiomisc/issues", - "Changelog": ( - "https://github.com/aiokitchen/aiomisc/blob/master/CHANGELOG.md" - ), - "Documentation": "https://aiomisc.readthedocs.io/en/latest/", - }, -) diff --git a/tox.ini b/tox.ini index 981dba8a..b3723373 100644 --- a/tox.ini +++ b/tox.ini @@ -1,119 +1,19 @@ [tox] -envlist = pylava,checkdoc,py3{7-11},uvloop3{7-10},pydoc,rpc +envlist = rpc,rpc_udp +isolated_build = True [testenv] -passenv = COVERALLS_* GITHUB_* TEST_* FORCE_COLOR -usedevelop = true - -extras = - develop - -commands= - pytest -v \ - --cov=aiomisc \ - --cov=aiomisc_log \ - --cov=aiomisc_pytest \ - --cov=aiomisc_worker \ - --cov-report=term-missing \ - --doctest-modules \ - --aiomisc-test-timeout=120 \ - tests - - coveralls - -[testenv:pydoc] -basepython=python3.10 -usedevelop = true - -extras = - develop - -commands= - pytest -sv docs/source - -[testenv:uvloop37] -basepython=python3.7 -extras = - develop - uvloop - -[testenv:uvloop38] -basepython=python3.8 -extras = - develop - uvloop - -[testenv:uvloop39] -basepython=python3.9 -extras = - develop - uvloop - -[testenv:uvloop310] -basepython=python3.10 -extras = - develop - uvloop - -[testenv:rpc] basepython=python3.10 deps = - msgspec~=0.4.2 - uvloop - -changedir=examples/rpc + msgspec~=0.9.1 + uvloop~=0.17.0 commands= pytest -v --doctest-modules tests.py +[testenv:rpc] +changedir=examples/rpc [testenv:rpc_udp] -basepython=python3.10 - -deps = - msgspec~=0.4.2 - uvloop - changedir=examples/rpc_udp - -commands= - pytest -v --doctest-modules tests.py - - -[testenv:checkdoc] -skip_install=true -deps = - collective.checkdocs - pygments - -commands = - python setup.py checkdocs - - -[testenv:pylava] -deps = - pyflakes==2.4.0 - pylava - -commands= - pylava -o pylava.ini . - - -[testenv:mypy] -usedevelop = true - -deps = - mypy==0.991 - -commands = - mypy --install-types --non-interactive aiomisc aiomisc_log aiomisc_worker - - -[testenv:gray] - -deps = - gray - autoflake==1.4 - -commands = - gray aiomisc* From 80996abe8e01c3c11ff1a44d7c15bf875a397add Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:21:07 +0300 Subject: [PATCH 02/45] WIP --- .github/workflows/tests.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b62afc37..649af573 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,7 @@ jobs: - run: poetry run mypy env: FORCE_COLOR: 1 - "docs examples": + docs-examples: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -47,7 +47,7 @@ jobs: env: FORCE_COLOR: 1 - "tests on linux": + tests-on-linux: runs-on: ubuntu-latest strategy: @@ -87,7 +87,7 @@ jobs: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - "tests on macos": + tests-on-macos: runs-on: macos-latest strategy: @@ -126,7 +126,7 @@ jobs: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - "tests on windows": + tests-on-windows: runs-on: windows-latest strategy: @@ -164,7 +164,7 @@ jobs: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - "tests rpc example": + tests-rpc-example: runs-on: ubuntu-latest strategy: @@ -191,10 +191,10 @@ jobs: finish: needs: - - "tests on linux" - - "tests on macos" - - "tests on windows" - - "tests rpc example" + - tests-on-linux + - tests-on-macos + - tests-on-windows + - tests-rpc-example runs-on: ubuntu-latest steps: - name: Coveralls Finished From c27a578608e46030d28578af0db3e9fe2763f5c8 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:21:58 +0300 Subject: [PATCH 03/45] remove tox --- poetry.lock | 29 +---------------------------- pyproject.toml | 1 - 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/poetry.lock b/poetry.lock index 26847558..319189b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1015,29 +1015,6 @@ category = "dev" optional = false python-versions = ">= 3.7" -[[package]] -name = "tox" -version = "3.27.1" -description = "tox is a generic virtualenv management and test command line tool" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[package.dependencies] -colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} -filelock = ">=3.0.0" -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} -packaging = ">=14" -pluggy = ">=0.12.0" -py = ">=1.4.17" -six = ">=1.14.0" -tomli = {version = ">=2.0.1", markers = "python_version >= \"3.7\" and python_version < \"3.11\""} -virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" - -[package.extras] -docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] -testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)"] - [[package]] name = "typed-ast" version = "1.5.4" @@ -1150,7 +1127,7 @@ uvloop = [] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "d242beb6df1c2be0c0782359af78f593035ae253135bfd9b6d3c52b008b11869" +content-hash = "888973ca20f7382319bd0752bde460bb2acbcfed2c2efc70a426428cca5a18f7" [metadata.files] aiocontextvars = [ @@ -1953,10 +1930,6 @@ tornado = [ {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, ] -tox = [ - {file = "tox-3.27.1-py2.py3-none-any.whl", hash = "sha256:f52ca66eae115fcfef0e77ef81fd107133d295c97c52df337adedb8dfac6ab84"}, - {file = "tox-3.27.1.tar.gz", hash = "sha256:b2a920e35a668cc06942ffd1cf3a4fb221a4d909ca72191fb6d84b0b18a7be04"}, -] typed-ast = [ {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, diff --git a/pyproject.toml b/pyproject.toml index e969f99e..65359065 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,6 @@ sphinx-intl = "^2.0" timeout-decorator = "^0.5.0" types-croniter = "^1.3" collective-checkdocs = "^0.2" -tox = "^3.27.1" types-setuptools = "^65.6.0.1" raven = "^6.10.0" From 0bb4c7a82ed6f40af7b76563c4ea1275f664d127 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:23:43 +0300 Subject: [PATCH 04/45] fix rpx tests --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 649af573..5fc03ccb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -182,7 +182,7 @@ jobs: python-version: "3.10" - run: python -m pip install poetry - run: poetry install --with=uvloop - - run: pip install msgspec~=0.9.1 + - run: poetry run python -m pip install msgspec~=0.9.1 - run: >- cd examples/${{ matrix.example }} && poetry run pytest -v --doctest-modules tests.py From c909f38242793f97dc5d04c96b3b055b8fdea73a Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:25:39 +0300 Subject: [PATCH 05/45] report coverage only from linux tests --- .github/workflows/tests.yml | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5fc03ccb..5ddaa7d7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -107,24 +107,9 @@ jobs: - run: python -m pip install poetry - run: poetry install - run: poetry install --without=uvloop - - run: >- - poetry run pytest - -vv - --cov=aiomisc - --cov=aiomisc_log - --cov=aiomisc_pytest - --cov=aiomisc_worker - --cov-report=term-missing - --doctest-modules - --aiomisc-test-timeout=120 - tests + - run: poetry run pytest -vv --aiomisc-test-timeout=120 tests env: FORCE_COLOR: 1 - - run: poetry run coveralls - env: - COVERALLS_PARALLEL: 'true' - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} tests-on-windows: runs-on: windows-latest @@ -145,24 +130,9 @@ jobs: python-version: "${{ matrix.python }}" - run: python -m pip install poetry - run: poetry install --without=uvloop - - run: >- - poetry run pytest - -vv - --cov=aiomisc - --cov=aiomisc_log - --cov=aiomisc_pytest - --cov=aiomisc_worker - --cov-report=term-missing - --doctest-modules - --aiomisc-test-timeout=120 - tests + - run: poetry run pytest -vv --aiomisc-test-timeout=120 tests env: FORCE_COLOR: 1 - - run: poetry run coveralls - env: - COVERALLS_PARALLEL: 'true' - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} tests-rpc-example: runs-on: ubuntu-latest From b5d1991e8ae56b791c8418ffc3a0f050a3032045 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:28:33 +0300 Subject: [PATCH 06/45] fix pytest command --- .github/workflows/tests.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5ddaa7d7..7aa97ee6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -69,15 +69,15 @@ jobs: - run: python -m pip install poetry - run: poetry install --with=uvloop - run: >- - poetry run pytest - -vv - --cov=aiomisc - --cov=aiomisc_log - --cov=aiomisc_pytest - --cov=aiomisc_worker - --cov-report=term-missing - --doctest-modules - --aiomisc-test-timeout=120 + poetry run pytest \ + -vv \ + --cov=aiomisc \ + --cov=aiomisc_log \ + --cov=aiomisc_pytest \ + --cov=aiomisc_worker \ + --cov-report=term-missing \ + --doctest-modules \ + --aiomisc-test-timeout=120 \ tests env: FORCE_COLOR: 1 From 7bbf0db96c6e1622fab1e236cc82f82bf4b98d00 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:32:10 +0300 Subject: [PATCH 07/45] fix macos without uvloop --- .github/workflows/tests.yml | 1 - pyproject.toml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7aa97ee6..df8e4103 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -105,7 +105,6 @@ jobs: with: python-version: "${{ matrix.python }}" - run: python -m pip install poetry - - run: poetry install - run: poetry install --without=uvloop - run: poetry run pytest -vv --aiomisc-test-timeout=120 tests env: diff --git a/pyproject.toml b/pyproject.toml index 65359065..361fc9d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,7 @@ aiohttp = "<4" aiohttp-asgi = "^0.4.0" async-timeout = "^4.0.2" autoflake = "1.4" +collective-checkdocs = "^0.2" coveralls = "^3.3.1" croniter = "^1.3.8" fastapi = "^0.88.0" @@ -55,6 +56,7 @@ pytest-cov = "^4.0.0" pytest-freezegun = "^0.4.2" pytest-rst = ">=0.0.7" pytest-subtests = "^0.9.0" +raven = "^6.10.0" rich = "^12.6" setproctitle = "^1.3" sphinx = ">=3.5.1" @@ -62,9 +64,7 @@ sphinx-autobuild = "^2021.3.14" sphinx-intl = "^2.0" timeout-decorator = "^0.5.0" types-croniter = "^1.3" -collective-checkdocs = "^0.2" types-setuptools = "^65.6.0.1" -raven = "^6.10.0" [tool.poetry.group.uvloop.dependencies] uvloop = "^0.17.0" From fef929944e187dbcac72289a15ef8c00b4fb8cb0 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:39:07 +0300 Subject: [PATCH 08/45] no test 3.11 on macos --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index df8e4103..ca3027e8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -97,7 +97,6 @@ jobs: python: - '3.9' - '3.10' - - '3.11' steps: - uses: actions/checkout@v2 - name: Setup python${{ matrix.python }} From 656b3cd0aae0f62efe29f6f22629ff9a1911bbcd Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:42:14 +0300 Subject: [PATCH 09/45] ignore IO error when logging trying to flush at exit --- aiomisc/log.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/aiomisc/log.py b/aiomisc/log.py index 9240fb4e..7ccf2933 100644 --- a/aiomisc/log.py +++ b/aiomisc/log.py @@ -56,7 +56,11 @@ def wrap_logging_handler( ), no_return=True, statistic_name="logger", ) - atexit.register(handler.flush) + def at_exit() -> None: + with suppress(Exception): + handler.flush() + + atexit.register(at_exit) return buffered_handler From 27c1a5589507863e8b020b8b1873f7935cc9fd7a Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 1 Dec 2022 00:48:10 +0300 Subject: [PATCH 10/45] unregister atexit on handler del --- aiomisc/log.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/aiomisc/log.py b/aiomisc/log.py index 7ccf2933..157a5cff 100644 --- a/aiomisc/log.py +++ b/aiomisc/log.py @@ -5,8 +5,10 @@ import time import traceback from contextlib import suppress +from functools import partial from socket import socket -from typing import Any, Dict, List, Optional, Union +from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union +from weakref import finalize import aiomisc_log from aiomisc_log.enum import LogFormat, LogLevel @@ -38,6 +40,16 @@ def has_target() -> bool: time.sleep(flush_interval) +def suppressor( + callback: Callable[..., None], + exceptions: Tuple[Type[BaseException], ...] = (Exception,), +) -> Callable[..., None]: + def wrapper() -> None: + with suppress(*exceptions): + callback() + return wrapper + + def wrap_logging_handler( handler: logging.Handler, loop: Optional[asyncio.AbstractEventLoop] = None, @@ -56,11 +68,9 @@ def wrap_logging_handler( ), no_return=True, statistic_name="logger", ) - def at_exit() -> None: - with suppress(Exception): - handler.flush() - - atexit.register(at_exit) + at_exit_flusher = suppressor(handler.flush) + atexit.register(at_exit_flusher) + finalize(buffered_handler, partial(atexit.unregister, at_exit_flusher)) return buffered_handler From ad388a1bb9736d71df91560f8f4bab9de36c377c Mon Sep 17 00:00:00 2001 From: Nikitin Artyom Date: Fri, 2 Dec 2022 22:54:08 +0300 Subject: [PATCH 11/45] Fix aggregate tests (#155) --- tests/test_aggregate.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_aggregate.py b/tests/test_aggregate.py index e31cd858..e9d86ed8 100644 --- a/tests/test_aggregate.py +++ b/tests/test_aggregate.py @@ -120,7 +120,6 @@ async def test_max_count(loop): @aggregate(leeway * 1000, max_count) async def pow(*args: float, power: float = 2) -> List[float]: nonlocal t_exec - await asyncio.sleep(0.03) t_exec = time.time() event.set() @@ -151,7 +150,6 @@ async def test_max_count_multiple_batches(loop): @aggregate(leeway * 1000, max_count) async def pow(*args: float, power: float = 2) -> List[float]: nonlocal t_exec - await asyncio.sleep(0.03) t_exec = time.time() event.set() @@ -167,7 +165,7 @@ async def pow(*args: float, power: float = 2) -> List[float]: await event.wait() event.clear() elapsed = t_exec - t - assert 0 < elapsed < leeway * 2 + assert 0 < elapsed < leeway await wait(tasks[:5]) for i in range(5): @@ -258,7 +256,6 @@ async def test_max_count_cancel(loop): @aggregate(leeway * 1000, max_count) async def pow(*args: float, power: float = 2) -> List[float]: nonlocal executions, executing_task, t_exec, delay_exec - await asyncio.sleep(0.03) t_exec = time.time() executions += 1 executing_task = tasks[arg.get()] From e9da793b104c2ebae10cc35bdd4175d868340dd8 Mon Sep 17 00:00:00 2001 From: Nikitin Artyom Date: Sun, 4 Dec 2022 09:24:29 +0300 Subject: [PATCH 12/45] Fix aggregate tests more (#156) --- tests/test_aggregate.py | 93 +++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/tests/test_aggregate.py b/tests/test_aggregate.py index e9d86ed8..36384a39 100644 --- a/tests/test_aggregate.py +++ b/tests/test_aggregate.py @@ -1,4 +1,5 @@ import asyncio +import logging import math import platform import time @@ -10,6 +11,8 @@ from aiomisc.aggregate import Arg, ResultNotSetError, aggregate, aggregate_async +log = logging.getLogger(__name__) + pytestmark = pytest.mark.skipif( platform.system() == "Windows", @@ -18,6 +21,28 @@ ) +@pytest.fixture +async def leeway(): + async def func(): + loop = asyncio.get_event_loop() + t = loop.time() + await asyncio.sleep(0) + return loop.time() - t + + tasks = [ + asyncio.create_task(func()) + for _ in range(100) + ] + ts = await asyncio.gather(*tasks) + estimated = max(ts) * 2 + default = 0.1 + + if estimated > default: + log.warning('Slow system: leeway increased to %.2f s', leeway) + + return max(estimated, default) + + async def test_invalid_func(): with pytest.raises(ValueError) as excinfo: @aggregate(10) @@ -48,30 +73,22 @@ async def pho(*args): assert str(excinfo.value) == "max_count must be positive int or None" -async def test_error(loop): - t_exec = 0 +async def test_error(loop, leeway): event = Event() - leeway = 0.1 @aggregate(leeway * 1000) async def pow(*args: float, power: float = 2) -> Any: - nonlocal t_exec - t_exec = time.time() event.set() raise ValueError async def pho(num: int): return await pow(float(num)) - t = time.time() - tasks = [] for i in range(10): tasks.append(loop.create_task(pho(i))) await event.wait() - elapsed = t_exec - t - assert leeway * 0.9 < elapsed < leeway * 2 await wait(tasks) for task in tasks: @@ -79,10 +96,9 @@ async def pho(num: int): assert isinstance(task.exception(), ValueError) -async def test_leeway_ok(loop): +async def test_leeway_ok(loop, leeway): t_exec = 0 event = Event() - leeway = 0.1 @aggregate(leeway * 1000) async def pow(*args: float, power: float = 2) -> List[float]: @@ -92,12 +108,12 @@ async def pow(*args: float, power: float = 2) -> List[float]: return [math.pow(num, power) for num in args] - t = time.time() - tasks = [] for i in range(9): tasks.append(loop.create_task(pow(i))) + t = time.time() + await asyncio.sleep(leeway * 0.1) assert all(not task.done() for task in tasks) @@ -111,10 +127,9 @@ async def pow(*args: float, power: float = 2) -> List[float]: assert task.result() == math.pow(i, 2) -async def test_max_count(loop): +async def test_max_count(loop, leeway): t_exec = 0 event = Event() - leeway = 0.1 max_count = 5 @aggregate(leeway * 1000, max_count) @@ -125,12 +140,12 @@ async def pow(*args: float, power: float = 2) -> List[float]: return [math.pow(num, power) for num in args] - t = time.time() - tasks = [] for i in range(5): tasks.append(loop.create_task(pow(i))) + t = time.time() + await event.wait() elapsed = t_exec - t assert 0 < elapsed < leeway * 2 @@ -141,10 +156,9 @@ async def pow(*args: float, power: float = 2) -> List[float]: assert task.result() == math.pow(i, 2) -async def test_max_count_multiple_batches(loop): +async def test_max_count_multiple_batches(loop, leeway): t_exec = 0 event = Event() - leeway = 0.1 max_count = 5 @aggregate(leeway * 1000, max_count) @@ -155,12 +169,12 @@ async def pow(*args: float, power: float = 2) -> List[float]: return [math.pow(num, power) for num in args] - t = time.time() - tasks = [] for i in range(9): tasks.append(loop.create_task(pow(i))) + t = time.time() + # Wait for the first batch await event.wait() event.clear() @@ -173,23 +187,21 @@ async def pow(*args: float, power: float = 2) -> List[float]: for i in range(5, 9): assert not tasks[i].done() + tasks.append(loop.create_task(pow(9))) + # Wait for the second batch await event.wait() - elapsed = t_exec - t - assert leeway * 0.9 < elapsed < leeway * 2 - await wait(tasks[5:]) for i, task in enumerate(tasks): assert task.done() assert task.result() == math.pow(i, 2) -async def test_leeway_cancel(loop): +async def test_leeway_cancel(loop, leeway): t_exec = 0 delay_exec = 0.1 event = Event() executions = 0 - leeway = 0.1 arg = ContextVar("arg") tasks = [] executing_task = None @@ -209,11 +221,11 @@ async def pho(num: int): arg.set(num) return await pow(float(num)) - t = time.time() - for i in range(9): tasks.append(loop.create_task(pho(i))) + t = time.time() + # Execution must have started await event.wait() event.clear() @@ -268,12 +280,12 @@ async def pho(num: int): arg.set(num) return await pow(float(num)) - t = time.time() - tasks = [] for i in range(5): tasks.append(loop.create_task(pho(i))) + t = time.time() + # Execution must have started await event.wait() event.clear() @@ -303,12 +315,10 @@ async def pho(num: int): assert task.result() == math.pow(i, 2) -async def test_max_count_multiple_batches_cancel(loop): - t_exec = 0 +async def test_max_count_multiple_batches_cancel(loop, leeway): delay_exec = 0.1 event = Event() executions = 0 - leeway = 0.1 max_count = 5 arg = ContextVar("arg") tasks = [] @@ -316,8 +326,7 @@ async def test_max_count_multiple_batches_cancel(loop): @aggregate(leeway * 1000, max_count) async def pow(*args: float, power: float = 2) -> List[float]: - nonlocal executions, executing_task, t_exec, delay_exec - t_exec = time.time() + nonlocal executions, executing_task, delay_exec executions += 1 executing_task = tasks[arg.get()] event.set() @@ -329,8 +338,6 @@ async def pho(num: int): arg.set(num) return await pow(float(num)) - t = time.time() - tasks = [] for i in range(9): tasks.append(loop.create_task(pho(i))) @@ -362,10 +369,9 @@ async def pho(num: int): assert task.done() assert task.result() == math.pow(i, 2) + tasks.append(loop.create_task(pho(9))) # Second batch must have started execution await event.wait() - elapsed = t_exec - t - assert leeway * 0.9 < elapsed < leeway * 2 assert all(not task.done() for task in tasks[5:]) assert executions == 3 @@ -376,8 +382,7 @@ async def pho(num: int): assert task.result() == math.pow(i, 2) -async def test_low_level_sloppy(loop): - leeway = 0.1 +async def test_low_level_sloppy(loop, leeway): max_count = 2 @aggregate_async(leeway * 1000, max_count=max_count) @@ -396,8 +401,7 @@ async def pho(*args: Arg): assert isinstance(task2.exception(), ResultNotSetError) -async def test_low_level_ok(loop): - leeway = 0.1 +async def test_low_level_ok(loop, leeway): @aggregate_async(leeway * 1000) async def pow(*args: Arg, power: float = 2): @@ -414,8 +418,7 @@ async def pow(*args: Arg, power: float = 2): assert task.result() == math.pow(i, 2) -async def test_low_level_error(loop): - leeway = 0.1 +async def test_low_level_error(loop, leeway): @aggregate_async(leeway * 1000) async def pho(*args: Arg): From b00ee355241cc61041391657c7d960c3d0ee8fc0 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Mon, 19 Dec 2022 15:39:48 +0300 Subject: [PATCH 13/45] Pin logging-journald --- poetry.lock | 14 +++++++++++++- pyproject.toml | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 319189b8..404d7509 100644 --- a/poetry.lock +++ b/poetry.lock @@ -420,6 +420,14 @@ python-versions = "*" six = "*" tornado = {version = "*", markers = "python_version > \"2.7\""} +[[package]] +name = "logging-journald" +version = "0.6.4" +description = "Pure python logging handler for writing logs to the journald using native protocol" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" + [[package]] name = "markupsafe" version = "2.1.1" @@ -1127,7 +1135,7 @@ uvloop = [] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "888973ca20f7382319bd0752bde460bb2acbcfed2c2efc70a426428cca5a18f7" +content-hash = "f4e5a531dfe77edef88dde12dac5a042fd2b537b5fc6fb6dad1be4e784d804b4" [metadata.files] aiocontextvars = [ @@ -1479,6 +1487,10 @@ jinja2 = [ livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, ] +logging-journald = [ + {file = "logging_journald-0.6.4-py3-none-any.whl", hash = "sha256:4d4e169cf2814ddbc30687daef2ce38a58a0ec9cd7d739f21f0fb745c4a70ee9"}, + {file = "logging_journald-0.6.4.tar.gz", hash = "sha256:a03aa0a1b85ab5f3cdc534511d98ff55f58479e44fbf4e9eb5b965923cbb0c27"}, +] markupsafe = [ {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, diff --git a/pyproject.toml b/pyproject.toml index 361fc9d4..bef53515 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,7 @@ packages = [ [tool.poetry.dependencies] python = "^3.7" colorlog = "^6.0" +logging-journald = [{ version = '*', platform = 'linux' }] [tool.poetry.group.dev.dependencies] aiocontextvars = "0.2.2" From 3818a6e3e317f9e6f8860f836ad64dbc11229ee8 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Mon, 19 Dec 2022 18:07:13 +0300 Subject: [PATCH 14/45] mypy fixes in tests and refactor io --- .pre-commit-config.yaml | 28 ++-- aiomisc/io.py | 212 ++++++++++++++++++++----------- aiomisc/pool.py | 10 +- aiomisc/worker_pool.py | 2 +- pyproject.toml | 16 ++- tests/conftest.py | 6 +- tests/test_aggregate.py | 51 ++++---- tests/test_circuit_breaker.py | 5 +- tests/test_io.py | 5 +- tests/test_pool.py | 9 +- tests/test_process_pool.py | 4 +- tests/test_process_service.py | 4 +- tests/test_profiler.py | 4 +- tests/test_raven_service.py | 11 +- tests/test_recurring.py | 20 +-- tests/test_sdwatchdog_service.py | 14 +- tests/test_signal.py | 5 +- tests/test_thread_pool.py | 6 +- tests/test_utils.py | 7 +- tests/test_worker_pool.py | 25 ++-- tox.ini | 19 --- 21 files changed, 271 insertions(+), 192 deletions(-) delete mode 100644 tox.ini diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 821fecde..974f53fe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,20 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: + - repo: local + hooks: + - id: pylama + name: Check codestyle with Pylama + entry: poetry run mypy + language: system + types: [ python ] + + - id: mypy + name: Validate types with MyPy + entry: poetry run mypy + language: system + types: [ python ] + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.1.0 hooks: @@ -14,17 +28,3 @@ repos: hooks: - id: gray name: Reformat code with Gray - - - repo: local - hooks: - - id: pylama - name: Check codestyle with Pylama - entry: pylama - language: system - types: [ python ] - - - id: mypy - name: Validate types with MyPy - entry: mypy - language: system - types: [ python ] diff --git a/aiomisc/io.py b/aiomisc/io.py index 86cd30c4..68d60fd2 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -2,13 +2,16 @@ from concurrent.futures import Executor from functools import partial, total_ordering from pathlib import Path -from typing import Any, Awaitable, Callable, Generator, Optional, TypeVar, Union +from typing import ( + IO, Any, Awaitable, BinaryIO, Callable, Generator, Generic, List, Optional, + TextIO, TypeVar, Union, +) from .compat import EventLoopMixin from .thread_pool import threaded -T = TypeVar("T") +T = TypeVar("T", bound=Union[str, bytes]) def proxy_method_async( @@ -54,58 +57,50 @@ async def method(self, *args, **kwargs): # type: ignore return method -def proxy_method(name: str) -> Callable[..., Awaitable[Any]]: - def method(self: Any, *args: Any, **kwargs: Any) -> Any: - return getattr(self.fp, name)(*args, **kwargs) - - method.__name__ = name - return method - - -def proxy_property(name: str) -> property: - def fset(self: Any, value: Any) -> None: - setattr(self.fp, name, value) - - def fget(self: Any) -> Any: - return getattr(self.fp, name) - - def fdel(self: Any) -> None: - delattr(self.fp, name) - - return property(fget, fset, fdel) - - @total_ordering -class AsyncFileIOBase(EventLoopMixin): +class AsyncFileIO(EventLoopMixin, Generic[T]): __slots__ = ( "__opener", "fp", "executor", "__iterator_lock", ) + EventLoopMixin.__slots__ opener = staticmethod(threaded(open)) + _fp: Optional[Union[IO, BinaryIO, TextIO]] def __init__( self, fname: Union[str, Path], mode: str = "r", executor: Optional[Executor] = None, *args: Any, loop: Optional[asyncio.AbstractEventLoop] = None, **kwargs: Any, ): - self._loop = loop - self.fp = None self.executor = executor + self._loop = loop + self._fp = None self.__opener = partial(self.opener, fname, mode, *args, **kwargs) self.__iterator_lock = asyncio.Lock() + @classmethod + def open_fp( + cls, fp: IO, executor: Optional[Executor] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> "AsyncFileIO": + async_fp = cls(fp.name, mode=fp.mode, executor=executor, loop=loop) + async_fp._fp = fp + return async_fp + + @property + def fp(self) -> Union[IO, BinaryIO, TextIO]: + if self._fp is not None: + return self._fp + raise RuntimeError("file is not opened") + def closed(self) -> bool: - if self.fp is None: - raise RuntimeError("file is not opened") return self.fp.closed async def open(self) -> None: - if self.fp is not None: + if self._fp is not None: return + self._fp = await self.__opener() - self.fp = await self.__opener() # type: ignore - - def __await__(self) -> Generator[Any, Any, "AsyncFileIOBase"]: + def __await__(self) -> Generator[Any, Any, "AsyncFileIO"]: yield from self.open().__await__() return self @@ -129,12 +124,12 @@ def __del__(self) -> None: return self.fp.close() - del self.fp + del self._fp def __aiter__(self) -> "AsyncFileIOBase": return self - async def __anext__(self) -> Union[str, bytes]: + async def __anext__(self) -> T: async with self.__iterator_lock: line = await self.readline() @@ -156,65 +151,134 @@ def __lt__(self, other: Any) -> bool: def __hash__(self) -> int: return hash((self.__class__, self.fp)) - fileno = proxy_method("fileno") - isatty = proxy_method("isatty") + async def __execute_in_thread( + self, method: Callable[..., Any], *args: Any, + ) -> Any: + return await self.loop.run_in_executor(self.executor, method, *args) + + @property + def mode(self) -> str: + return self.fp.mode + + @property + def name(self) -> str: + return self.fp.name + + def fileno(self) -> int: + return self.fp.fileno() + + def isatty(self) -> bool: + return self.fp.isatty() + + async def close(self) -> None: + return await self.__execute_in_thread(self.fp.close) - mode = proxy_property("mode") - name = proxy_property("name") + def __getattribute__(self, name: str) -> Callable[..., Awaitable[Any]]: + async def method(*args: Any) -> Any: + return await self.__execute_in_thread( + getattr(self.fp, name), *args, + ) + method.__name__ = name + return method + + async def tell(self) -> int: + return self.fp.tell() + + async def readable(self) -> bool: + return self.fp.readable() + + async def seekable(self) -> bool: + return self.fp.seekable() + + async def writable(self) -> bool: + return self.fp.writable() + + async def flush(self) -> None: + await self.__execute_in_thread(self.fp.flush) - close = proxy_method_async("close") - detach = proxy_method_async("detach") - flush = proxy_method_async("flush") - peek = proxy_method_async("peek") - raw = proxy_property("raw") - read = proxy_method_async("read") - read1 = proxy_method_async("read1") - readinto = proxy_method_async("readinto") - readinto1 = proxy_method_async("readinto1") - readline = proxy_method_async("readline") - readlines = proxy_method_async("readlines") - seek = proxy_method_async("seek") - peek = proxy_method_async("peek") - truncate = proxy_method_async("truncate") - write = proxy_method_async("write") - writelines = proxy_method_async("writelines") + async def read(self, n: int = -1) -> T: + return await self.__execute_in_thread(self.fp.read, n) - tell = proxy_method_async("tell", in_executor=False) - readable = proxy_method_async("readable", in_executor=False) - seekable = proxy_method_async("seekable", in_executor=False) - writable = proxy_method_async("writable", in_executor=False) + async def readline(self, limit: int = -1) -> T: + return await self.__execute_in_thread(self.fp.readline, limit) + async def readlines(self, limit: int = -1) -> List[T]: + return await self.__execute_in_thread(self.fp.readlines, limit) -class AsyncTextFileIOBase: - newlines = proxy_property("newlines") - errors = proxy_property("errors") - line_buffering = proxy_property("line_buffering") - encoding = proxy_property("encoding") - buffer = proxy_property("buffer") + async def seek(self, offset: int, whence: int = 0) -> int: + return await self.__execute_in_thread(self.fp.seek, offset, whence) + async def truncate(self, size: Optional[int] = None) -> int: + return await self.__execute_in_thread(self.fp.truncate, size) -class AsyncBytesFileIOBase: - pass + async def write(self, s: T) -> int: + return await self.__execute_in_thread(self.fp.write, s) + async def writelines(self, lines: List[T]) -> None: + await self.__execute_in_thread(self.fp.writelines, lines) -class AsyncTextFileIO(AsyncFileIOBase, AsyncTextFileIOBase): - pass +AsyncFileIOBase = AsyncFileIO + + +class AsyncBinaryIO(AsyncFileIO[bytes]): + @property + def fp(self) -> BinaryIO: + return self._fp # type: ignore + + def __aiter__(self) -> "AsyncBytesFileIO": + return self + + async def __aenter__(self) -> "AsyncBinaryIO": + return await super().__aenter__() # type: ignore -class AsyncBytesFileIO(AsyncFileIOBase, AsyncBytesFileIOBase): - pass +class AsyncTextIO(AsyncFileIO[str]): + @property + def fp(self) -> TextIO: + return self._fp # type: ignore -AsyncFileT = Union[ - AsyncBytesFileIO, - AsyncTextFileIO, + @property + def newlines(self) -> Any: + return self.fp.newlines + + @property + def errors(self) -> Optional[str]: + return self.fp.errors + + @property + def line_buffering(self) -> int: + return self.fp.line_buffering + + @property + def encoding(self) -> str: + return self.fp.encoding + + def buffer(self) -> AsyncBinaryIO: + return AsyncBinaryIO.open_fp(self.fp.buffer) # type: ignore + + def __aiter__(self) -> "AsyncTextFileIO": + return self + + async def __aenter__(self) -> "AsyncTextIO": + return await super().__aenter__() # type: ignore + + +AsyncFileType = Union[ + AsyncBinaryIO, + AsyncTextIO, ] +# Aliases +AsyncBytesFileIO = AsyncBinaryIO +AsyncTextFileIO = AsyncTextIO +AsyncFileT = AsyncFileType + def async_open( fname: Union[str, Path], mode: str = "r", *args: Any, **kwargs: Any, -) -> AsyncFileT: +) -> AsyncFileType: if "b" in mode: return AsyncBytesFileIO( fname, mode, *args, **kwargs, diff --git a/aiomisc/pool.py b/aiomisc/pool.py index 783c2fa1..32f5dfda 100644 --- a/aiomisc/pool.py +++ b/aiomisc/pool.py @@ -5,14 +5,14 @@ from random import random from typing import ( Any, AsyncContextManager, Awaitable, Callable, Coroutine, DefaultDict, - NoReturn, Optional, Set, TypeVar, Union, + Generic, NoReturn, Optional, Set, TypeVar, Union, ) from .compat import EventLoopMixin from .utils import cancel_tasks -T = TypeVar("T") +T = TypeVar("T", bound=Any) Number = Union[int, float] log = logging.getLogger(__name__) @@ -45,7 +45,7 @@ async def __aexit__( await self.__aexit(self.__instance) -class PoolBase(ABC, EventLoopMixin): +class PoolBase(ABC, EventLoopMixin, Generic[T]): __slots__ = ( "_create_lock", "_instances", @@ -142,7 +142,7 @@ async def __create_new_instance(self) -> None: await self._instances.put(instance) - async def __acquire(self) -> Any: + async def __acquire(self) -> T: if not self._semaphore.locked(): await self.__create_new_instance() @@ -170,7 +170,7 @@ async def __release(self, instance: Any) -> None: self._instances.put_nowait(instance) - def acquire(self) -> ContextManager: + def acquire(self) -> AsyncContextManager[T]: return ContextManager(self.__acquire, self.__release) async def close(self, timeout: Optional[Number] = None) -> None: diff --git a/aiomisc/worker_pool.py b/aiomisc/worker_pool.py index d1e9c150..026f93df 100644 --- a/aiomisc/worker_pool.py +++ b/aiomisc/worker_pool.py @@ -124,7 +124,7 @@ def __create_supervisor(self, *identity: str) -> Popen: def __init__( self, workers: int, max_overflow: int = 0, *, - initializer: Optional[Callable[[], Any]] = None, + initializer: Optional[Callable[..., Any]] = None, initializer_args: Tuple[Any, ...] = (), initializer_kwargs: Mapping[str, Any] = MappingProxyType({}), statistic_name: Optional[str] = None, diff --git a/pyproject.toml b/pyproject.toml index bef53515..9f99c225 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -99,4 +99,18 @@ strict_optional = true warn_redundant_casts = true warn_unused_configs = true warn_unused_ignores = true -files = "aiomisc, aiomisc_log, aiomisc_worker" +files = [ + "aiomisc", + "aiomisc_log", + "aiomisc_worker", + "tests", +] + + +[[tool.mypy.overrides]] +module = ["tests.*"] +check_untyped_defs = true +disallow_incomplete_defs = false +disallow_untyped_calls = false +disallow_untyped_decorators = false +disallow_untyped_defs = false diff --git a/tests/conftest.py b/tests/conftest.py index a8214d7d..6e7413b6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,7 +14,7 @@ try: import uvloop except ImportError: - uvloop = None + uvloop = None # type: ignore @pytest.fixture @@ -59,8 +59,8 @@ def thread_pool_executor(request): policy_ids = ("asyncio",) if uvloop: - policies = (uvloop.EventLoopPolicy(),) + policies - policy_ids = ("uvloop",) + policy_ids + policies = (uvloop.EventLoopPolicy(),) + policies # type: ignore + policy_ids = ("uvloop",) + policy_ids # type: ignore @pytest.fixture(params=policies, ids=policy_ids) diff --git a/tests/test_aggregate.py b/tests/test_aggregate.py index 36384a39..101b6def 100644 --- a/tests/test_aggregate.py +++ b/tests/test_aggregate.py @@ -4,13 +4,14 @@ import platform import time from asyncio import Event, wait -from typing import Any, List +from typing import Any, List, Optional, Sequence import pytest -from aiocontextvars import ContextVar +from aiocontextvars import ContextVar # type: ignore from aiomisc.aggregate import Arg, ResultNotSetError, aggregate, aggregate_async + log = logging.getLogger(__name__) @@ -21,24 +22,24 @@ ) -@pytest.fixture -async def leeway(): - async def func(): +@pytest.fixture(scope="session") +def leeway() -> float: + async def func() -> float: loop = asyncio.get_event_loop() t = loop.time() await asyncio.sleep(0) return loop.time() - t - tasks = [ - asyncio.create_task(func()) - for _ in range(100) - ] - ts = await asyncio.gather(*tasks) - estimated = max(ts) * 2 + async def run() -> Sequence[float]: + tasks = [asyncio.create_task(func()) for _ in range(100)] + return await asyncio.gather(*tasks) + + ts: Sequence[float] = asyncio.run(run()) + estimated = max(ts) * 3 default = 0.1 if estimated > default: - log.warning('Slow system: leeway increased to %.2f s', leeway) + log.warning("Slow system: leeway increased to %.2f s", leeway) return max(estimated, default) @@ -97,8 +98,8 @@ async def pho(num: int): async def test_leeway_ok(loop, leeway): - t_exec = 0 - event = Event() + t_exec: float = 0. + event: Event = Event() @aggregate(leeway * 1000) async def pow(*args: float, power: float = 2) -> List[float]: @@ -128,7 +129,7 @@ async def pow(*args: float, power: float = 2) -> List[float]: async def test_max_count(loop, leeway): - t_exec = 0 + t_exec: float = 0. event = Event() max_count = 5 @@ -157,7 +158,7 @@ async def pow(*args: float, power: float = 2) -> List[float]: async def test_max_count_multiple_batches(loop, leeway): - t_exec = 0 + t_exec: float = 0. event = Event() max_count = 5 @@ -198,13 +199,13 @@ async def pow(*args: float, power: float = 2) -> List[float]: async def test_leeway_cancel(loop, leeway): - t_exec = 0 + t_exec: float = 0. delay_exec = 0.1 event = Event() executions = 0 arg = ContextVar("arg") - tasks = [] - executing_task = None + tasks: List[asyncio.Task] = [] + executing_task: asyncio.Task @aggregate(leeway * 1000) async def pow(*args: float, power: float = 2) -> List[float]: @@ -232,7 +233,7 @@ async def pho(num: int): elapsed = t_exec - t assert leeway * 0.9 < elapsed < leeway * 2 assert executions == 1 - first_executing_task = executing_task + first_executing_task: asyncio.Task = executing_task first_executing_task.cancel() # Another task must have tried to execute @@ -255,15 +256,15 @@ async def pho(num: int): async def test_max_count_cancel(loop): - t_exec = 0 + t_exec: float = 0. delay_exec = 0.1 event = Event() executions = 0 leeway = 100 max_count = 5 arg = ContextVar("arg") - tasks = [] - executing_task = None + tasks: List[asyncio.Task] = [] + executing_task: asyncio.Task @aggregate(leeway * 1000, max_count) async def pow(*args: float, power: float = 2) -> List[float]: @@ -321,8 +322,8 @@ async def test_max_count_multiple_batches_cancel(loop, leeway): executions = 0 max_count = 5 arg = ContextVar("arg") - tasks = [] - executing_task = None + tasks: List[asyncio.Task] = [] + executing_task: asyncio.Task @aggregate(leeway * 1000, max_count) async def pow(*args: float, power: float = 2) -> List[float]: diff --git a/tests/test_circuit_breaker.py b/tests/test_circuit_breaker.py index 80af291e..7df10dc1 100644 --- a/tests/test_circuit_breaker.py +++ b/tests/test_circuit_breaker.py @@ -1,5 +1,6 @@ import asyncio from collections import Counter +from typing import MutableMapping, Type, Union import pytest @@ -26,7 +27,7 @@ class PatchedCircuitBreaker(aiomisc.CircuitBreaker): """ CircuitBreaker for young time travelers """ - _TIME = 0 + _TIME = 0. @classmethod def tick(cls, second=1.0): @@ -86,7 +87,7 @@ async def test_simple(loop): with pytest.raises(CircuitBroken): circuit_breaker.call(ctx) - responses = Counter() + responses: MutableMapping[Union[bool, Type[Exception]], int] = Counter() # Delay is zero assert circuit_breaker.get_state_delay() == 0 diff --git a/tests/test_io.py b/tests/test_io.py index f20a6087..e74ee138 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -3,10 +3,12 @@ import uuid from pathlib import Path from tempfile import NamedTemporaryFile +from typing import List import pytest import aiomisc +from aiomisc.io import AsyncTextFileIO from tests import unix_only @@ -69,6 +71,7 @@ async def test_ordering(loop, tmp_path): async def test_async_for(loop, tmp_path): tdir = Path(tmp_path) + afp: AsyncTextFileIO async with aiomisc.io.async_open(tdir / "path", "w", loop=loop) as afp: await afp.write("foo\nbar\nbaz\n") @@ -81,8 +84,8 @@ async def test_async_for(loop, tmp_path): assert expected + result: List[str] = [] async with aiomisc.io.async_open(tdir / "path", "r", loop=loop) as afp: - result = [] async for line in afp: result.append(line) diff --git a/tests/test_pool.py b/tests/test_pool.py index a6789a29..a1091e42 100644 --- a/tests/test_pool.py +++ b/tests/test_pool.py @@ -10,11 +10,12 @@ async def test_base_class(loop: asyncio.AbstractEventLoop): with pytest.raises(TypeError): - aiomisc.PoolBase() + aiomisc.PoolBase() # type: ignore class SimplePool(aiomisc.PoolBase): - async def _create_instance(self): + async def _create_instance(self) -> asyncio.Future: + assert self._loop is not None return self._loop.create_future() async def _destroy_instance(self, instance): @@ -70,11 +71,11 @@ async def run(): await asyncio.sleep(2 * recycle) - async def run(): + async def run_blank(): async with pool.acquire(): pass - await asyncio.gather(*[run() for _ in range(size)]) + await asyncio.gather(*[run_blank() for _ in range(size)]) await asyncio.gather(*futures) await pool.close() diff --git a/tests/test_process_pool.py b/tests/test_process_pool.py index 99104c15..8af76c00 100644 --- a/tests/test_process_pool.py +++ b/tests/test_process_pool.py @@ -28,7 +28,7 @@ async def test_simple(pool, loop, timer): asyncio.gather( *[ loop.run_in_executor(pool, sleep, 1) for _ in range(4) - ] + ], ), timeout=2, ) @@ -49,6 +49,6 @@ async def test_exit(pool, loop): with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( - *[loop.run_in_executor(pool, suicide) for _ in range(4)] + *[loop.run_in_executor(pool, suicide) for _ in range(4)], ), timeout=2, ) diff --git a/tests/test_process_service.py b/tests/test_process_service.py index 29d3f878..0f61ebff 100644 --- a/tests/test_process_service.py +++ b/tests/test_process_service.py @@ -19,7 +19,7 @@ def test_abstractmethod_exception(): with pytest.raises(TypeError): - ProcessService() + ProcessService() # type: ignore class SampleProcessService(ProcessService): @@ -56,7 +56,7 @@ def in_process(self) -> Any: def test_respawning_process_service(tmpdir): - queue = Queue() + queue: Queue = Queue() svc = SimpleRespawningProcessService( queue=queue, process_poll_timeout=0.5, diff --git a/tests/test_profiler.py b/tests/test_profiler.py index cacd70dc..2f1c3b76 100644 --- a/tests/test_profiler.py +++ b/tests/test_profiler.py @@ -38,14 +38,14 @@ async def test_profiler_dump(): stats2 = Stats(path) # Getting the same dump - assert stats1.stats == stats2.stats + assert stats1.get_stats_profile() == stats2.get_stats_profile() # Enough sleep till next update await asyncio.sleep(0.2) stats3 = Stats(path) # Getting updated dump - assert stats2.stats != stats3.stats + assert stats2.get_stats_profile() != stats3.get_stats_profile() finally: if profiler: diff --git a/tests/test_raven_service.py b/tests/test_raven_service.py index da99bc82..c8023d90 100644 --- a/tests/test_raven_service.py +++ b/tests/test_raven_service.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from aiohttp import web from yarl import URL @@ -12,15 +14,14 @@ class REST(AIOHTTPService): - async def handle(request): + @staticmethod + async def handle(request: web.Request) -> Any: raise ValueError("Some error in handle handler") async def create_application(self): app = web.Application() - app.add_routes([ - web.get("/exc", self.handle), - web.get("/project-test", self.handle), - ]) + app.router.add_route("GET", "/exc", self.handle) + app.router.add_route("GET", "/project-test", self.handle) return app diff --git a/tests/test_recurring.py b/tests/test_recurring.py index 1a502b96..21a84ee6 100644 --- a/tests/test_recurring.py +++ b/tests/test_recurring.py @@ -20,7 +20,7 @@ async def task(): condition.notify_all() recurring = aiomisc.RecurringCallback(task) - task = recurring.start(strategy=lambda _: 0, loop=loop) + start_task = recurring.start(strategy=lambda _: 0, loop=loop) async with condition: await asyncio.wait_for( @@ -28,7 +28,7 @@ async def task(): timeout=5, ) - await aiomisc.cancel_tasks([task]) + await aiomisc.cancel_tasks([start_task]) async def test_long_func(loop): @@ -43,10 +43,10 @@ async def task(): condition.notify_all() recurring = aiomisc.RecurringCallback(task) - task = recurring.start(strategy=lambda _: 0, loop=loop) + start_task = recurring.start(strategy=lambda _: 0, loop=loop) await asyncio.sleep(1.2) - await aiomisc.cancel_tasks([task]) + await aiomisc.cancel_tasks([start_task]) async with condition: await asyncio.wait_for( @@ -71,10 +71,10 @@ async def task(): stop_event.set() recurring = aiomisc.RecurringCallback(task) - task = recurring.start(strategy=lambda _: 0, loop=loop, shield=True) + start_task = recurring.start(strategy=lambda _: 0, loop=loop, shield=True) await start_event.wait() - await aiomisc.cancel_tasks([task]) + await aiomisc.cancel_tasks([start_task]) await stop_event.wait() assert counter == 1 @@ -121,11 +121,11 @@ async def strategy(_: aiomisc.RecurringCallback): return 0 recurring = aiomisc.RecurringCallback(task) - task = recurring.start(strategy=strategy, loop=loop) + start_task = recurring.start(strategy=strategy, loop=loop) await start_event.wait() await stop_event.wait() - await task + await start_task assert counter == 3 assert strategy_counter == 5 @@ -146,8 +146,8 @@ async def strategy(_: aiomisc.RecurringCallback): return None recurring = aiomisc.RecurringCallback(task) - task = recurring.start(strategy=strategy, loop=loop) + start_task = recurring.start(strategy=strategy, loop=loop) - await task + await start_task assert strategy_counter == 1 assert counter == 0 diff --git a/tests/test_sdwatchdog_service.py b/tests/test_sdwatchdog_service.py index c347a575..22ace275 100644 --- a/tests/test_sdwatchdog_service.py +++ b/tests/test_sdwatchdog_service.py @@ -5,6 +5,7 @@ from collections import Counter, defaultdict, deque from pathlib import Path from tempfile import TemporaryDirectory +from typing import Any, Deque, MutableMapping, Tuple import pytest @@ -24,11 +25,16 @@ def test_sdwatchdog_service(loop): tmp_path = Path(tmp_dir) sock_path = str(tmp_path / "notify.sock") - packets = deque() + packets: Deque[Tuple[Any, ...]] = deque() class FakeSystemd(UDPServer): - def handle_datagram(self, data: bytes, addr: tuple) -> None: - packets.append((data.decode().split("=", 1), addr)) + def handle_datagram( + self, data: bytes, addr: Tuple[Any, ...], + ) -> None: + key: str + value: str + key, value = data.decode().split("=", 1) + packets.append(((key, value), addr)) with bind_socket( socket.AF_UNIX, socket.SOCK_DGRAM, address=sock_path, @@ -52,7 +58,7 @@ def handle_datagram(self, data: bytes, addr: tuple) -> None: os.environ.pop(key) assert packets - messages_count = Counter() + messages_count: MutableMapping[str, int] = Counter() messages = defaultdict(set) for (key, value), sender in packets: diff --git a/tests/test_signal.py b/tests/test_signal.py index 642391ea..cbc31838 100644 --- a/tests/test_signal.py +++ b/tests/test_signal.py @@ -136,7 +136,8 @@ async def foo(*args, **kwargs): async def multiple_receivers(signal): - foo_called, bar_called = False, False + foo_called = False + bar_called = False @receiver(signal) async def foo(): @@ -150,4 +151,4 @@ async def bar(): await signal.call() - assert all(foo_called, bar_called) + assert all((foo_called, bar_called)) diff --git a/tests/test_thread_pool.py b/tests/test_thread_pool.py index 8b7dfdc1..d725af39 100644 --- a/tests/test_thread_pool.py +++ b/tests/test_thread_pool.py @@ -16,7 +16,7 @@ try: import contextvars except ImportError: - contextvars = None + contextvars = None # type: ignore pytestmark = pytest.mark.catch_loop_exceptions @@ -249,7 +249,7 @@ def arange(*args): result = [] agen = arange(count) - async for item in agen: + async for item in agen: # type: ignore result.append(item) assert result == list(range(count)) @@ -407,7 +407,7 @@ def errored(val): @pytest.mark.skipif(contextvars is None, reason="no contextvars support") async def test_context_vars(threaded_decorator, loop): - ctx_var = contextvars.ContextVar("test") + ctx_var = contextvars.ContextVar("test") # type: ignore @threaded_decorator def test(arg): diff --git a/tests/test_utils.py b/tests/test_utils.py index a58b60e7..e3f67d0a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -5,6 +5,7 @@ import time import uuid from random import shuffle +from typing import List, Optional, Sequence import pytest @@ -31,7 +32,7 @@ async def test_select(loop: asyncio.AbstractEventLoop): async def test_select_cancelling(loop: asyncio.AbstractEventLoop): - results = [] + results: List[Optional[bool]] = [] async def good_coro(wait): nonlocal results @@ -130,7 +131,9 @@ async def main(loop): def test_chunk_list(): - data = tuple(map(tuple, aiomisc.chunk_list(range(10), 3))) + data: Sequence[Sequence[int]] = tuple( + map(tuple, aiomisc.chunk_list(range(10), 3)), + ) assert data == ((0, 1, 2), (3, 4, 5), (6, 7, 8), (9,)) diff --git a/tests/test_worker_pool.py b/tests/test_worker_pool.py index b6980ccb..f4ccadfb 100644 --- a/tests/test_worker_pool.py +++ b/tests/test_worker_pool.py @@ -6,6 +6,7 @@ from multiprocessing.context import ProcessError from os import getpid from time import sleep +from typing import Any, AsyncGenerator import pytest from setproctitle import setproctitle @@ -19,7 +20,9 @@ @pytest.fixture -async def worker_pool(request, loop) -> WorkerPool: +async def worker_pool( + request: pytest.FixtureRequest, loop: asyncio.AbstractEventLoop, +) -> AsyncGenerator[WorkerPool, None]: async with WorkerPool( PROCESS_NUM, initializer=setproctitle, @@ -35,7 +38,7 @@ async def test_success(worker_pool): *[ worker_pool.create_task(operator.mul, i, i) for i in range(worker_pool.workers * 2) - ] + ], ) results = sorted(results) @@ -50,7 +53,7 @@ async def test_incomplete_task_kill(worker_pool): *[ worker_pool.create_task(getpid) for _ in range(worker_pool.workers * 4) - ] + ], ) with pytest.raises(asyncio.TimeoutError): @@ -59,7 +62,7 @@ async def test_incomplete_task_kill(worker_pool): *[ worker_pool.create_task(sleep, 600) for _ in range(worker_pool.workers) - ] + ], ), timeout=1, ) @@ -67,7 +70,7 @@ async def test_incomplete_task_kill(worker_pool): *[ worker_pool.create_task(getpid) for _ in range(worker_pool.workers * 4) - ] + ], ) @@ -94,7 +97,7 @@ def get_stats() -> dict: *[ worker_pool.create_task(getpid) for _ in range(worker_pool.workers * 4) - ] + ], ) with pytest.raises(asyncio.TimeoutError): @@ -103,7 +106,7 @@ def get_stats() -> dict: *[ worker_pool.create_task(sleep, 600) for _ in range(worker_pool.workers) - ] + ], ), timeout=1, ) @@ -111,7 +114,7 @@ def get_stats() -> dict: *[ worker_pool.create_task(getpid) for _ in range(worker_pool.workers * 4) - ] + ], ) pids_end = set(worker_pool.pids) @@ -125,7 +128,7 @@ async def test_exceptions(worker_pool): *[ worker_pool.create_task(operator.truediv, i, 0) for i in range(worker_pool.workers * 2) - ], return_exceptions=True + ], return_exceptions=True, ) assert len(results) == worker_pool.workers * 2 @@ -142,7 +145,7 @@ async def test_exit(worker_pool): worker_pool.create_task(exit, 1) for _ in range(worker_pool.workers) ], - return_exceptions=True + return_exceptions=True, ), timeout=5, ) @@ -158,7 +161,7 @@ async def test_exit_respawn(worker_pool): worker_pool.create_task(exit, 1) for _ in range(worker_pool.workers * 3) ], - return_exceptions=True + return_exceptions=True, ) assert len(exceptions) == worker_pool.workers * 3 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index b3723373..00000000 --- a/tox.ini +++ /dev/null @@ -1,19 +0,0 @@ -[tox] -envlist = rpc,rpc_udp -isolated_build = True - -[testenv] -basepython=python3.10 - -deps = - msgspec~=0.9.1 - uvloop~=0.17.0 - -commands= - pytest -v --doctest-modules tests.py - -[testenv:rpc] -changedir=examples/rpc - -[testenv:rpc_udp] -changedir=examples/rpc_udp From 82f3cde4992c1dc8da65a414aa109d6038ffe6eb Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Mon, 19 Dec 2022 19:33:38 +0300 Subject: [PATCH 15/45] mypy fixes in tests --- aiomisc/io.py | 2 +- aiomisc/service/asgi.py | 18 ++++++++- aiomisc/service/base.py | 3 ++ aiomisc/service/udp.py | 2 +- poetry.lock | 8 ++-- pyproject.toml | 2 +- tests/test_cron_service.py | 4 +- tests/test_entrypoint.py | 64 ++++++++++++++++---------------- tests/test_sdwatchdog_service.py | 2 +- 9 files changed, 63 insertions(+), 42 deletions(-) diff --git a/aiomisc/io.py b/aiomisc/io.py index 68d60fd2..96261799 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -60,7 +60,7 @@ async def method(self, *args, **kwargs): # type: ignore @total_ordering class AsyncFileIO(EventLoopMixin, Generic[T]): __slots__ = ( - "__opener", "fp", "executor", "__iterator_lock", + "__opener", "_fp", "executor", "__iterator_lock", ) + EventLoopMixin.__slots__ opener = staticmethod(threaded(open)) diff --git a/aiomisc/service/asgi.py b/aiomisc/service/asgi.py index fac890e0..e5445fbf 100644 --- a/aiomisc/service/asgi.py +++ b/aiomisc/service/asgi.py @@ -1,8 +1,12 @@ from abc import abstractmethod +from typing import Any, Protocol, Union from aiohttp.web import Application from aiohttp_asgi import ASGIResource -from aiohttp_asgi.resource import ASGIApplicationType +from aiohttp_asgi.resource import ( + ASGIApplicationType, ASGIContext, ASGIMatchInfo, ASGIReceiveType, + ASGIScopeType, ASGISendType, +) from .aiohttp import AIOHTTPService, AIOHTTPSSLService @@ -40,3 +44,15 @@ async def create_asgi_app(self) -> ASGIApplicationType: async def create_application(self) -> Application: return _create_app(await self.create_asgi_app()) + + +__all__ = ( + "ASGIApplicationType", + "ASGIContext", + "ASGIHTTPService", + "ASGIMatchInfo", + "ASGIReceiveType", + "ASGIResource", + "ASGIScopeType", + "ASGISendType", +) diff --git a/aiomisc/service/base.py b/aiomisc/service/base.py index 91e72e9b..2d5bdcc3 100644 --- a/aiomisc/service/base.py +++ b/aiomisc/service/base.py @@ -55,6 +55,9 @@ def __init__(self, **kwargs: Any): self.__context: Optional[Context] = None self.__start_event: Optional[asyncio.Event] = None + def __getattr__(self, item: str) -> Any: + return self.__instance_params[item] + @property def start_event(self) -> asyncio.Event: if self.__start_event is None: diff --git a/aiomisc/service/udp.py b/aiomisc/service/udp.py index c19cc6c3..ad64a0c7 100644 --- a/aiomisc/service/udp.py +++ b/aiomisc/service/udp.py @@ -71,7 +71,7 @@ def sendto(self, data: bytes, addr: tuple) -> Any: return self._transport.sendto(data, addr) @abstractmethod - def handle_datagram(self, data: bytes, addr: tuple) -> None: + async def handle_datagram(self, data: bytes, addr: tuple) -> None: raise NotImplementedError async def start(self) -> None: diff --git a/poetry.lock b/poetry.lock index 404d7509..cdaa4c04 100644 --- a/poetry.lock +++ b/poetry.lock @@ -30,7 +30,7 @@ speedups = ["Brotli", "aiodns", "cchardet"] [[package]] name = "aiohttp-asgi" -version = "0.4.0" +version = "0.4.1" description = "Adapter to running ASGI applications on aiohttp" category = "dev" optional = false @@ -1135,7 +1135,7 @@ uvloop = [] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "f4e5a531dfe77edef88dde12dac5a042fd2b537b5fc6fb6dad1be4e784d804b4" +content-hash = "fedbdb2344cc68ba08badc5114d5ebb266bfb0c198c65e68f04419f6cdbdb3de" [metadata.files] aiocontextvars = [ @@ -1232,8 +1232,8 @@ aiohttp = [ {file = "aiohttp-3.8.3.tar.gz", hash = "sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269"}, ] aiohttp-asgi = [ - {file = "aiohttp-asgi-0.4.0.tar.gz", hash = "sha256:0ee1bfb7fc844f307fd0b6d28d6929772809d99c16cb74260d5f4b6b6db306e2"}, - {file = "aiohttp_asgi-0.4.0-py3-none-any.whl", hash = "sha256:e0637e8cf02c42db117bae2bdc75e15db43c270ed3f3bf4e0e261e4e4ed50642"}, + {file = "aiohttp-asgi-0.4.1.tar.gz", hash = "sha256:954a324c1f8e1028e22fea493521899c0078b9daa88a9a60708acb291c28302d"}, + {file = "aiohttp_asgi-0.4.1-py3-none-any.whl", hash = "sha256:3d5a519a3b9e18d4f0089b9572de70a841f91690b6e66351d27b87082ff7ba40"}, ] aiosignal = [ {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, diff --git a/pyproject.toml b/pyproject.toml index 9f99c225..08e5f848 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,7 +75,7 @@ aiomisc = "aiomisc_pytest.pytest_plugin" [tool.poetry.extras] aiohttp = ["aiohttp"] -asgi = ["aiohttp-asgi"] +asgi = ["aiohttp-asgi~=0.4.2"] carbon = ["aiocarbon~=0.15"] raven = ["aiohttp', 'raven"] uvloop = ["uvloop>=0.14,<1"] diff --git a/tests/test_cron_service.py b/tests/test_cron_service.py index b6ad8c82..7f136054 100644 --- a/tests/test_cron_service.py +++ b/tests/test_cron_service.py @@ -11,7 +11,7 @@ def test_cron(): counter = 0 - condition = None + condition: asyncio.Condition async def callback(): nonlocal counter @@ -57,7 +57,7 @@ async def assert_counter(): def test_register(): counter = 0 - condition = None + condition: asyncio.Condition async def callback(): nonlocal counter diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py index a0270ac0..efef48c7 100644 --- a/tests/test_entrypoint.py +++ b/tests/test_entrypoint.py @@ -5,7 +5,7 @@ from asyncio.tasks import Task from contextlib import ExitStack, suppress from tempfile import mktemp -from typing import Any +from typing import Any, Callable, Coroutine, Optional, Tuple, Union import aiohttp.web import fastapi @@ -16,7 +16,10 @@ from aiomisc.entrypoint import Entrypoint from aiomisc.service import TCPServer, TLSServer, UDPServer from aiomisc.service.aiohttp import AIOHTTPService -from aiomisc.service.asgi import ASGIApplicationType, ASGIHTTPService +from aiomisc.service.asgi import ( + ASGIApplicationType, ASGIHTTPService, ASGIReceiveType, ASGIScopeType, + ASGISendType, +) from aiomisc.service.tcp import RobustTCPClient, TCPClient from aiomisc.service.tls import RobustTLSClient, TLSClient from tests import unix_only @@ -26,7 +29,7 @@ import uvloop uvloop_loop_type = uvloop.Loop except ImportError: - uvloop_loop_type = None + uvloop_loop_type = None # type: ignore pytestmark = pytest.mark.catch_loop_exceptions @@ -75,12 +78,8 @@ def unix_socket_tcp(): def test_service_class(): with pytest.raises(TypeError): - services = ( - aiomisc.Service(running=False, stopped=False), - aiomisc.Service(running=False, stopped=False), - ) - - with aiomisc.entrypoint(*services): + service = aiomisc.Service(running=False, stopped=False) # type: ignore + with aiomisc.entrypoint(service): pass @@ -90,31 +89,34 @@ async def start(self): self.running = True class DummyService(StartingService): - async def stop(self, err: Exception = None): + async def stop(self, err: Optional[Exception] = None): self.stopped = True - services = ( + services: Tuple[StartingService, ...] + dummy_services: Tuple[DummyService, ...] + + dummy_services = ( DummyService(running=False, stopped=False), DummyService(running=False, stopped=False), ) - with aiomisc.entrypoint(*services): + with aiomisc.entrypoint(*dummy_services): pass - for svc in services: + for svc in dummy_services: assert svc.running assert svc.stopped - services = ( + dummy_services = ( DummyService(running=False, stopped=False), DummyService(running=False, stopped=False), ) with pytest.raises(RuntimeError): - with aiomisc.entrypoint(*services): + with aiomisc.entrypoint(*dummy_services): raise RuntimeError - for svc in services: + for svc in dummy_services: assert svc.running assert svc.stopped @@ -127,13 +129,13 @@ async def stop(self, err: Exception = None): with aiomisc.entrypoint(*services): raise RuntimeError - for svc in services: - assert svc.running + for starting_svc in services: + assert starting_svc.running -def test_wrong_sublclass(): +def test_wrong_subclass(): with pytest.raises(TypeError): - class _(aiomisc.Service): + class NoAsyncStartService(aiomisc.Service): def start(self): return True @@ -142,11 +144,11 @@ async def start(self): return with pytest.raises(TypeError): - class _(MyService): + class NoAsyncStopServiceSubclass(MyService): def stop(self): return True - class _(MyService): + class AsyncStopServiceSubclass(MyService): async def stop(self): return True @@ -343,7 +345,7 @@ async def handle_client( writer.close() class TestClient(TLSClient): - event: asyncio.Event() + event: asyncio.Event async def handle_connection( self, reader: asyncio.StreamReader, @@ -447,7 +449,7 @@ def test_udp_server(aiomisc_socket_factory): class TestService(UDPServer): DATA = [] - async def handle_datagram(self, data: bytes, addr: tuple): + async def handle_datagram(self, data: bytes, addr: tuple) -> None: self.DATA.append(data) service = TestService("127.0.0.1", sock=sock) @@ -551,11 +553,11 @@ def writer(): def test_aiohttp_service_create_app(): with pytest.raises(TypeError): - class _(AIOHTTPService): + class NoAsyncCreateApplication(AIOHTTPService): def create_application(self): return None - class _(AIOHTTPService): + class AsyncCreateApplication(AIOHTTPService): async def create_application(self): return aiohttp.web.Application() @@ -606,11 +608,11 @@ async def http_client(): def test_asgi_service_create_app(): with pytest.raises(TypeError): - class _(ASGIHTTPService): - def create_asgi_app(self) -> ASGIApplicationType: - return lambda: None + class NoAsyncCreateASGIApp(ASGIHTTPService): + def create_asgi_app(self) -> ASGIApplicationType: # type: ignore + return lambda: None # type: ignore - class _(ASGIHTTPService): + class AsyncCreateASGIApp(ASGIHTTPService): async def create_asgi_app(self) -> ASGIApplicationType: return fastapi.FastAPI() @@ -786,7 +788,7 @@ class MyService(aiomisc.service.Service): async def start(self): self.__class__.ctx = 1 - async def stop(self, exc: Exception = None): + async def stop(self, exc: Optional[Exception] = None) -> None: self.__class__.ctx = 2 service = MyService() diff --git a/tests/test_sdwatchdog_service.py b/tests/test_sdwatchdog_service.py index 22ace275..65ded4a5 100644 --- a/tests/test_sdwatchdog_service.py +++ b/tests/test_sdwatchdog_service.py @@ -28,7 +28,7 @@ def test_sdwatchdog_service(loop): packets: Deque[Tuple[Any, ...]] = deque() class FakeSystemd(UDPServer): - def handle_datagram( + async def handle_datagram( self, data: bytes, addr: Tuple[Any, ...], ) -> None: key: str From 1013e221761b8e90cfe4b30a4c0cbb15b07992d6 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Mon, 19 Dec 2022 19:52:56 +0300 Subject: [PATCH 16/45] fixes --- aiomisc/io.py | 26 ++++++++++++++------------ aiomisc/service/base.py | 5 ++++- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/aiomisc/io.py b/aiomisc/io.py index 96261799..43565a52 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -60,10 +60,9 @@ async def method(self, *args, **kwargs): # type: ignore @total_ordering class AsyncFileIO(EventLoopMixin, Generic[T]): __slots__ = ( - "__opener", "_fp", "executor", "__iterator_lock", + "_fp", "executor", "__iterator_lock", ) + EventLoopMixin.__slots__ - opener = staticmethod(threaded(open)) _fp: Optional[Union[IO, BinaryIO, TextIO]] def __init__( @@ -74,7 +73,7 @@ def __init__( self.executor = executor self._loop = loop self._fp = None - self.__opener = partial(self.opener, fname, mode, *args, **kwargs) + self.__open_args = (fname, mode, *args), kwargs self.__iterator_lock = asyncio.Lock() @classmethod @@ -86,6 +85,13 @@ def open_fp( async_fp._fp = fp return async_fp + async def open(self) -> None: + if self._fp is not None: + return + + args, kwargs = self.__open_args + self._fp = await self.__execute_in_thread(open, *args, **kwargs) + @property def fp(self) -> Union[IO, BinaryIO, TextIO]: if self._fp is not None: @@ -95,11 +101,6 @@ def fp(self) -> Union[IO, BinaryIO, TextIO]: def closed(self) -> bool: return self.fp.closed - async def open(self) -> None: - if self._fp is not None: - return - self._fp = await self.__opener() - def __await__(self) -> Generator[Any, Any, "AsyncFileIO"]: yield from self.open().__await__() return self @@ -173,11 +174,12 @@ def isatty(self) -> bool: async def close(self) -> None: return await self.__execute_in_thread(self.fp.close) - def __getattribute__(self, name: str) -> Callable[..., Awaitable[Any]]: + def __getattr__(self, name: str) -> Callable[..., Awaitable[Any]]: async def method(*args: Any) -> Any: - return await self.__execute_in_thread( - getattr(self.fp, name), *args, - ) + getter = getattr(self.fp, name) + if callable(getter): + return await self.__execute_in_thread(getter, *args) + return getter method.__name__ = name return method diff --git a/aiomisc/service/base.py b/aiomisc/service/base.py index 2d5bdcc3..4aff6834 100644 --- a/aiomisc/service/base.py +++ b/aiomisc/service/base.py @@ -56,7 +56,10 @@ def __init__(self, **kwargs: Any): self.__start_event: Optional[asyncio.Event] = None def __getattr__(self, item: str) -> Any: - return self.__instance_params[item] + try: + return self.__instance_params[item] + except KeyError as e: + raise AttributeError from e @property def start_event(self) -> asyncio.Event: From 0de5a27d0ac7486c6c4391eaf2ff57179adf627b Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Mon, 19 Dec 2022 19:56:43 +0300 Subject: [PATCH 17/45] test syncronization --- tests/test_entrypoint.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py index efef48c7..beaaa2cd 100644 --- a/tests/test_entrypoint.py +++ b/tests/test_entrypoint.py @@ -446,11 +446,14 @@ async def go(): def test_udp_server(aiomisc_socket_factory): port, sock = aiomisc_socket_factory(socket.AF_INET, socket.SOCK_DGRAM) + event = asyncio.Event() + class TestService(UDPServer): DATA = [] async def handle_datagram(self, data: bytes, addr: tuple) -> None: self.DATA.append(data) + event.set() service = TestService("127.0.0.1", sock=sock) @@ -465,6 +468,7 @@ def writer(): loop.run_until_complete( asyncio.wait_for(writer(), timeout=10), ) + loop.run_until_complete(event.wait()) assert TestService.DATA assert TestService.DATA == [b"hello server\n"] From 654d96714c76459d60e4fd5890eb8844b8b13557 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Mon, 19 Dec 2022 19:58:13 +0300 Subject: [PATCH 18/45] upgrade packages --- poetry.lock | 364 +++++++++++++++++++++++++------------------------ pyproject.toml | 4 +- 2 files changed, 190 insertions(+), 178 deletions(-) diff --git a/poetry.lock b/poetry.lock index cdaa4c04..13d3aa98 100644 --- a/poetry.lock +++ b/poetry.lock @@ -30,7 +30,7 @@ speedups = ["Brotli", "aiodns", "cchardet"] [[package]] name = "aiohttp-asgi" -version = "0.4.1" +version = "0.4.3" description = "Adapter to running ASGI applications on aiohttp" category = "dev" optional = false @@ -136,7 +136,7 @@ pytz = ">=2015.7" [[package]] name = "certifi" -version = "2022.9.24" +version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false @@ -313,15 +313,15 @@ test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==22.10.0)", "coverage[toml] (>= [[package]] name = "filelock" -version = "3.8.0" +version = "3.8.2" description = "A platform independent file lock." category = "dev" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"] -testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2022.9.29)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] +testing = ["covdefaults (>=2.2.2)", "coverage (>=6.5)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] [[package]] name = "freezegun" @@ -344,7 +344,7 @@ python-versions = ">=3.7" [[package]] name = "identify" -version = "2.5.9" +version = "2.5.10" description = "File identification library for Python" category = "dev" optional = false @@ -371,7 +371,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "5.1.0" +version = "5.2.0" description = "Read metadata from Python packages" category = "dev" optional = false @@ -382,7 +382,7 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] @@ -446,7 +446,7 @@ python-versions = ">=3.6" [[package]] name = "multidict" -version = "6.0.2" +version = "6.0.3" description = "multidict implementation" category = "dev" optional = false @@ -493,18 +493,15 @@ setuptools = "*" [[package]] name = "packaging" -version = "21.3" +version = "22.0" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +python-versions = ">=3.7" [[package]] name = "platformdirs" -version = "2.5.4" +version = "2.6.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false @@ -634,17 +631,6 @@ tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "p toml = ["toml (>=0.10.2)"] vulture = ["vulture"] -[[package]] -name = "pyparsing" -version = "3.0.9" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" -optional = false -python-versions = ">=3.6.8" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pytest" version = "7.2.0" @@ -731,7 +717,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2022.6" +version = "2022.7" description = "World timezone definitions, modern and historical" category = "dev" optional = false @@ -1033,7 +1019,7 @@ python-versions = ">=3.6" [[package]] name = "types-croniter" -version = "1.3.2" +version = "1.3.2.1" description = "Typing stubs for croniter" category = "dev" optional = false @@ -1041,7 +1027,7 @@ python-versions = "*" [[package]] name = "types-setuptools" -version = "65.6.0.1" +version = "65.6.0.2" description = "Typing stubs for setuptools" category = "dev" optional = false @@ -1083,7 +1069,7 @@ test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "my [[package]] name = "virtualenv" -version = "20.17.0" +version = "20.17.1" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -1101,7 +1087,7 @@ testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7 [[package]] name = "yarl" -version = "1.8.1" +version = "1.8.2" description = "Yet another URL library" category = "dev" optional = false @@ -1135,7 +1121,7 @@ uvloop = [] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "fedbdb2344cc68ba08badc5114d5ebb266bfb0c198c65e68f04419f6cdbdb3de" +content-hash = "e7d96179f1acc89c2737b91f845f0f348c4a9db025054e7e77a6f23ab83d3761" [metadata.files] aiocontextvars = [ @@ -1232,8 +1218,8 @@ aiohttp = [ {file = "aiohttp-3.8.3.tar.gz", hash = "sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269"}, ] aiohttp-asgi = [ - {file = "aiohttp-asgi-0.4.1.tar.gz", hash = "sha256:954a324c1f8e1028e22fea493521899c0078b9daa88a9a60708acb291c28302d"}, - {file = "aiohttp_asgi-0.4.1-py3-none-any.whl", hash = "sha256:3d5a519a3b9e18d4f0089b9572de70a841f91690b6e66351d27b87082ff7ba40"}, + {file = "aiohttp-asgi-0.4.3.tar.gz", hash = "sha256:2b211ed97ad174bdfcf2419465386e2af83ad4cf25bb06a463ad49e8e038e185"}, + {file = "aiohttp_asgi-0.4.3-py3-none-any.whl", hash = "sha256:1a77540f4758a6c8736797abd553e80e29a8cade6c864808d483e98e35a78724"}, ] aiosignal = [ {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, @@ -1267,8 +1253,8 @@ babel = [ {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, ] certifi = [ - {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, - {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, ] cfgv = [ {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, @@ -1377,8 +1363,8 @@ fastapi = [ {file = "fastapi-0.88.0.tar.gz", hash = "sha256:915bf304180a0e7c5605ec81097b7d4cd8826ff87a02bb198e336fb9f3b5ff02"}, ] filelock = [ - {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"}, - {file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"}, + {file = "filelock-3.8.2-py3-none-any.whl", hash = "sha256:8df285554452285f79c035efb0c861eb33a4bcfa5b7a137016e32e6a90f9792c"}, + {file = "filelock-3.8.2.tar.gz", hash = "sha256:7565f628ea56bfcd8e54e42bdc55da899c85c1abfe1b5bcfd147e9188cebb3b2"}, ] freezegun = [ {file = "freezegun-1.0.0-py2.py3-none-any.whl", hash = "sha256:02b35de52f4699a78f6ac4518e4cd3390dddc43b0aeb978335a8f270a2d9668b"}, @@ -1461,8 +1447,8 @@ frozenlist = [ {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, ] identify = [ - {file = "identify-2.5.9-py2.py3-none-any.whl", hash = "sha256:a390fb696e164dbddb047a0db26e57972ae52fbd037ae68797e5ae2f4492485d"}, - {file = "identify-2.5.9.tar.gz", hash = "sha256:906036344ca769539610436e40a684e170c3648b552194980bb7b617a8daeb9f"}, + {file = "identify-2.5.10-py2.py3-none-any.whl", hash = "sha256:fb7c2feaeca6976a3ffa31ec3236a6911fbc51aec9acc111de2aed99f244ade2"}, + {file = "identify-2.5.10.tar.gz", hash = "sha256:dce9e31fee7dbc45fea36a9e855c316b8fbf807e65a862f160840bb5a2bf5dfd"}, ] idna = [ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, @@ -1473,8 +1459,8 @@ imagesize = [ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] importlib-metadata = [ - {file = "importlib_metadata-5.1.0-py3-none-any.whl", hash = "sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313"}, - {file = "importlib_metadata-5.1.0.tar.gz", hash = "sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b"}, + {file = "importlib_metadata-5.2.0-py3-none-any.whl", hash = "sha256:0eafa39ba42bf225fc00e67f701d71f85aead9f878569caf13c3724f704b970f"}, + {file = "importlib_metadata-5.2.0.tar.gz", hash = "sha256:404d48d62bba0b7a77ff9d405efd91501bef2e67ff4ace0bed40a0cf28c3c7cd"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1538,65 +1524,80 @@ mccabe = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] multidict = [ - {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"}, - {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"}, - {file = "multidict-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389"}, - {file = "multidict-6.0.2-cp310-cp310-win32.whl", hash = "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293"}, - {file = "multidict-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658"}, - {file = "multidict-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15"}, - {file = "multidict-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc"}, - {file = "multidict-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a"}, - {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60"}, - {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86"}, - {file = "multidict-6.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d"}, - {file = "multidict-6.0.2-cp38-cp38-win32.whl", hash = "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57"}, - {file = "multidict-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96"}, - {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c"}, - {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e"}, - {file = "multidict-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937"}, - {file = "multidict-6.0.2-cp39-cp39-win32.whl", hash = "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a"}, - {file = "multidict-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae"}, - {file = "multidict-6.0.2.tar.gz", hash = "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013"}, + {file = "multidict-6.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:73009ea04205966d47e16d98686ac5c438af23a1bb30b48a2c5da3423ec9ce37"}, + {file = "multidict-6.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b92a9f3ab904397a33b193000dc4de7318ea175c4c460a1e154c415f9008e3d"}, + {file = "multidict-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:578bfcb16f4b8675ef71b960c00f174b0426e0eeb796bab6737389d8288eb827"}, + {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1650ea41c408755da5eed52ac6ccbc8938ccc3e698d81e6f6a1be02ff2a0945"}, + {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d52442e7c951e4c9ee591d6047706e66923d248d83958bbf99b8b19515fffaef"}, + {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad7d66422b9cc51125509229693d27e18c08f2dea3ac9de408d821932b1b3759"}, + {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cd14e61f0da2a2cfb9fe05bfced2a1ed7063ce46a7a8cd473be4973de9a7f91"}, + {file = "multidict-6.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:190626ced82d4cc567a09e7346340d380154a493bac6905e0095d8158cdf1e38"}, + {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:791458a1f7d1b4ab3bd9e93e0dcd1d59ef7ee9aa051dcd1ea030e62e49b923fd"}, + {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b46e79a9f4db53897d17bc64a39d1c7c2be3e3d4f8dba6d6730a2b13ddf0f986"}, + {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e4a095e18847c12ec20e55326ab8782d9c2d599400a3a2f174fab4796875d0e2"}, + {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fb6c3dc3d65014d2c782f5acf0b3ba14e639c6c33d3ed8932ead76b9080b3544"}, + {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3541882266247c7cd3dba78d6ef28dbe704774df60c9e4231edaa4493522e614"}, + {file = "multidict-6.0.3-cp310-cp310-win32.whl", hash = "sha256:67090b17a0a5be5704fd109f231ee73cefb1b3802d41288d6378b5df46ae89ba"}, + {file = "multidict-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:36df958b15639e40472adaa4f0c2c7828fe680f894a6b48c4ce229f59a6a798b"}, + {file = "multidict-6.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5b51969503709415a35754954c2763f536a70b8bf7360322b2edb0c0a44391f6"}, + {file = "multidict-6.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:24e8d513bfcaadc1f8b0ebece3ff50961951c54b07d5a775008a882966102418"}, + {file = "multidict-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d325d61cac602976a5d47b19eaa7d04e3daf4efce2164c630219885087234102"}, + {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbbe17f8a7211b623502d2bf41022a51da3025142401417c765bf9a56fed4c"}, + {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4fb3fe591956d8841882c463f934c9f7485cfd5f763a08c0d467b513dc18ef89"}, + {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1925f78a543b94c3d46274c66a366fee8a263747060220ed0188e5f3eeea1c0"}, + {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e1ce0b187c4e93112304dcde2aa18922fdbe8fb4f13d8aa72a5657bce0563a"}, + {file = "multidict-6.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e07c24018986fb00d6e7eafca8fcd6e05095649e17fcf0e33a592caaa62a78b9"}, + {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:114a4ab3e5cfbc56c4b6697686ecb92376c7e8c56893ef20547921552f8bdf57"}, + {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ccf55f28066b4f08666764a957c2b7c241c7547b0921d69c7ceab5f74fe1a45"}, + {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:9d359b0a962e052b713647ac1f13eabf2263167b149ed1e27d5c579f5c8c7d2c"}, + {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:df7b4cee3ff31b3335aba602f8d70dbc641e5b7164b1e9565570c9d3c536a438"}, + {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ee9b1cae9a6c5d023e5a150f6f6b9dbb3c3bbc7887d6ee07d4c0ecb49a473734"}, + {file = "multidict-6.0.3-cp311-cp311-win32.whl", hash = "sha256:960ce1b790952916e682093788696ef7e33ac6a97482f9b983abdc293091b531"}, + {file = "multidict-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:2b66d61966b12e6bba500e5cbb2c721a35e119c30ee02495c5629bd0e91eea30"}, + {file = "multidict-6.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:526f8397fc124674b8f39748680a0ff673bd6a715fecb4866716d36e380f015f"}, + {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f5d5129a937af4e3c4a1d6c139f4051b7d17d43276cefdd8d442a7031f7eef2"}, + {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38d394814b39be1c36ac709006d39d50d72a884f9551acd9c8cc1ffae3fc8c4e"}, + {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99341ca1f1db9e7f47914cb2461305665a662383765ced6f843712564766956d"}, + {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5790cc603456b6dcf8a9a4765f666895a6afddc88b3d3ba7b53dea2b6e23116"}, + {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce8e51774eb03844588d3c279adb94efcd0edeccd2f97516623292445bcc01f9"}, + {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:baa96a3418e27d723064854143b2f414a422c84cc87285a71558722049bebc5a"}, + {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:cb4a08f0aaaa869f189ffea0e17b86ad0237b51116d494da15ef7991ee6ad2d7"}, + {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:62db44727d0befea68e8ad2881bb87a9cfb6b87d45dd78609009627167f37b69"}, + {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:4cc5c8cd205a9810d16a5cd428cd81bac554ad1477cb87f4ad722b10992e794d"}, + {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f76109387e1ec8d8e2137c94c437b89fe002f29e0881aae8ae45529bdff92000"}, + {file = "multidict-6.0.3-cp37-cp37m-win32.whl", hash = "sha256:f8a728511c977df6f3d8af388fcb157e49f11db4a6637dd60131b8b6e40b0253"}, + {file = "multidict-6.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c2a1168e5aa7c72499fb03c850e0f03f624fa4a5c8d2e215c518d0a73872eb64"}, + {file = "multidict-6.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eddf604a3de2ace3d9a4e4d491be7562a1ac095a0a1c95a9ec5781ef0273ef11"}, + {file = "multidict-6.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d09daf5c6ce7fc6ed444c9339bbde5ea84e2534d1ca1cd37b60f365c77f00dea"}, + {file = "multidict-6.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:12e0d396faa6dc55ff5379eee54d1df3b508243ff15bfc8295a6ec7a4483a335"}, + {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70740c2bc9ab1c99f7cdcb104f27d16c63860c56d51c5bf0ef82fc1d892a2131"}, + {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e322c94596054352f5a02771eec71563c018b15699b961aba14d6dd943367022"}, + {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4159fc1ec9ede8ab93382e0d6ba9b1b3d23c72da39a834db7a116986605c7ab4"}, + {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47defc0218682281a52fb1f6346ebb8b68b17538163a89ea24dfe4da37a8a9a3"}, + {file = "multidict-6.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f9511e48bde6b995825e8d35e434fc96296cf07a25f4aae24ff9162be7eaa46"}, + {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e0bce9f7c30e7e3a9e683f670314c0144e8d34be6b7019e40604763bd278d84f"}, + {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:01b456046a05ff7cceefb0e1d2a9d32f05efcb1c7e0d152446304e11557639ce"}, + {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:8230a39bae6c2e8a09e4da6bace5064693b00590a4a213e38f9a9366da10e7dd"}, + {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:445c0851a1cbc1f2ec3b40bc22f9c4a235edb3c9a0906122a9df6ea8d51f886c"}, + {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9aac6881454a750554ed4b280a839dcf9e2133a9d12ab4d417d673fb102289b7"}, + {file = "multidict-6.0.3-cp38-cp38-win32.whl", hash = "sha256:81c3d597591b0940e04949e4e4f79359b2d2e542a686ba0da5e25de33fec13e0"}, + {file = "multidict-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:dc4cfef5d899f5f1a15f3d2ac49f71107a01a5a2745b4dd53fa0cede1419385a"}, + {file = "multidict-6.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d408172519049e36fb6d29672f060dc8461fc7174eba9883c7026041ef9bfb38"}, + {file = "multidict-6.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e068dfeadbce63072b2d8096486713d04db4946aad0a0f849bd4fc300799d0d3"}, + {file = "multidict-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8b817d4ed68fd568ec5e45dd75ddf30cc72a47a6b41b74d5bb211374c296f5e"}, + {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cf5d19e12eff855aa198259c0b02fd3f5d07e1291fbd20279c37b3b0e6c9852"}, + {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5a811aab1b4aea0b4be669363c19847a8c547510f0e18fb632956369fdbdf67"}, + {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2cfda34b7cb99eacada2072e0f69c0ad3285cb6f8e480b11f2b6d6c1c6f92718"}, + {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beeca903e4270b4afcd114f371a9602240dc143f9e944edfea00f8d4ad56c40d"}, + {file = "multidict-6.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd5771e8ea325f85cbb361ddbdeb9ae424a68e5dfb6eea786afdcd22e68a7d5d"}, + {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9dbab2a7e9c073bc9538824a01f5ed689194db7f55f2b8102766873e906a6c1a"}, + {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f2c0957b3e8c66c10d27272709a5299ab3670a0f187c9428f3b90d267119aedb"}, + {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:94cbe5535ef150546b8321aebea22862a3284da51e7b55f6f95b7d73e96d90ee"}, + {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d0e798b072cf2aab9daceb43d97c9c527a0c7593e67a7846ad4cc6051de1e303"}, + {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a27b029caa3b555a4f3da54bc1e718eb55fcf1a11fda8bf0132147b476cf4c08"}, + {file = "multidict-6.0.3-cp39-cp39-win32.whl", hash = "sha256:018c8e3be7f161a12b3e41741b6721f9baeb2210f4ab25a6359b7d76c1017dce"}, + {file = "multidict-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:5e58ec0375803526d395f6f7e730ecc45d06e15f68f7b9cdbf644a2918324e51"}, + {file = "multidict-6.0.3.tar.gz", hash = "sha256:2523a29006c034687eccd3ee70093a697129a3ffe8732535d3b2df6a4ecc279d"}, ] mypy = [ {file = "mypy-0.991-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7d17e0a9707d0772f4a7b878f04b4fd11f6f5bcb9b3813975a9b13c9332153ab"}, @@ -1639,12 +1640,12 @@ nodeenv = [ {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, ] packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, + {file = "packaging-22.0-py3-none-any.whl", hash = "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3"}, + {file = "packaging-22.0.tar.gz", hash = "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3"}, ] platformdirs = [ - {file = "platformdirs-2.5.4-py3-none-any.whl", hash = "sha256:af0276409f9a02373d540bf8480021a048711d572745aef4b7842dad245eba10"}, - {file = "platformdirs-2.5.4.tar.gz", hash = "sha256:1006647646d80f16130f052404c6b901e80ee4ed6bef6792e1f238a8969106f7"}, + {file = "platformdirs-2.6.0-py3-none-any.whl", hash = "sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca"}, + {file = "platformdirs-2.6.0.tar.gz", hash = "sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -1716,10 +1717,6 @@ pylama = [ {file = "pylama-8.4.1-py3-none-any.whl", hash = "sha256:5bbdbf5b620aba7206d688ed9fc917ecd3d73e15ec1a89647037a09fa3a86e60"}, {file = "pylama-8.4.1.tar.gz", hash = "sha256:2d4f7aecfb5b7466216d48610c7d6bad1c3990c29cdd392ad08259b161e486f6"}, ] -pyparsing = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] pytest = [ {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, @@ -1744,8 +1741,8 @@ python-dateutil = [ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] pytz = [ - {file = "pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, - {file = "pytz-2022.6.tar.gz", hash = "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2"}, + {file = "pytz-2022.7-py2.py3-none-any.whl", hash = "sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd"}, + {file = "pytz-2022.7.tar.gz", hash = "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a"}, ] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, @@ -1969,12 +1966,12 @@ typed-ast = [ {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] types-croniter = [ - {file = "types-croniter-1.3.2.tar.gz", hash = "sha256:e96e9c855247f294fb88cc1363a5eb93fd1df5943fe85dda29179285e00deabc"}, - {file = "types_croniter-1.3.2-py3-none-any.whl", hash = "sha256:f529295f94aff6da82222739bbcdeed7fe98de9fe38597f04071d2a1b980ee06"}, + {file = "types-croniter-1.3.2.1.tar.gz", hash = "sha256:1f0a14b9465471f460640de935e8e4a9b3fe90537ff1f287594e6e53f3ff6b86"}, + {file = "types_croniter-1.3.2.1-py3-none-any.whl", hash = "sha256:469e795a71f45fd2895af3accfccfbf337c9df364fcc23a8768417cbf1447339"}, ] types-setuptools = [ - {file = "types-setuptools-65.6.0.1.tar.gz", hash = "sha256:a03cf72f336929c9405f485dd90baef31a401776675f785f69a5a519f0b099ca"}, - {file = "types_setuptools-65.6.0.1-py3-none-any.whl", hash = "sha256:c957599502195ab98e90f0560466fa963f6a23373905e6d4e1772dbfaf1e44b7"}, + {file = "types-setuptools-65.6.0.2.tar.gz", hash = "sha256:ad60ccf01d626de9762224448f36c13e0660e863afd6dc11d979b3739a6c7d24"}, + {file = "types_setuptools-65.6.0.2-py3-none-any.whl", hash = "sha256:2c2b4f756f79778074ce2d21f745aa737b12160d9f8dfa274f47a7287c7a2fee"}, ] typing-extensions = [ {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, @@ -2017,69 +2014,84 @@ uvloop = [ {file = "uvloop-0.17.0.tar.gz", hash = "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1"}, ] virtualenv = [ - {file = "virtualenv-20.17.0-py3-none-any.whl", hash = "sha256:40a7e06a98728fd5769e1af6fd1a706005b4bb7e16176a272ed4292473180389"}, - {file = "virtualenv-20.17.0.tar.gz", hash = "sha256:7d6a8d55b2f73b617f684ee40fd85740f062e1f2e379412cb1879c7136f05902"}, + {file = "virtualenv-20.17.1-py3-none-any.whl", hash = "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4"}, + {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, ] yarl = [ - {file = "yarl-1.8.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28"}, - {file = "yarl-1.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3"}, - {file = "yarl-1.8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880"}, - {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40"}, - {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b"}, - {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497"}, - {file = "yarl-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a"}, - {file = "yarl-1.8.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f"}, - {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd"}, - {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957"}, - {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28"}, - {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843"}, - {file = "yarl-1.8.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453"}, - {file = "yarl-1.8.1-cp310-cp310-win32.whl", hash = "sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272"}, - {file = "yarl-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0"}, - {file = "yarl-1.8.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035"}, - {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc"}, - {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b"}, - {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231"}, - {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda"}, - {file = "yarl-1.8.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507"}, - {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee"}, - {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0"}, - {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d"}, - {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd"}, - {file = "yarl-1.8.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780"}, - {file = "yarl-1.8.1-cp37-cp37m-win32.whl", hash = "sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07"}, - {file = "yarl-1.8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802"}, - {file = "yarl-1.8.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a"}, - {file = "yarl-1.8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1"}, - {file = "yarl-1.8.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548"}, - {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461"}, - {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe"}, - {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae"}, - {file = "yarl-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc"}, - {file = "yarl-1.8.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae"}, - {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546"}, - {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead"}, - {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4"}, - {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e"}, - {file = "yarl-1.8.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae"}, - {file = "yarl-1.8.1-cp38-cp38-win32.whl", hash = "sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0"}, - {file = "yarl-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4"}, - {file = "yarl-1.8.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936"}, - {file = "yarl-1.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350"}, - {file = "yarl-1.8.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357"}, - {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b"}, - {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54"}, - {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb"}, - {file = "yarl-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c"}, - {file = "yarl-1.8.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6"}, - {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64"}, - {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae"}, - {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3"}, - {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0"}, - {file = "yarl-1.8.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e"}, - {file = "yarl-1.8.1-cp39-cp39-win32.whl", hash = "sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6"}, - {file = "yarl-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be"}, - {file = "yarl-1.8.1.tar.gz", hash = "sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf"}, + {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5"}, + {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:47d49ac96156f0928f002e2424299b2c91d9db73e08c4cd6742923a086f1c863"}, + {file = "yarl-1.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3fc056e35fa6fba63248d93ff6e672c096f95f7836938241ebc8260e062832fe"}, + {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58a3c13d1c3005dbbac5c9f0d3210b60220a65a999b1833aa46bd6677c69b08e"}, + {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10b08293cda921157f1e7c2790999d903b3fd28cd5c208cf8826b3b508026996"}, + {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de986979bbd87272fe557e0a8fcb66fd40ae2ddfe28a8b1ce4eae22681728fef"}, + {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c4fcfa71e2c6a3cb568cf81aadc12768b9995323186a10827beccf5fa23d4f8"}, + {file = "yarl-1.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae4d7ff1049f36accde9e1ef7301912a751e5bae0a9d142459646114c70ecba6"}, + {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bf071f797aec5b96abfc735ab97da9fd8f8768b43ce2abd85356a3127909d146"}, + {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:74dece2bfc60f0f70907c34b857ee98f2c6dd0f75185db133770cd67300d505f"}, + {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:df60a94d332158b444301c7f569659c926168e4d4aad2cfbf4bce0e8fb8be826"}, + {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:63243b21c6e28ec2375f932a10ce7eda65139b5b854c0f6b82ed945ba526bff3"}, + {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cfa2bbca929aa742b5084fd4663dd4b87c191c844326fcb21c3afd2d11497f80"}, + {file = "yarl-1.8.2-cp310-cp310-win32.whl", hash = "sha256:b05df9ea7496df11b710081bd90ecc3a3db6adb4fee36f6a411e7bc91a18aa42"}, + {file = "yarl-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:24ad1d10c9db1953291f56b5fe76203977f1ed05f82d09ec97acb623a7976574"}, + {file = "yarl-1.8.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a1fca9588f360036242f379bfea2b8b44cae2721859b1c56d033adfd5893634"}, + {file = "yarl-1.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f37db05c6051eff17bc832914fe46869f8849de5b92dc4a3466cd63095d23dfd"}, + {file = "yarl-1.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77e913b846a6b9c5f767b14dc1e759e5aff05502fe73079f6f4176359d832581"}, + {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0978f29222e649c351b173da2b9b4665ad1feb8d1daa9d971eb90df08702668a"}, + {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388a45dc77198b2460eac0aca1efd6a7c09e976ee768b0d5109173e521a19daf"}, + {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2305517e332a862ef75be8fad3606ea10108662bc6fe08509d5ca99503ac2aee"}, + {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42430ff511571940d51e75cf42f1e4dbdded477e71c1b7a17f4da76c1da8ea76"}, + {file = "yarl-1.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3150078118f62371375e1e69b13b48288e44f6691c1069340081c3fd12c94d5b"}, + {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c15163b6125db87c8f53c98baa5e785782078fbd2dbeaa04c6141935eb6dab7a"}, + {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d04acba75c72e6eb90745447d69f84e6c9056390f7a9724605ca9c56b4afcc6"}, + {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e7fd20d6576c10306dea2d6a5765f46f0ac5d6f53436217913e952d19237efc4"}, + {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:75c16b2a900b3536dfc7014905a128a2bea8fb01f9ee26d2d7d8db0a08e7cb2c"}, + {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6d88056a04860a98341a0cf53e950e3ac9f4e51d1b6f61a53b0609df342cc8b2"}, + {file = "yarl-1.8.2-cp311-cp311-win32.whl", hash = "sha256:fb742dcdd5eec9f26b61224c23baea46c9055cf16f62475e11b9b15dfd5c117b"}, + {file = "yarl-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8c46d3d89902c393a1d1e243ac847e0442d0196bbd81aecc94fcebbc2fd5857c"}, + {file = "yarl-1.8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ceff9722e0df2e0a9e8a79c610842004fa54e5b309fe6d218e47cd52f791d7ef"}, + {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f6b4aca43b602ba0f1459de647af954769919c4714706be36af670a5f44c9c1"}, + {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1684a9bd9077e922300ecd48003ddae7a7474e0412bea38d4631443a91d61077"}, + {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ebb78745273e51b9832ef90c0898501006670d6e059f2cdb0e999494eb1450c2"}, + {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3adeef150d528ded2a8e734ebf9ae2e658f4c49bf413f5f157a470e17a4a2e89"}, + {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57a7c87927a468e5a1dc60c17caf9597161d66457a34273ab1760219953f7f4c"}, + {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:efff27bd8cbe1f9bd127e7894942ccc20c857aa8b5a0327874f30201e5ce83d0"}, + {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a783cd344113cb88c5ff7ca32f1f16532a6f2142185147822187913eb989f739"}, + {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:705227dccbe96ab02c7cb2c43e1228e2826e7ead880bb19ec94ef279e9555b5b"}, + {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:34c09b43bd538bf6c4b891ecce94b6fa4f1f10663a8d4ca589a079a5018f6ed7"}, + {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a48f4f7fea9a51098b02209d90297ac324241bf37ff6be6d2b0149ab2bd51b37"}, + {file = "yarl-1.8.2-cp37-cp37m-win32.whl", hash = "sha256:0414fd91ce0b763d4eadb4456795b307a71524dbacd015c657bb2a39db2eab89"}, + {file = "yarl-1.8.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d881d152ae0007809c2c02e22aa534e702f12071e6b285e90945aa3c376463c5"}, + {file = "yarl-1.8.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5df5e3d04101c1e5c3b1d69710b0574171cc02fddc4b23d1b2813e75f35a30b1"}, + {file = "yarl-1.8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7a66c506ec67eb3159eea5096acd05f5e788ceec7b96087d30c7d2865a243918"}, + {file = "yarl-1.8.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2b4fa2606adf392051d990c3b3877d768771adc3faf2e117b9de7eb977741229"}, + {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e21fb44e1eff06dd6ef971d4bdc611807d6bd3691223d9c01a18cec3677939e"}, + {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93202666046d9edadfe9f2e7bf5e0782ea0d497b6d63da322e541665d65a044e"}, + {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc77086ce244453e074e445104f0ecb27530d6fd3a46698e33f6c38951d5a0f1"}, + {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dd68a92cab699a233641f5929a40f02a4ede8c009068ca8aa1fe87b8c20ae3"}, + {file = "yarl-1.8.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b372aad2b5f81db66ee7ec085cbad72c4da660d994e8e590c997e9b01e44901"}, + {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6f3515aafe0209dd17fb9bdd3b4e892963370b3de781f53e1746a521fb39fc0"}, + {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dfef7350ee369197106805e193d420b75467b6cceac646ea5ed3049fcc950a05"}, + {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:728be34f70a190566d20aa13dc1f01dc44b6aa74580e10a3fb159691bc76909d"}, + {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ff205b58dc2929191f68162633d5e10e8044398d7a45265f90a0f1d51f85f72c"}, + {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf211dcad448a87a0d9047dc8282d7de59473ade7d7fdf22150b1d23859f946"}, + {file = "yarl-1.8.2-cp38-cp38-win32.whl", hash = "sha256:272b4f1599f1b621bf2aabe4e5b54f39a933971f4e7c9aa311d6d7dc06965165"}, + {file = "yarl-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:326dd1d3caf910cd26a26ccbfb84c03b608ba32499b5d6eeb09252c920bcbe4f"}, + {file = "yarl-1.8.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f8ca8ad414c85bbc50f49c0a106f951613dfa5f948ab69c10ce9b128d368baf8"}, + {file = "yarl-1.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:418857f837347e8aaef682679f41e36c24250097f9e2f315d39bae3a99a34cbf"}, + {file = "yarl-1.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae0eec05ab49e91a78700761777f284c2df119376e391db42c38ab46fd662b77"}, + {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:009a028127e0a1755c38b03244c0bea9d5565630db9c4cf9572496e947137a87"}, + {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3edac5d74bb3209c418805bda77f973117836e1de7c000e9755e572c1f7850d0"}, + {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da65c3f263729e47351261351b8679c6429151ef9649bba08ef2528ff2c423b2"}, + {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ef8fb25e52663a1c85d608f6dd72e19bd390e2ecaf29c17fb08f730226e3a08"}, + {file = "yarl-1.8.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcd7bb1e5c45274af9a1dd7494d3c52b2be5e6bd8d7e49c612705fd45420b12d"}, + {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44ceac0450e648de86da8e42674f9b7077d763ea80c8ceb9d1c3e41f0f0a9951"}, + {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:97209cc91189b48e7cfe777237c04af8e7cc51eb369004e061809bcdf4e55220"}, + {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:48dd18adcf98ea9cd721a25313aef49d70d413a999d7d89df44f469edfb38a06"}, + {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e59399dda559688461762800d7fb34d9e8a6a7444fd76ec33220a926c8be1516"}, + {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d617c241c8c3ad5c4e78a08429fa49e4b04bedfc507b34b4d8dceb83b4af3588"}, + {file = "yarl-1.8.2-cp39-cp39-win32.whl", hash = "sha256:cb6d48d80a41f68de41212f3dfd1a9d9898d7841c8f7ce6696cf2fd9cb57ef83"}, + {file = "yarl-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:6604711362f2dbf7160df21c416f81fac0de6dbcf0b5445a2ef25478ecc4c778"}, + {file = "yarl-1.8.2.tar.gz", hash = "sha256:49d43402c6e3013ad0978602bf6bf5328535c48d192304b91b97a3c6790b1562"}, ] zipp = [ {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, diff --git a/pyproject.toml b/pyproject.toml index 08e5f848..e5230264 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ logging-journald = [{ version = '*', platform = 'linux' }] [tool.poetry.group.dev.dependencies] aiocontextvars = "0.2.2" aiohttp = "<4" -aiohttp-asgi = "^0.4.0" +aiohttp-asgi = "^0.4.3" async-timeout = "^4.0.2" autoflake = "1.4" collective-checkdocs = "^0.2" @@ -75,7 +75,7 @@ aiomisc = "aiomisc_pytest.pytest_plugin" [tool.poetry.extras] aiohttp = ["aiohttp"] -asgi = ["aiohttp-asgi~=0.4.2"] +asgi = ["aiohttp-asgi~=0.4.3"] carbon = ["aiocarbon~=0.15"] raven = ["aiohttp', 'raven"] uvloop = ["uvloop>=0.14,<1"] From 7f9e37eddde546527bf08ee81d91d618c4a11b8b Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 12:45:26 +0300 Subject: [PATCH 19/45] pylama fixes --- aiomisc/io.py | 1 - aiomisc/service/asgi.py | 1 - poetry.lock | 6 +++--- pyproject.toml | 2 +- tests/test_aggregate.py | 2 +- tests/test_entrypoint.py | 7 ++----- tests/test_worker_pool.py | 2 +- 7 files changed, 8 insertions(+), 13 deletions(-) diff --git a/aiomisc/io.py b/aiomisc/io.py index 43565a52..1c4e65c0 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -8,7 +8,6 @@ ) from .compat import EventLoopMixin -from .thread_pool import threaded T = TypeVar("T", bound=Union[str, bytes]) diff --git a/aiomisc/service/asgi.py b/aiomisc/service/asgi.py index e5445fbf..a3e6077a 100644 --- a/aiomisc/service/asgi.py +++ b/aiomisc/service/asgi.py @@ -1,5 +1,4 @@ from abc import abstractmethod -from typing import Any, Protocol, Union from aiohttp.web import Application from aiohttp_asgi import ASGIResource diff --git a/poetry.lock b/poetry.lock index 13d3aa98..f93c02de 100644 --- a/poetry.lock +++ b/poetry.lock @@ -344,7 +344,7 @@ python-versions = ">=3.7" [[package]] name = "identify" -version = "2.5.10" +version = "2.5.11" description = "File identification library for Python" category = "dev" optional = false @@ -1447,8 +1447,8 @@ frozenlist = [ {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, ] identify = [ - {file = "identify-2.5.10-py2.py3-none-any.whl", hash = "sha256:fb7c2feaeca6976a3ffa31ec3236a6911fbc51aec9acc111de2aed99f244ade2"}, - {file = "identify-2.5.10.tar.gz", hash = "sha256:dce9e31fee7dbc45fea36a9e855c316b8fbf807e65a862f160840bb5a2bf5dfd"}, + {file = "identify-2.5.11-py2.py3-none-any.whl", hash = "sha256:e7db36b772b188099616aaf2accbee122949d1c6a1bac4f38196720d6f9f06db"}, + {file = "identify-2.5.11.tar.gz", hash = "sha256:14b7076b29c99b1b0b8b08e96d448c7b877a9b07683cd8cfda2ea06af85ffa1c"}, ] idna = [ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, diff --git a/pyproject.toml b/pyproject.toml index e5230264..1adf2c10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,6 @@ fastapi = "^0.88.0" freezegun = "<1.1" mypy = "^0.991" pre-commit = "^2.20.0" -pylama = "^8.4.1" pytest = "^7.2.0" pytest-cov = "^4.0.0" pytest-freezegun = "^0.4.2" @@ -66,6 +65,7 @@ sphinx-intl = "^2.0" timeout-decorator = "^0.5.0" types-croniter = "^1.3" types-setuptools = "^65.6.0.1" +pylama = "^8.4.1" [tool.poetry.group.uvloop.dependencies] uvloop = "^0.17.0" diff --git a/tests/test_aggregate.py b/tests/test_aggregate.py index 101b6def..dda04c85 100644 --- a/tests/test_aggregate.py +++ b/tests/test_aggregate.py @@ -4,7 +4,7 @@ import platform import time from asyncio import Event, wait -from typing import Any, List, Optional, Sequence +from typing import Any, List, Sequence import pytest from aiocontextvars import ContextVar # type: ignore diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py index beaaa2cd..f3912640 100644 --- a/tests/test_entrypoint.py +++ b/tests/test_entrypoint.py @@ -5,7 +5,7 @@ from asyncio.tasks import Task from contextlib import ExitStack, suppress from tempfile import mktemp -from typing import Any, Callable, Coroutine, Optional, Tuple, Union +from typing import Any, Optional, Tuple import aiohttp.web import fastapi @@ -16,10 +16,7 @@ from aiomisc.entrypoint import Entrypoint from aiomisc.service import TCPServer, TLSServer, UDPServer from aiomisc.service.aiohttp import AIOHTTPService -from aiomisc.service.asgi import ( - ASGIApplicationType, ASGIHTTPService, ASGIReceiveType, ASGIScopeType, - ASGISendType, -) +from aiomisc.service.asgi import ASGIApplicationType, ASGIHTTPService from aiomisc.service.tcp import RobustTCPClient, TCPClient from aiomisc.service.tls import RobustTLSClient, TLSClient from tests import unix_only diff --git a/tests/test_worker_pool.py b/tests/test_worker_pool.py index f4ccadfb..cf1e6a62 100644 --- a/tests/test_worker_pool.py +++ b/tests/test_worker_pool.py @@ -6,7 +6,7 @@ from multiprocessing.context import ProcessError from os import getpid from time import sleep -from typing import Any, AsyncGenerator +from typing import AsyncGenerator import pytest from setproctitle import setproctitle From 18354728de4aa347b3a06538410bf401a36415db Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 12:55:54 +0300 Subject: [PATCH 20/45] skip profiler tests on old python versions --- tests/test_profiler.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_profiler.py b/tests/test_profiler.py index 2f1c3b76..ac11bcb3 100644 --- a/tests/test_profiler.py +++ b/tests/test_profiler.py @@ -1,8 +1,11 @@ import asyncio import os +import sys from pstats import Stats from tempfile import NamedTemporaryFile +import pytest + from aiomisc.service.profiler import Profiler from tests import unix_only @@ -17,6 +20,7 @@ async def test_profiler_start_stop(): @unix_only +@pytest.mark.skipif(sys.version_info < (3, 9)) async def test_profiler_dump(): profiler = None fl = NamedTemporaryFile(delete=False) From 858a9d10263e666e5f824b03ab136a920071c69e Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 13:00:01 +0300 Subject: [PATCH 21/45] add reason --- tests/test_profiler.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_profiler.py b/tests/test_profiler.py index ac11bcb3..55f4061a 100644 --- a/tests/test_profiler.py +++ b/tests/test_profiler.py @@ -20,7 +20,10 @@ async def test_profiler_start_stop(): @unix_only -@pytest.mark.skipif(sys.version_info < (3, 9)) +@pytest.mark.skipif( + sys.version_info < (3, 9), + reason="get_stats_profile available on 3.9+", +) async def test_profiler_dump(): profiler = None fl = NamedTemporaryFile(delete=False) From 4a19cc2e127368f8ec43ef2c67eaee4812f431a2 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 13:29:34 +0300 Subject: [PATCH 22/45] fix version --- tests/test_profiler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_profiler.py b/tests/test_profiler.py index 55f4061a..bdf56f49 100644 --- a/tests/test_profiler.py +++ b/tests/test_profiler.py @@ -21,8 +21,8 @@ async def test_profiler_start_stop(): @unix_only @pytest.mark.skipif( - sys.version_info < (3, 9), - reason="get_stats_profile available on 3.9+", + sys.version_info < (3, 10), + reason="get_stats_profile available on 3.10+", ) async def test_profiler_dump(): profiler = None From 1113d7c65817b6fd191b2bf14fa327f0c2d19324 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 16:59:57 +0300 Subject: [PATCH 23/45] bump to 16.3.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1adf2c10..d1cb2377 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aiomisc" -version = "16.2.11" +version = "16.3.0" description = "aiomisc - miscellaneous utils for asyncio" authors = ["Dmitry Orlov "] readme = "README.rst" From c6f274d01d335dd1b3a896a3897734e1cdda2d4a Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 17:06:04 +0300 Subject: [PATCH 24/45] move pylyma config to pyproject.toml --- pylama.ini | 9 --------- pyproject.toml | 10 ++++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 pylama.ini diff --git a/pylama.ini b/pylama.ini deleted file mode 100644 index 32434b79..00000000 --- a/pylama.ini +++ /dev/null @@ -1,9 +0,0 @@ -[pylama] -linters = mccabe,pycodestyle,pyflakes -skip = *env*,.tox*,*build*,.*,env/*,.venv/* -ignore = C901 - -[pylama:pycodestyle] -max_line_length = 80 -show-pep8 = True -show-source = True diff --git a/pyproject.toml b/pyproject.toml index d1cb2377..fc8a5882 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -114,3 +114,13 @@ disallow_incomplete_defs = false disallow_untyped_calls = false disallow_untyped_decorators = false disallow_untyped_defs = false + +[tool.pylama] +linters = "mccabe,pycodestyle,pyflakes" +skip = "*env*,.tox*,*build*,.*,env/*,.venv/*" +ignore = "C901" + +[tool.pylama.linter.pycodestyle] +max_line_length = 80 +show-pep8 = true +show-source = true From 811a221ba67566f4fc993d17b69eff3fa673fb5a Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 17:53:42 +0300 Subject: [PATCH 25/45] add version --- aiomisc/__init__.py | 3 ++ aiomisc/version.py | 8 ++--- bump.py | 79 --------------------------------------------- 3 files changed, 7 insertions(+), 83 deletions(-) delete mode 100644 bump.py diff --git a/aiomisc/__init__.py b/aiomisc/__init__.py index f23b08ff..28adf6fd 100644 --- a/aiomisc/__init__.py +++ b/aiomisc/__init__.py @@ -25,6 +25,7 @@ SelectResult, awaitable, bind_socket, cancel_tasks, chunk_list, new_event_loop, select, shield, ) +from .version import __version__, version_info from .worker_pool import WorkerPool @@ -75,5 +76,7 @@ "threaded_iterable_separate", "threaded_separate", "timeout", + "version", + "version_info", "wait_coroutine", ) diff --git a/aiomisc/version.py b/aiomisc/version.py index f9128abc..c643df06 100644 --- a/aiomisc/version.py +++ b/aiomisc/version.py @@ -1,5 +1,5 @@ -""" This file is automatically generated by distutils. """ +import pkg_resources -# Follow PEP-0396 rationale -version_info = (16, 2, 11, "gda272c7") -__version__ = "16.2.11" + +__version__ = pkg_resources.get_distribution("aiomisc").version +version_info = tuple(map(int, __version__.split("."))) diff --git a/bump.py b/bump.py deleted file mode 100644 index 827255fe..00000000 --- a/bump.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -import logging -from os import environ -from subprocess import check_output - - -log = logging.getLogger('' if __name__ == '__main__' else __name__) - -VERSION_FILE_TEMPLATE = ''' -""" This file is automatically generated by distutils. """ - -# Follow PEP-0396 rationale -version_info = ({major}, {minor}, {commits}, "{commit_hash}") -__version__ = "{major}.{minor}.{commits}" -''' - - -def git_version(): - # construct minimal environment - env = { - 'LANG': 'C', - 'LANGUAGE': 'C', - 'LC_ALL': 'C', - 'PATH': environ.get('PATH'), - 'SYSTEMROOT': environ.get('SYSTEMROOT'), - } - - env = {k: v for k, v in env.items() if v is not None} - - try: - output = check_output([ - 'git', 'describe', '--always', '--long', 'HEAD' - ], env=env).decode() - except OSError: - output = 'v0.0' - - log.info("GIT version is: %r", output) - version, commits, commit_hash = output.lstrip('v').strip().rsplit('-', 2) - - return ( - tuple(map(int, version.split('.'))), - int(commits), - commit_hash, - ) - - -def update_version(filename='version.py'): - version, commits, commit_hash = git_version() - - major, minor = version - - content = VERSION_FILE_TEMPLATE.format( - major=major, - minor=minor, - commits=commits, - commit_hash=commit_hash - ) - - log.info( - 'Writing version %s.%s.%s-%s to %r', - major, minor, commits, commit_hash, - filename, - ) - - with open(filename, 'w+') as version_file: - version_file.write(content.lstrip()) - - -if __name__ == '__main__': - # Just for manual testing - from argparse import ArgumentParser - - parser = ArgumentParser() - parser.add_argument('version_file') - arguments = parser.parse_args() - logging.basicConfig(level=logging.INFO, format='%(message)s') - - update_version(arguments.version_file) From 64c7756ce8358f6886f7a8bc1481e485336b9e8a Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 17:58:30 +0300 Subject: [PATCH 26/45] remove warning for worker_pool --- aiomisc/worker_pool.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/aiomisc/worker_pool.py b/aiomisc/worker_pool.py index 026f93df..72ec081d 100644 --- a/aiomisc/worker_pool.py +++ b/aiomisc/worker_pool.py @@ -4,7 +4,6 @@ import os import socket import sys -import warnings from inspect import Traceback from multiprocessing import ProcessError from os import chmod, urandom @@ -27,13 +26,6 @@ from aiomisc_worker.protocol import AsyncProtocol, FileIOProtocol -if sys.version_info < (3, 7): - warnings.warn( - "Python 3.6 works not well see https://bugs.python.org/issue37380", - RuntimeWarning, - ) - - class WorkerPoolStatistic(Statistic): processes: int spawning: int From 10cd927d37bf09af53bfe064a28dd977835a3db0 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 19:02:29 +0300 Subject: [PATCH 27/45] fix setattr and getattr --- aiomisc/service/base.py | 22 ++++++++++++++++------ aiomisc/service/process.py | 1 - tests/test_entrypoint.py | 17 +++++++++++++---- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/aiomisc/service/base.py b/aiomisc/service/base.py index 4aff6834..1208d8a8 100644 --- a/aiomisc/service/base.py +++ b/aiomisc/service/base.py @@ -44,7 +44,12 @@ class Service(metaclass=ServiceMeta): __async_required__: Tuple[str, ...] = ("start", "stop") __required__: Tuple[str, ...] = () - __instance_params: Dict[str, Any] + _instance_params: Dict[str, Any] + + def __new__(cls, *args: Any, **kwargs: Any) -> "Service": + instance = super().__new__(cls) + instance._instance_params = {} + return instance def __init__(self, **kwargs: Any): lost_kw = self.__required__ - kwargs.keys() @@ -55,11 +60,16 @@ def __init__(self, **kwargs: Any): self.__context: Optional[Context] = None self.__start_event: Optional[asyncio.Event] = None - def __getattr__(self, item: str) -> Any: + def __getattr__(self, key: str) -> Any: try: - return self.__instance_params[item] + return self._instance_params[key] except KeyError as e: - raise AttributeError from e + raise AttributeError() from e + + def __setattr__(self, key: str, value: Any) -> None: + super(Service, self).__setattr__(key, value) + if key in self._instance_params: + self._instance_params[key] = value @property def start_event(self) -> asyncio.Event: @@ -80,13 +90,13 @@ def set_loop(self, loop: asyncio.AbstractEventLoop) -> None: self.__start_event = asyncio.Event() def _set_params(self, **kwargs: Any) -> None: - self.__instance_params = kwargs + self._instance_params = kwargs for name, value in kwargs.items(): setattr(self, name, value) def __getstate__(self) -> Dict[str, Any]: - return self.__instance_params + return self._instance_params def __setstate__(self, state: Dict[str, Any]) -> None: self._set_params(**state) diff --git a/aiomisc/service/process.py b/aiomisc/service/process.py index 32297041..cc8e58fd 100644 --- a/aiomisc/service/process.py +++ b/aiomisc/service/process.py @@ -38,7 +38,6 @@ class ProcessService(Service): _process_start_event: synchronize.Event _process_stop_event: synchronize.Event _lock: Lock - _instance_params: Dict[str, Any] def get_process_kwargs(self) -> Dict[str, Any]: return {} diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py index f3912640..2e5b97ee 100644 --- a/tests/test_entrypoint.py +++ b/tests/test_entrypoint.py @@ -164,6 +164,8 @@ async def start(self): def test_tcp_server(): + event = asyncio.Event() + class TestService(TCPServer): DATA = [] @@ -173,6 +175,7 @@ async def handle_client( ): self.DATA.append(await reader.readline()) writer.close() + event.set() service = TestService("127.0.0.1", 0) @@ -185,12 +188,15 @@ def writer(port): loop.run_until_complete( asyncio.wait_for(writer(service.port), timeout=10), ) + loop.run_until_complete(event.wait()) assert TestService.DATA assert TestService.DATA == [b"hello server\n"] def test_tcp_client(aiomisc_socket_factory, localhost): + event = asyncio.Event() + class TestService(TCPServer): DATA = [] @@ -199,23 +205,21 @@ async def handle_client( writer: asyncio.StreamWriter, ): self.DATA.append(await reader.readline()) + event.set() class TestClient(TCPClient): - event: asyncio.Event - async def handle_connection( self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, ) -> None: writer.write(b"hello server\n") await writer.drain() - self.loop.call_soon(self.event.set) port, sock = aiomisc_socket_factory() event = asyncio.Event() services = [ TestService(sock=sock), - TestClient(address=localhost, port=port, event=event), + TestClient(address=localhost, port=port), ] async def go(): @@ -225,6 +229,7 @@ async def go(): loop.run_until_complete( asyncio.wait_for(go(), timeout=10), ) + loop.run_until_complete(event.wait()) assert TestService.DATA assert TestService.DATA == [b"hello server\n"] @@ -286,6 +291,8 @@ async def go(): def test_tls_server( client_cert_required, certs, ssl_client_context, localhost, ): + event = asyncio.Event() + class TestService(TLSServer): DATA = [] @@ -295,6 +302,7 @@ async def handle_client( ): self.DATA.append(await reader.readline()) writer.close() + event.set() service = TestService( address="127.0.0.1", port=0, @@ -325,6 +333,7 @@ def writer(port): loop.run_until_complete( asyncio.wait_for(writer(service.port), timeout=10), ) + loop.run_until_complete(event.wait()) assert TestService.DATA assert TestService.DATA == [b"hello server\n"] From 49c508e8b49e34a5fcd57cb2add8be06e0282fb0 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 19:12:39 +0300 Subject: [PATCH 28/45] linter fixes --- aiomisc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiomisc/__init__.py b/aiomisc/__init__.py index 28adf6fd..477cc947 100644 --- a/aiomisc/__init__.py +++ b/aiomisc/__init__.py @@ -48,6 +48,7 @@ "StrategyStop", "ThreadPoolExecutor", "WorkerPool", + "__version__", "aggregate", "aggregate_async", "asyncbackoff", @@ -76,7 +77,6 @@ "threaded_iterable_separate", "threaded_separate", "timeout", - "version", "version_info", "wait_coroutine", ) From 41ec8780fba5317967e91baa458a98ecddb8b98c Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Tue, 20 Dec 2022 19:15:32 +0300 Subject: [PATCH 29/45] add __all__ for version --- aiomisc/version.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aiomisc/version.py b/aiomisc/version.py index c643df06..719be3c6 100644 --- a/aiomisc/version.py +++ b/aiomisc/version.py @@ -3,3 +3,9 @@ __version__ = pkg_resources.get_distribution("aiomisc").version version_info = tuple(map(int, __version__.split("."))) + + +__all__ = ( + "__version__", + "version_info", +) From 7cf070bad4ec007b5d2ea0adfbe11a0f8fb76df5 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 29 Dec 2022 08:59:32 +0300 Subject: [PATCH 30/45] Improve documentation --- Makefile | 6 +- aiomisc/version.py | 14 +- docs/requirements.txt | 1 - docs/source/async_backoff.rst | 2 + docs/source/conf.py | 10 +- docs/source/index.rst | 198 ++++++++- docs/source/locale/ru/LC_MESSAGES/index.po | 392 ++++++++++++++++-- docs/source/locale/ru/LC_MESSAGES/services.po | 120 +++--- docs/source/locale/ru/LC_MESSAGES/tutorial.po | 147 ++++--- docs/source/services.rst | 33 +- docs/source/tutorial.rst | 8 +- poetry.lock | 150 ++++++- pyproject.toml | 12 +- 13 files changed, 882 insertions(+), 211 deletions(-) diff --git a/Makefile b/Makefile index 23480dad..df3a20d4 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ all: bump clean sdist test upload -NAME:=$(shell python3 setup.py --name) -VERSION:=$(shell python3 setup.py --version | sed 's/+/-/g') +NAME:=$(shell poetry version -n | awk '{print $1}') +VERSION:=$(shell poetry version -n | awk '{print $2}') bump: - python3 bump.py aiomisc/version.py + poetry build uml: docker run --rm -v $(shell pwd):/mnt hrektts/plantuml \ diff --git a/aiomisc/version.py b/aiomisc/version.py index 719be3c6..b819a46a 100644 --- a/aiomisc/version.py +++ b/aiomisc/version.py @@ -1,11 +1,5 @@ -import pkg_resources +# THIS FILE WAS GENERATED BY "poem_plugins.general.version.drivers.git.GitVersionDriver" +# NEWER EDIT THIS FILE MANUALLY - -__version__ = pkg_resources.get_distribution("aiomisc").version -version_info = tuple(map(int, __version__.split("."))) - - -__all__ = ( - "__version__", - "version_info", -) +version_info = (16, 3, 0) +__version__ = "16.3.0" diff --git a/docs/requirements.txt b/docs/requirements.txt index 2c82b705..e6adcd19 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ # ONLY FOR ReadTheDocs -.[develop] autodoc furo diff --git a/docs/source/async_backoff.rst b/docs/source/async_backoff.rst index 468fd33c..8d371fbb 100644 --- a/docs/source/async_backoff.rst +++ b/docs/source/async_backoff.rst @@ -103,6 +103,8 @@ Keyword arguments notation: ... +.. _asyncretry: + ``asyncretry`` ============== diff --git a/docs/source/conf.py b/docs/source/conf.py index 98f340f8..cbc58947 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,8 +20,8 @@ import os import sys from datetime import datetime - from importlib.machinery import SourceFileLoader +from typing import Any, Dict, List sys.path.insert(0, os.path.abspath(os.path.dirname("__file__"))) @@ -88,12 +88,12 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [] +exclude_patterns: List[Any] = [] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" @@ -163,7 +163,7 @@ # -- Options for LaTeX output --------------------------------------------- -latex_elements = { +latex_elements: Dict[str, Any] = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'a4paper', @@ -242,5 +242,5 @@ # html_sidebars = {"**": ["about.html", "navigation.html", "searchbox.html"]} -locale_dirs = ['locale/'] # path is example but recommended. +locale_dirs = ["locale/"] # path is example but recommended. gettext_compact = False # optional. diff --git a/docs/source/index.rst b/docs/source/index.rst index 54bdf775..0ec82a18 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -25,48 +25,107 @@ aiomisc - miscellaneous utils for asyncio Miscellaneous utils for asyncio. +As a programmer, you are no stranger to the challenges that come with building +and maintaining software applications. One area that can be particularly +difficult is making architecture of the software that using asynchronous I/O. + +This is where aiomisc comes in. aiomisc is a Python library that provides a +collection of utility functions and classes for working with asynchronous I/O +in a more intuitive and efficient way. It is built on top of the ``asyncio`` +library and is designed to make it easier for developers to write +asynchronous code that is both reliable and scalable. + +With aiomisc, you can take advantage of powerful features like +:doc:`worker pools `, :doc:`connection pools `, +:doc:`circuit breaker pattern `, +and retry mechanisms such as :doc:`asyncbackoff ` and +:ref:`asyncretry ` to make your asyncio code more robust and +easier to maintain. In this documentation, we'll take a closer look at what +``aiomisc`` has to offer and how it can help you streamline your asyncio +development. Installation ------------ -Installing from PyPI: +Installation is possible in standard ways, such as PyPI or installation from +a git repository directly. + +Installing from PyPI_: .. code-block:: bash pip3 install aiomisc -With uvloop_: +Installing from github.com: .. code-block:: bash - pip3 install "aiomisc[uvloop]" + # Using git tool + pip3 install git+https://github.com/aiokitchen/aiomisc.git + # Alternative way using http + pip3 install \ + https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip -With aiohttp_: +The package contains several extras and you can install additional dependencies +if you specify them in this way. + +With uvloop_: .. code-block:: bash - pip3 install "aiomisc[aiohttp]" + pip3 install "aiomisc[uvloop]" -Installing from github.com: +With aiohttp_: .. code-block:: bash - pip3 install git+https://github.com/aiokitchen/aiomisc.git - pip3 install \ - https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip + pip3 install "aiomisc[aiohttp]" -.. _uvloop: https://pypi.org/project/uvloop +Complete table of extras bellow: + ++-----------------------------------+-------------------+------------------------------------------------+ +| example | dependencies | description | ++===================================+===================+================================================+ +| ``pip install aiomisc[aiohttp]`` | ``aiohttp`` | For running aiohttp_ applications. | ++-----------------------------------+-------------------+------------------------------------------------+ +| ``pip install aiomisc[asgi]`` | ``aiohttp-asgi`` | For running ASGI_ applications | ++-----------------------------------+-------------------+------------------------------------------------+ +| ``pip install aiomisc[carbon]`` | ``aiocarbon`` | Sending metrics to carbon_ (part of graphite_) | ++-----------------------------------+-------------------+------------------------------------------------+ +| ``pip install aiomisc[cron]`` | ``croniter`` | use croniter_ for sheduling tasks | ++-----------------------------------+-------------------+------------------------------------------------+ +| ``pip install aiomisc[raven]`` | ``raven`` | Sending exceptions to sentry_ using raven_ | ++-----------------------------------+-------------------+------------------------------------------------+ +| ``pip install aiomisc[rich]`` | ``rich`` | You might using rich_ for logging | ++-----------------------------------+-------------------+------------------------------------------------+ +| ``pip install aiomisc[uvloop]`` | ``uvloop`` | use uvloop_ as a default event loop | ++-----------------------------------+-------------------+------------------------------------------------+ + +.. _ASGI: https://asgi.readthedocs.io/en/latest/ +.. _PyPI: https://pypi.org/ .. _aiohttp: https://pypi.org/project/aiohttp - +.. _carbon: https://pypi.org/project/carbon +.. _croniter: https://pypi.org/project/croniter +.. _graphite: http://graphiteapp.org +.. _raven: https://pypi.org/project/raven +.. _rich: https://pypi.org/project/rich +.. _sentry: https://sentry.io/ +.. _uvloop: https://pypi.org/project/uvloop Quick Start ----------- -Complete the :doc:`/tutorial` or see this quick start. +This section will cover how this library creates and uses the event loop and +creates services. Of course, you can't write about everything here, but you +can read about a lot in the :doc:`/tutorial` section, and you can always refer +to the :doc:`/modules` and :doc:`/api/index` sections for help. + +Event-loop and entrypoint ++++++++++++++++++++++++++ -Async entrypoint with logging and useful arguments: +Let's look at this simple example first: .. code-block:: python @@ -84,13 +143,22 @@ Async entrypoint with logging and useful arguments: if __name__ == '__main__': - with entrypoint( - log_level="info", log_format="color" - ) as loop: + with entrypoint(log_level="info", log_format="color") as loop: loop.run_until_complete(main()) -Install event loop on program start: +This code declares an asynchronous ``main()`` function that exits after +3 seconds. It would seem nothing interesting, but the whole point is in +the ``entrypoint``. + +What does the ``entrypoint`` do, it would seem not so much, it creates an +event-loop and transfers control to the user. However, under the hood, the +logger is configured in a separate thread, a pool of threads is created, +services are started, but more on that later and there are no services +in this example. + +Alternatively, you can choose not to use an entrypoint, just create an +event-loop and set this as a default event loop for current thread: .. code-block:: python :name: test_index_get_loop @@ -98,9 +166,10 @@ Install event loop on program start: import asyncio import aiomisc - # Installing uvloop event loop - # and set `aiomisc.thread_pool.ThreadPoolExecutor` - # as default executor + # * Installs uvloop event loop is it's has been installed. + # * Creates and set `aiomisc.thread_pool.ThreadPoolExecutor` + # as a default executor + # * Sets just created event-loop as a current event-loop for this thread. aiomisc.new_event_loop() async def main(): @@ -110,8 +179,13 @@ Install event loop on program start: loop = asyncio.get_event_loop() loop.run_until_complete(main()) +The example above is useful if your code is already using an implicitly created +event loop, you will have to modify less code, just add +``aiomisc.new_event_loop()`` and all calls to ``asyncio.get_event_loop()`` +will return the created instance. -Close current event loop and install a new one: +However, you can do with one call. Following example closes implicitly created +asyncio event loop and install a new one: .. code-block:: python :name: test_index_new_loop @@ -126,6 +200,88 @@ Close current event loop and install a new one: loop = aiomisc.new_event_loop() loop.run_until_complete(main()) +Services +++++++++ + +The main thing that an ``entrypoint`` does is start and gracefully +stop services. + +The service concept within this library means a class derived from +the ``aiosmic.Service`` class and implementing the +``async def start(self) -> None:`` method and optionally the +``async def stop(self, exc: Optional[ Exception]) -> None`` method. + +The concept of stopping a service is not necessarily is pressing ``Ctrl+C`` +keys by user, it's actually just exiting the ``entrypoint`` context manager. + +The example below shows what your service might look like: + +.. code-block:: python + + from aiomisc import entrypoint, Service + + class MyService(Service): + async def start(self): + do_something_when_start() + + async def stop(self, exc): + do_graceful_shutdown() + + + with entrypoint(MyService()) as loop: + loop.run_forever() + +The entry point can start as many instances of the service as it likes, +and all of them will start concurrently. + +There is also a way if the ``start`` method is a payload for a service, +and then there is no need to implement the stop method, since the running +task with the ``start`` function will be canceled at the stop stage. +But in this case, you will have to notify the ``entrypoint`` that the +initialization of the service instance is complete and it can continue. + +Like this: + +.. code-block:: python + + import asyncio + from threading import Event + from aiomisc import entrypoint, Service + + event = Event() + + class MyService(Service): + async def start(self): + # Send signal to entrypoint for continue running + self.start_event.set() + await asyncio.sleep(3600) + + + with entrypoint(MyService()) as loop: + assert event.is_set() + +.. note:: + + The ``entrypoint`` passes control to the body of the context manager only + after all service instances have started. As mentioned above, a start is + considered to be the completion of the ``start`` method or the setting of + an start event with ``self.start_event.set()``. + +The whole power of this library is in the set of already implemented or +abstract services. +Such as: :ref:`AIOHTTPService `, +:ref:`ASGIService `, :ref:`TCPServer `, +:ref:`UDPServer `, :ref:`TCPClient `, +:ref:`PeriodicService `, +:ref:`CronService ` and so on. + +Unfortunately in this section it is not possible to pay more attention to this, +please pay attention to the :doc:`/tutorial` section section, there are more +examples and explanations, and of cource you always can find out an answer on +the :doc:`/api/index` or in the source code. The authors have tried to make +the source code as clear and simple as possible, so feel free to explore it. + + Versioning ---------- diff --git a/docs/source/locale/ru/LC_MESSAGES/index.po b/docs/source/locale/ru/LC_MESSAGES/index.po index 0777e2fb..57c74584 100644 --- a/docs/source/locale/ru/LC_MESSAGES/index.po +++ b/docs/source/locale/ru/LC_MESSAGES/index.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-26 23:08+0300\n" +"POT-Creation-Date: 2022-12-29 08:57+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/index.rst:2 msgid "aiomisc - miscellaneous utils for asyncio" @@ -35,83 +35,405 @@ msgstr "Актуальная версия" msgid "Miscellaneous utils for asyncio." msgstr "Различные утилиты для asyncio" -#: ../../source/index.rst:30 -msgid "Installation" -msgstr "Установка" +#: ../../source/index.rst:28 +msgid "" +"As a programmer, you are no stranger to the challenges that come with " +"building and maintaining software applications. One area that can be " +"particularly difficult is making architecture of the software that using " +"asynchronous I/O." +msgstr "" +"Вам, как программисту, знакомы проблемы, связанные с созданием и " +"обслуживанием программных приложений. Одной из областей, которая может " +"быть особенно сложной, является создание архитектуры программного " +"обеспечения, использующего асинхронный ввод-вывод." #: ../../source/index.rst:32 -msgid "Installing from PyPI:" -msgstr "Установка с PyPI" +msgid "" +"This is where aiomisc comes in. aiomisc is a Python library that provides" +" a collection of utility functions and classes for working with " +"asynchronous I/O in a more intuitive and efficient way. It is built on " +"top of the ``asyncio`` library and is designed to make it easier for " +"developers to write asynchronous code that is both reliable and scalable." +msgstr "" +"Здесь на помощь приходит aiomisc. aiomisc — это библиотека Python, " +"которая предоставляет набор служебных функций и классов для работы с " +"асинхронным вводом-выводом более интуитивно понятным и эффективным " +"способом. Он построен на основе популярной библиотеки ``asyncio`` и " +"предназначен для облегчения написания асинхронного кода разработчиками, " +"который является одновременно надежным и масштабируемым." #: ../../source/index.rst:38 +msgid "" +"With aiomisc, you can take advantage of powerful features like " +":doc:`worker pools `, :doc:`connection pools `, " +":doc:`circuit breaker pattern `, and retry mechanisms " +"such as :doc:`asyncbackoff ` and :ref:`asyncretry " +"` to make your asyncio code more robust and easier to " +"maintain. In this documentation, we'll take a closer look at what " +"``aiomisc`` has to offer and how it can help you streamline your asyncio " +"development." +msgstr "" +"С aiomisc вы можете воспользоваться такими мощными функциями, как: " +":doc:`worker пул `, :doc:`connection пул `, " +":doc:`шаблон «предохранитель» `, и механизмы повторов " +"такие как :doc:`asyncbackoff ` и :ref:`asyncretry " +"" + +#: ../../source/index.rst:48 +msgid "Installation" +msgstr "Установка" + +#: ../../source/index.rst:50 +msgid "" +"Installation is possible in standard ways, such as PyPI or installation " +"from a git repository directly." +msgstr "" +"Возможна установка стандартными способами, такими как PyPI или установка " +"из репозитория git напрямую." + +#: ../../source/index.rst:53 +msgid "Installing from PyPI_:" +msgstr "Установка с PyPI_:" + +#: ../../source/index.rst:59 +msgid "Installing from github.com:" +msgstr "Установка из репозитория на github.com:" + +#: ../../source/index.rst:70 +msgid "" +"The package contains several extras and you can install additional " +"dependencies if you specify them in this way." +msgstr "" +"Пакет содержит несколько дополнений, и вы можете установить " +"дополнительные зависимости, если вы укажете их таким образом." + +#: ../../source/index.rst:73 msgid "With uvloop_:" msgstr "Вместе с uvloop_" -#: ../../source/index.rst:45 +#: ../../source/index.rst:80 msgid "With aiohttp_:" msgstr "Вместе с aiohttp_:" -#: ../../source/index.rst:52 -msgid "Installing from github.com:" -msgstr "Установка с github.com:" +#: ../../source/index.rst:86 +msgid "Complete table of extras bellow:" +msgstr "Полная таблица дополнений ниже:" + +#: ../../source/index.rst:89 +msgid "example" +msgstr "пример" + +#: ../../source/index.rst:89 +msgid "dependencies" +msgstr "зависимости" + +#: ../../source/index.rst:89 +msgid "description" +msgstr "описание" + +#: ../../source/index.rst:91 +msgid "``pip install aiomisc[aiohttp]``" +msgstr "" -#: ../../source/index.rst:65 +#: ../../source/index.rst:91 +msgid "``aiohttp``" +msgstr "" + +#: ../../source/index.rst:91 +msgid "For running aiohttp_ applications." +msgstr "Для запуска приложений написанных с aiohttp_." + +#: ../../source/index.rst:93 +msgid "``pip install aiomisc[asgi]``" +msgstr "" + +#: ../../source/index.rst:93 +msgid "``aiohttp-asgi``" +msgstr "" + +#: ../../source/index.rst:93 +msgid "For running ASGI_ applications" +msgstr "Для запуска ASGI_ приложений" + +#: ../../source/index.rst:95 +msgid "``pip install aiomisc[carbon]``" +msgstr "" + +#: ../../source/index.rst:95 +msgid "``aiocarbon``" +msgstr "" + +#: ../../source/index.rst:95 +msgid "Sending metrics to carbon_ (part of graphite_)" +msgstr "Чтобы посылать метрики в carbon_ (часть graphite_)" + +#: ../../source/index.rst:97 +msgid "``pip install aiomisc[cron]``" +msgstr "" + +#: ../../source/index.rst:97 +msgid "``croniter``" +msgstr "" + +#: ../../source/index.rst:97 +msgid "use croniter_ for sheduling tasks" +msgstr "планирование задачи с croniter_" + +#: ../../source/index.rst:99 +msgid "``pip install aiomisc[raven]``" +msgstr "" + +#: ../../source/index.rst:99 +msgid "``raven``" +msgstr "" + +#: ../../source/index.rst:99 +msgid "Sending exceptions to sentry_ using raven_" +msgstr "Чтобы посылать исключения в sentry_ используя raven_" + +#: ../../source/index.rst:101 +msgid "``pip install aiomisc[rich]``" +msgstr "" + +#: ../../source/index.rst:101 +msgid "``rich``" +msgstr "" + +#: ../../source/index.rst:101 +msgid "You might using rich_ for logging" +msgstr "Можете использовать rich_ для логирования" + +#: ../../source/index.rst:103 +msgid "``pip install aiomisc[uvloop]``" +msgstr "" + +#: ../../source/index.rst:103 +msgid "``uvloop``" +msgstr "" + +#: ../../source/index.rst:103 +msgid "use uvloop_ as a default event loop" +msgstr "используйте uvloop_ как основной event-loop" + +#: ../../source/index.rst:118 msgid "Quick Start" msgstr "Быстрый старт" -#: ../../source/index.rst:67 -msgid "Complete the :doc:`/tutorial` or see this quick start." -msgstr "Пройдите :doc:`/tutorial` или посмотрите примеры ниже." +#: ../../source/index.rst:120 +msgid "" +"This section will cover how this library creates and uses the event loop " +"and creates services. Of course, you can't write about everything here, " +"but you can read about a lot in the :doc:`/tutorial` section, and you can" +" always refer to the :doc:`/modules` and :doc:`/api/index` sections for " +"help." +msgstr "" +"В этом разделе будет рассказано, как эта библиотека создает и использует " +"цикл обработки событий и создает службы. Конечно, обо всем тут не " +"напишешь, но о многом можно прочитать в разделе :doc:`/tutorial`, и " +"всегда можно обратиться к разделу :doc:`/modules` и разделу " +":doc:`/api/index` для справки." -#: ../../source/index.rst:69 -msgid "Async entrypoint with logging and useful arguments:" +#: ../../source/index.rst:126 +msgid "Event-loop and entrypoint" +msgstr "Eventloop и entrypoint" + +#: ../../source/index.rst:128 +msgid "Let's look at this simple example first:" +msgstr "Сначала рассмотрим этот простой пример:" + +#: ../../source/index.rst:150 +msgid "" +"This code declares an asynchronous ``main()`` function that exits after 3" +" seconds. It would seem nothing interesting, but the whole point is in " +"the ``entrypoint``." msgstr "" -"Асинхронная точка входа (entrypoint) с логированием и полезными " -"аргументами" +"Этот код объявляет асинхронную функцию ``main()``, которая завершается " +"через 3 секунды. Казалось бы, ничего интересного, но все дело в " +"``entrypoint``." -#: ../../source/index.rst:93 -msgid "Install event loop on program start:" -msgstr "Установка event loop на старте программы:" +#: ../../source/index.rst:154 +msgid "" +"What does the ``entrypoint`` do, it would seem not so much, it creates an" +" event-loop and transfers control to the user. However, under the hood, " +"the logger is configured in a separate thread, a pool of threads is " +"created, services are started, but more on that later and there are no " +"services in this example." +msgstr "" +"Что делает ``entrypoint``, казалось бы не так уж и много, она создает " +"event-loop и передает управление пользователю. Однако под капотом " +"настраивается журналирование в отдельном потоке, создается пул потоков, " +"запускаются сервисы, но об этом позже и сервисов в данном примере нет." -#: ../../source/index.rst:114 -msgid "Close current event loop and install a new one:" -msgstr "Закрываем текущий event loop и устанавлиаем новый:" +#: ../../source/index.rst:160 +msgid "" +"Alternatively, you can choose not to use an entrypoint, just create an " +"event-loop and set this as a default event loop for current thread:" +msgstr "" +"В принципе вы можете не использовать точку входа, а просто создать " +"eventloop и установите его по умолчанию для текущего потока:" -#: ../../source/index.rst:130 +#: ../../source/index.rst:182 +msgid "" +"The example above is useful if your code is already using an implicitly " +"created event loop, you will have to modify less code, just add " +"``aiomisc.new_event_loop()`` and all calls to " +"``asyncio.get_event_loop()`` will return the created instance." +msgstr "" +"Приведенный выше пример полезен, если в вашем коде уже неявно " +"используется созданный eventloop, тогда вам придется изменить меньше " +"кода, просто добавьте ``aiomisc.new_event_loop()`` и все вызовы " +"``asyncio.get_event_loop()`` вернет созданный экземпляр." + +#: ../../source/index.rst:187 +msgid "" +"However, you can do with one call. Following example closes implicitly " +"created asyncio event loop and install a new one:" +msgstr "" +"Однако можно обойтись и одним вызовом. Следующий пример закрывает неявно " +"созданный eventloop asyncio и устанавливает новый:" + +#: ../../source/index.rst:204 +msgid "Services" +msgstr "Сервисы" + +#: ../../source/index.rst:206 +msgid "" +"The main thing that an ``entrypoint`` does is start and gracefully stop " +"services." +msgstr "" +"Главное, что делает точка входа, — это запускает и корректно " +"останавливает «Сервисы»." + +#: ../../source/index.rst:209 +msgid "" +"The service concept within this library means a class derived from the " +"``aiosmic.Service`` class and implementing the ``async def start(self) ->" +" None:`` method and optionally the ``async def stop(self, exc: Optional[ " +"Exception]) -> None`` method." +msgstr "" +"Концепция «Сервис», в этой библиотеке, означает класс, наследованный от " +"класса ``aiosmic.Service`` и реализующий метод ``async def start(self) ->" +" None`` и, опционально, метод ``async def stop(self, exc: Optional[ " +"Exception]) -> None``." + +#: ../../source/index.rst:214 +#, fuzzy +msgid "" +"The concept of stopping a service is not necessarily is pressing " +"``Ctrl+C`` keys by user, it's actually just exiting the ``entrypoint`` " +"context manager." +msgstr "" +"Концепция остановки службы не обязательно заключается в нажатии " +"пользователем клавиш ``Ctrl+C``, на самом деле это просто выход из " +"контекстного менеджера ``entrypoint``." + +#: ../../source/index.rst:217 +msgid "The example below shows what your service might look like:" +msgstr "Пример ниже иллюстрирует, как может выглядеть ваш сервис:" + +#: ../../source/index.rst:234 +msgid "" +"The entry point can start as many instances of the service as it likes, " +"and all of them will start concurrently." +msgstr "" +"Точка входа может запускать любое количество экземпляров службы, и все " +"они будут запускаться конкурентно." + +#: ../../source/index.rst:237 +msgid "" +"There is also a way if the ``start`` method is a payload for a service, " +"and then there is no need to implement the stop method, since the running" +" task with the ``start`` function will be canceled at the stop stage. But" +" in this case, you will have to notify the ``entrypoint`` that the " +"initialization of the service instance is complete and it can continue." +msgstr "" +"Также есть способ, если метод ``start`` является полезной нагрузкой для " +"сервиса, и тогда нет необходимости реализовывать метод ``stop``, так как " +"задача с функцией ``start`` будет отменена на этапе выхода из entrypoint." +" Но в этом случае вам придется уведомить ``entrypoint`` о том, что " +"инициализация экземпляра службы завершена и ее можно продолжить." + +#: ../../source/index.rst:243 +msgid "Like this:" +msgstr "Примерно так:" + +#: ../../source/index.rst:265 +msgid "" +"The ``entrypoint`` passes control to the body of the context manager only" +" after all service instances have started. As mentioned above, a start is" +" considered to be the completion of the ``start`` method or the setting " +"of an start event with ``self.start_event.set()``." +msgstr "" +"``entrypoint`` передает управление телу контекстного менеджера только " +"после того, как все экземпляры службы запущены. Как упоминалось выше, " +"стартом считается завершение метода ``start`` или установка стартового " +"события с помощью ``self.start_event.set()``." + +#: ../../source/index.rst:270 +msgid "" +"The whole power of this library is in the set of already implemented or " +"abstract services. Such as: :ref:`AIOHTTPService `, " +":ref:`ASGIService `, :ref:`TCPServer `, " +":ref:`UDPServer `, :ref:`TCPClient `, " +":ref:`PeriodicService `, :ref:`CronService ` and so on." +msgstr "" +"Вся мощь этой библиотеки это набор уже реализованных или абстрактных " +"сервисов таких как: :ref:`AIOHTTPService `, " +":ref:`ASGIService `, :ref:`TCPServer `, " +":ref:`UDPServer `, :ref:`TCPClient `, " +":ref:`PeriodicService `, :ref:`CronService ` и так далее." + +#: ../../source/index.rst:278 +msgid "" +"Unfortunately in this section it is not possible to pay more attention to" +" this, please pay attention to the :doc:`/tutorial` section section, " +"there are more examples and explanations, and of cource you always can " +"find out an answer on the :doc:`/api/index` or in the source code. The " +"authors have tried to make the source code as clear and simple as " +"possible, so feel free to explore it." +msgstr "" +"К сожалению в данном разделе нет возможности уделить этому больше внимания, " +"обратите внимание на раздел :doc:`/tutorial`, там больше примеров и " +"пояснений, ну и конечно вы всегда можете узнать ответ на :doc:`/api/index` " +"или в исходном коде. Авторы постарались сделать исходный код максимально " +"понятным и простым, поэтому не стесняйтесь исследовать его." + +#: ../../source/index.rst:286 msgid "Versioning" msgstr "Версионирование" -#: ../../source/index.rst:132 +#: ../../source/index.rst:288 msgid "This software follows `Semantic Versioning`_" msgstr "" "Это программное обеспечение следует методологиии `Семантического " "Версионирования`_" -#: ../../source/index.rst:136 +#: ../../source/index.rst:292 msgid "How to develop?" msgstr "Как начать разработку?" -#: ../../source/index.rst:138 +#: ../../source/index.rst:294 msgid "Should be installed:" msgstr "Должно быть установлено" -#: ../../source/index.rst:140 +#: ../../source/index.rst:296 msgid "`virtualenv`" msgstr "`virtualenv`" -#: ../../source/index.rst:141 +#: ../../source/index.rst:297 msgid "GNU Make as `make`" msgstr "GNU Make как `make`" -#: ../../source/index.rst:142 +#: ../../source/index.rst:298 msgid "Python 3.7+ as `python3`" msgstr "Python 3.7+ как `python3`" -#: ../../source/index.rst:145 +#: ../../source/index.rst:301 msgid "For setting up developer environment just type" msgstr "Для настройки окружения разработчика просто наберите" -#: ../../source/index.rst:155 +#: ../../source/index.rst:311 msgid "Table Of Contents" msgstr "Содержание" - diff --git a/docs/source/locale/ru/LC_MESSAGES/services.po b/docs/source/locale/ru/LC_MESSAGES/services.po index 464e374d..eeca674b 100644 --- a/docs/source/locale/ru/LC_MESSAGES/services.po +++ b/docs/source/locale/ru/LC_MESSAGES/services.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-01 23:17+0300\n" +"POT-Creation-Date: 2022-12-29 08:09+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/services.rst:2 msgid "Services" @@ -81,11 +81,11 @@ msgstr "" "Этот пакет содержит несколько полезных базовых классов для написания " "простых сервисов." -#: ../../source/services.rst:53 +#: ../../source/services.rst:56 msgid "``TCPServer``" msgstr "Класс ``TCPServer``" -#: ../../source/services.rst:55 +#: ../../source/services.rst:58 msgid "" "``TCPServer`` - it's a base class for writing TCP servers. Just implement" " ``handle_client(reader, writer)`` to use it." @@ -94,11 +94,11 @@ msgstr "" "реализуйте ``handle_client(reader, writer)``, чтобы принимать TCP " "соединения." -#: ../../source/services.rst:98 +#: ../../source/services.rst:103 msgid "``UDPServer``" msgstr "Класс ``UDPServer``" -#: ../../source/services.rst:100 +#: ../../source/services.rst:105 msgid "" "``UDPServer`` - it's a base class for writing UDP servers. Just implement" " ``handle_datagram(data, addr)`` to use it." @@ -107,11 +107,11 @@ msgstr "" "реализуйте ``handle_datagram(data, addr)``, чтобы принимать UDP " "соединения." -#: ../../source/services.rst:115 +#: ../../source/services.rst:120 msgid "``TLSServer``" msgstr "Класс ``TLSServer``" -#: ../../source/services.rst:117 +#: ../../source/services.rst:122 msgid "" "``TLSServer`` - it's a base class for writing TCP servers with TLS. Just " "implement ``handle_client(reader, writer)`` to use it." @@ -119,11 +119,11 @@ msgstr "" "TLSServer - это базовый класс для написания TCP-серверов с использованием" " TLS. Просто реализуйте ``handle_client(reader, writer)``." -#: ../../source/services.rst:142 +#: ../../source/services.rst:149 msgid "``TCPClient``" msgstr "" -#: ../../source/services.rst:144 +#: ../../source/services.rst:151 msgid "" "``TCPClient`` - it's a base class for writing TCP clients. Just implement" " ``handle_connection(reader, writer)`` to use it." @@ -132,11 +132,11 @@ msgstr "" "реализуйте ``handle_client(reader, writer)``, чтобы принимать TCP " "соединения." -#: ../../source/services.rst:190 +#: ../../source/services.rst:197 msgid "``TLSClient``" msgstr "" -#: ../../source/services.rst:192 +#: ../../source/services.rst:199 msgid "" "``TLSClient`` - it's a base class for writing TLS clients. Just implement" " ``handle_connection(reader, writer)`` to use it." @@ -145,11 +145,11 @@ msgstr "" "реализуйте ``handle_client(reader, writer)``, чтобы принимать TCP " "соединения." -#: ../../source/services.rst:247 +#: ../../source/services.rst:254 msgid "``RobustTCPClient``" msgstr "" -#: ../../source/services.rst:249 +#: ../../source/services.rst:256 msgid "" "``RobustTCPClient`` - it's a base class for writing TCP clients with " "auto-reconnection when connection lost. Just implement " @@ -158,11 +158,11 @@ msgstr "" "TLSServer - это базовый класс для написания TCP-серверов с использованием" " TLS. Просто реализуйте ``handle_client(reader, writer)``." -#: ../../source/services.rst:296 +#: ../../source/services.rst:303 msgid "``RobustTLSClient``" msgstr "" -#: ../../source/services.rst:298 +#: ../../source/services.rst:305 msgid "" "``RobustTLSClient`` - it's a base class for writing TLS clients with " "auto-reconnection when connection lost. Just implement " @@ -171,11 +171,11 @@ msgstr "" "TLSServer - это базовый класс для написания TCP-серверов с использованием" " TLS. Просто реализуйте ``handle_client(reader, writer)``." -#: ../../source/services.rst:353 +#: ../../source/services.rst:363 msgid "``PeriodicService``" msgstr "Класс ``PeriodicService``" -#: ../../source/services.rst:355 +#: ../../source/services.rst:365 msgid "" "``PeriodicService`` runs ``PeriodicCallback`` as a service and waits for " "the running callback to complete on the stop method. You need to use " @@ -187,7 +187,7 @@ msgstr "" "PeriodicService в качестве базового класса и переопределить асинхронный " "метод callback." -#: ../../source/services.rst:359 +#: ../../source/services.rst:369 msgid "" "Service class accepts required ``interval`` argument - periodic interval " "in seconds and optional ``delay`` argument - periodic execution delay in " @@ -197,11 +197,11 @@ msgstr "" "запуска в секундах и необязательный аргумент ``delay`` - задержку первого" " выполнения в секундах (по умолчанию 0)." -#: ../../source/services.rst:381 +#: ../../source/services.rst:393 msgid "``CronService``" msgstr "Класс ``CronService``" -#: ../../source/services.rst:385 +#: ../../source/services.rst:395 msgid "" "``CronService`` runs ``CronCallback's`` as a service and waits for " "running callbacks to complete on the stop method." @@ -209,7 +209,7 @@ msgstr "" "``CronService`` запускает ``CronCallback`` в качестве сервиса и ожидает " "завершения выполнения обратных вызовов при остановке." -#: ../../source/services.rst:388 +#: ../../source/services.rst:398 msgid "" "It's based on croniter_. You can register async coroutine method with " "``spec`` argument - cron like format:" @@ -217,16 +217,16 @@ msgstr "" "Основан на croniter_. Вы можете зарегистрировать асинхронный метод с " "аргументом ``spec`` - формат, подобный cron:" -#: ../../source/services.rst:392 +#: ../../source/services.rst:404 msgid "requires installed croniter_:" msgstr "необходимо установить библиотеку croniter_:" -#: ../../source/services.rst:398 ../../source/services.rst:538 -#: ../../source/services.rst:602 +#: ../../source/services.rst:410 ../../source/services.rst:552 +#: ../../source/services.rst:618 msgid "or using extras:" msgstr "или как дополнительную зависимость" -#: ../../source/services.rst:422 +#: ../../source/services.rst:434 msgid "" "You can also inherit from ``CronService``, but remember that callback " "registration should be proceeded before start" @@ -234,11 +234,11 @@ msgstr "" "Вы также можете наследовать от ``CronService``, но помните, что " "регистрация обратного вызова должна выполняться до запуска" -#: ../../source/services.rst:447 +#: ../../source/services.rst:459 msgid "Multiple services" msgstr "Несколько сервисов" -#: ../../source/services.rst:449 +#: ../../source/services.rst:461 msgid "" "Pass several service instances to the ``entrypoint`` to run all of them. " "After exiting the entrypoint service instances will be gracefully shut " @@ -249,11 +249,11 @@ msgstr "" "корректно закрыты вызовом метода ``stop()`` или через отмену метода " "``start()``." -#: ../../source/services.rst:488 +#: ../../source/services.rst:500 msgid "Configuration" msgstr "Конфигурация" -#: ../../source/services.rst:490 +#: ../../source/services.rst:502 msgid "" "``Service`` metaclass accepts all kwargs and will set it to ``self`` as " "attributes." @@ -261,19 +261,19 @@ msgstr "" "Метакласс ``Service`` принимает все именованные аргументы в ``__init__`` " "и устанавливает из как атрибуты в ``self``." -#: ../../source/services.rst:528 +#: ../../source/services.rst:542 msgid "aiohttp service" msgstr "aiohttp сервис" -#: ../../source/services.rst:532 +#: ../../source/services.rst:546 msgid "requires installed aiohttp:" msgstr "требуется установленная библиоткеа aiohttp" -#: ../../source/services.rst:545 +#: ../../source/services.rst:559 msgid "aiohttp application can be started as a service:" msgstr "Приложение aiohttp может быть запущено как сервис:" -#: ../../source/services.rst:587 +#: ../../source/services.rst:601 msgid "" "Class ``AIOHTTPSSLService`` is similar to ``AIOHTTPService`` but creates " "an HTTPS server. You must pass SSL-required options (see ``TLSServer`` " @@ -283,19 +283,19 @@ msgstr "" " сервер. Вы должны передать требуемые для SSL параметры (см. Класс " "TLSServer)." -#: ../../source/services.rst:592 +#: ../../source/services.rst:608 msgid "asgi service" msgstr "asgi сервис" -#: ../../source/services.rst:596 +#: ../../source/services.rst:612 msgid "requires installed aiohttp-asgi:" msgstr "требуется установленная библиоткеа aiohttp-asgi:" -#: ../../source/services.rst:609 +#: ../../source/services.rst:625 msgid "Any ASGI-like application can be started as a service:" msgstr "Любое ASGI совместимое приложение может быть запущено как сервис:" -#: ../../source/services.rst:649 +#: ../../source/services.rst:665 msgid "" "Class ``ASGIHTTPSSLService`` is similar to ``ASGIHTTPService`` but " "creates HTTPS server. You must pass SSL-required options (see " @@ -305,11 +305,11 @@ msgstr "" "HTTPS сервер. Вы должны передать требуемые для SSL параметры (см. Класс " "``TLSServer``)." -#: ../../source/services.rst:653 +#: ../../source/services.rst:672 msgid "Memory Tracer" msgstr "Трассировщик памяти" -#: ../../source/services.rst:655 +#: ../../source/services.rst:674 msgid "" "Simple and useful service for logging large python objects allocated in " "memory." @@ -317,15 +317,15 @@ msgstr "" "Простой и полезный сервис для логирования больших объектов Python, " "размещенных в памяти." -#: ../../source/services.rst:679 ../../source/services.rst:726 +#: ../../source/services.rst:698 ../../source/services.rst:747 msgid "Output example:" msgstr "Пример вывода:" -#: ../../source/services.rst:701 +#: ../../source/services.rst:722 msgid "Profiler" msgstr "``Profiler`` - профилировщик" -#: ../../source/services.rst:703 +#: ../../source/services.rst:724 msgid "" "Simple service for profiling. Optional `path` argument can be provided to" " dump complete profiling data, which can be later used by, for example, " @@ -337,43 +337,44 @@ msgstr "" "позже могут быть использованы, например, snakeviz. Также можно изменить " "порядок с аргументом ``order`` (по умолчанию \"cumulative\")." -#: ../../source/services.rst:743 +#: ../../source/services.rst:766 msgid "Raven service" msgstr "Raven сервис" -#: ../../source/services.rst:745 +#: ../../source/services.rst:768 msgid "" "Simple service for sending unhandled exceptions to the `sentry`_ service " "instance." msgstr "Простой сервис для отправки необработанных исключений в сервис `sentry`_." -#: ../../source/services.rst:750 +#: ../../source/services.rst:773 msgid "Simple example:" msgstr "Простой пример:" -#: ../../source/services.rst:792 +#: ../../source/services.rst:815 msgid "Full configuration:" msgstr "Все опции для клиента:" -#: ../../source/services.rst:852 +#: ../../source/services.rst:875 msgid "" "You will find the full specification of options in the `Raven " "documentation`_." msgstr "Вы можете найти полное описание параметров в `документации Raven`_." -#: ../../source/services.rst:858 +#: ../../source/services.rst:881 msgid "``SDWatchdogService``" msgstr "``SDWatchdogService``" -#: ../../source/services.rst:860 +#: ../../source/services.rst:883 +#, fuzzy msgid "" -"Service just adding to your entrypoint and notifying SystemD service " -"watchdog timer." +"Ready to use service just adding to your entrypoint and notifying SystemD" +" service watchdog timer." msgstr "" "Просто добавьте этот сервис в entrypoint и он будет отправлять " "уведомления сторожевому таймеру SystemD." -#: ../../source/services.rst:863 +#: ../../source/services.rst:886 msgid "" "This can be safely added at any time, since if the service does not " "detect systemd-related environment variables, then its initialization is " @@ -383,19 +384,19 @@ msgstr "" "найдет переменных окружения, которые устанавливает systemd, Сервис просто" " не запустится, однако выполнение приложения продолжится." -#: ../../source/services.rst:866 +#: ../../source/services.rst:889 msgid "Example of python file:" msgstr "Пример python файла:" -#: ../../source/services.rst:883 +#: ../../source/services.rst:906 msgid "Example of systemd service file:" msgstr "Пример systemd сервис-файла:" -#: ../../source/services.rst:917 +#: ../../source/services.rst:943 msgid "``ProcessService``" msgstr "Класс ``ProcessService``" -#: ../../source/services.rst:919 +#: ../../source/services.rst:945 msgid "" "A base class for launching a function by a separate system process, and " "by termination when the parent process is stopped." @@ -403,11 +404,11 @@ msgstr "" "Базовый класс для запуска функции отдельным системным процессом и " "завершения при остановке родительского процесса." -#: ../../source/services.rst:963 +#: ../../source/services.rst:989 msgid "``RespawningProcessService``" msgstr "Класс ``RespawningProcessService``" -#: ../../source/services.rst:965 +#: ../../source/services.rst:991 msgid "" "A base class for launching a function by a separate system process, and " "by termination when the parent process is stopped, It's pretty like " @@ -418,4 +419,3 @@ msgstr "" "завершения при остановке родительского процесса. Это очень похоже на " "`ProcessService` с одним отличием - если дочерний процесс неожиданно " "завершится, то он будет перезапущен." - diff --git a/docs/source/locale/ru/LC_MESSAGES/tutorial.po b/docs/source/locale/ru/LC_MESSAGES/tutorial.po index 565ba66a..421394b7 100644 --- a/docs/source/locale/ru/LC_MESSAGES/tutorial.po +++ b/docs/source/locale/ru/LC_MESSAGES/tutorial.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 16.1.10\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-04 00:12+0300\n" +"POT-Creation-Date: 2022-12-29 08:23+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/tutorial.rst:2 msgid "Tutorial" @@ -21,13 +21,18 @@ msgstr "Учебник" #: ../../source/tutorial.rst:5 msgid "" -"``aiomisc`` - is a one library collection of utilities that helps you " -"write asynchronous services." +"``aiomisc`` is a Python library that provides a set of utilities for " +"building asynchronous services. It allows you to split your program into " +"smaller, independent services that can run concurrently, improving the " +"overall performance and scalability of your application." msgstr "" -"``aiomisc`` - это набор утилит в одной библиотеке, которые помогают вам " -"писать асинхронные сервисы." +"``aiomisc`` — это библиотека Python, которая предоставляет набор утилит " +"для создание асинхронных сервисов. Это позволяет вам разделить вашу " +"программу на небольшие независимые службы, которые могут работать " +"одновременно, улучшая общую производительность и масштабируемость вашего " +"приложения." -#: ../../source/tutorial.rst:8 +#: ../../source/tutorial.rst:10 msgid "" "The main approach in this library is to split your program into " "independent services that can work concurrently in asynchronous mode. The" @@ -39,7 +44,7 @@ msgstr "" "режиме. Библиотека также предоставляет набор готовых к использованию " "сервисов с заранее написанной логикой запуска и остановки." -#: ../../source/tutorial.rst:12 +#: ../../source/tutorial.rst:14 msgid "" "The vast majority of functions and classes are written in such a way that" " they can be used in a program that was not originally designed according" @@ -55,10 +60,18 @@ msgstr "" "все должно работать." #: ../../source/tutorial.rst:20 +msgid "" +"Overall, aiomisc is a powerful tool for developers looking to build " +"efficient and scalable asynchronous services in Python." +msgstr "" +"В целом, aiomisc — это мощный инструмент для разработчиков, стремящихся " +"создавать эффективные и масштабируемые асинхронные сервисы на Python." + +#: ../../source/tutorial.rst:24 msgid "Services" msgstr "Сервисы" -#: ../../source/tutorial.rst:22 +#: ../../source/tutorial.rst:26 msgid "" "If you want to run a tcp or web server, you will have to write something " "like this:" @@ -66,7 +79,7 @@ msgstr "" "Если вы хотите запустить tcp или веб-сервер, вам придется написать что-то" " вроде этого:" -#: ../../source/tutorial.rst:41 +#: ../../source/tutorial.rst:45 msgid "" "In order to start or stop an async programs, usually using function " "``asyncio.run(example_async_func())`` which available since Python 3.7. " @@ -81,7 +94,7 @@ msgstr "" "Чтобы продолжить выполнение кода вечно, вы можете применить следующий " "трюк:" -#: ../../source/tutorial.rst:66 +#: ../../source/tutorial.rst:70 msgid "" "When the user presses `Ctrl+C`, the program simply terminates, but if you" " want to explicitly free up some resources, for example, close database " @@ -93,7 +106,7 @@ msgstr "" "соединения с базой данных или откатить незавершенные транзакции, то вам " "нужно сделать что-то вроде этого:" -#: ../../source/tutorial.rst:96 +#: ../../source/tutorial.rst:100 msgid "" "It is a good solution because it is implemented without any 3rd-party " "libraries. When your program starts to grow, you will probably want to " @@ -107,7 +120,7 @@ msgstr "" "инициализацию конкурентно. На первый взгляд кажется, что этот код решит " "проблему:" -#: ../../source/tutorial.rst:128 +#: ../../source/tutorial.rst:132 msgid "" "But if suddenly some part of the initialization does not go according to " "plan, then you somehow have to figure out what exactly went wrong, so " @@ -119,7 +132,7 @@ msgstr "" "конкурентном выполнении код уже не будет таким простым, как в этом " "примере." -#: ../../source/tutorial.rst:132 +#: ../../source/tutorial.rst:136 msgid "" "And in order to somehow organize the code, you should make a separate " "function that will contain the ``try/except/finally`` block and contain " @@ -129,7 +142,7 @@ msgstr "" "функцию, которая будет содержать блок ``try/except/finally`` и содержать " "обработку ошибок." -#: ../../source/tutorial.rst:172 +#: ../../source/tutorial.rst:176 msgid "" "And now if the user presses Ctrl+C, you need to describe the shutdown " "logic again, but now in the ``except`` block." @@ -137,7 +150,7 @@ msgstr "" "И теперь, если пользователь нажимает Ctrl+C, вам нужно снова описать " "логику завершения работы, но уже в блоке ``except``." -#: ../../source/tutorial.rst:175 +#: ../../source/tutorial.rst:179 msgid "" "In order to describe the logic of starting and stopping in one place, as " "well as testing in one single way, there is a ``Service`` abstraction." @@ -146,7 +159,7 @@ msgstr "" " тестирования одним-единственным способом, и существует абстракция " "``Service``." -#: ../../source/tutorial.rst:178 +#: ../../source/tutorial.rst:182 msgid "" "The service is an abstract base class with mandatory ``start()`` and " "optional ``stop()`` methods." @@ -154,7 +167,7 @@ msgstr "" "Сервис представляет из себя абстрактный базовый класс, в котором нужно " "реализовать метод ``start()`` и не обязательно метод ``stop()``" -#: ../../source/tutorial.rst:181 +#: ../../source/tutorial.rst:185 msgid "" "The service can operate in two modes. The first is when the ``start()`` " "method runs forever, then you do not need to implement a ``stop()``, but " @@ -165,7 +178,7 @@ msgstr "" "выполняется вечно, тогда не нужно реализовывать стоп, но нужно сообщить " "что инициализация успешно закончена с помощью ``self.start_event.set()``." -#: ../../source/tutorial.rst:202 +#: ../../source/tutorial.rst:206 msgid "" "In this case, stopping the service will consist in the completion of the " "coroutine that was created by ``start()``." @@ -173,7 +186,7 @@ msgstr "" "В этом случае остановка сервиса будет заключаться в завершении " "сопрограммы которую породила ``start()``" -#: ../../source/tutorial.rst:205 +#: ../../source/tutorial.rst:209 msgid "" "The second method is an explicit description of the way to ``start()`` " "and ``stop()``." @@ -181,15 +194,15 @@ msgstr "" "Второй способ это явное описание способа запуска и остановки реализовав " "методы ``start()`` и ``stop()``" -#: ../../source/tutorial.rst:225 +#: ../../source/tutorial.rst:229 msgid "In this case, the service will be started and stopped once." msgstr "В этом случае запуск и остановка сервиса будут выполнены однократно." -#: ../../source/tutorial.rst:229 +#: ../../source/tutorial.rst:233 msgid "Service configuration" msgstr "Конфигурация сервисов" -#: ../../source/tutorial.rst:231 +#: ../../source/tutorial.rst:235 msgid "" "The ``Service`` is a metaclass, it handles the special attributes of " "classes inherited from it at on the their declaration stage." @@ -197,7 +210,7 @@ msgstr "" "Так как ``Service`` это метакласс, он может обрабатывать специальные " "аттрибуты классов наследуемых от него на этапе объявления класса." -#: ../../source/tutorial.rst:234 +#: ../../source/tutorial.rst:238 msgid "" "Here is a simple imperative example of how service initialization can be " "extended through inheritance." @@ -205,7 +218,7 @@ msgstr "" "Вот простой императивный пример как инициализация сервиса может быть " "расширена через наследование." -#: ../../source/tutorial.rst:260 +#: ../../source/tutorial.rst:264 msgid "" "In fact, you can do nothing of this, since the Service metaclass sets all" " the passed keyword parameters to self by default." @@ -213,7 +226,7 @@ msgstr "" "На самом деле, можно было ничего и не делать, так как метакласс установит" " все переданные именованные параметры в self по умолчанию." -#: ../../source/tutorial.rst:283 +#: ../../source/tutorial.rst:287 msgid "" "If a special class property ``__required__`` is declared, then the " "service will required for the user to declare these named parameters." @@ -222,7 +235,7 @@ msgstr "" "требовать чтобы он был передан явно при инициализации как именованный " "параметр." -#: ../../source/tutorial.rst:305 +#: ../../source/tutorial.rst:309 msgid "" "Also a very useful special class attribute is ``__async_required__``. It " "is useful for writing base classes, in general. This contains the tuple " @@ -234,7 +247,7 @@ msgstr "" "классов. Он содержит кортеж имен методов, которые должны быть явно " "объявлены асинхронными (через ``async def``)." -#: ../../source/tutorial.rst:341 +#: ../../source/tutorial.rst:345 msgid "" "If the inheritor declares these methods differently, there will be an " "error at the class declaration stage." @@ -242,11 +255,11 @@ msgstr "" "Если наследник объявит эти методы по-другому, будет ошибка на этапе " "объявления класса." -#: ../../source/tutorial.rst:356 +#: ../../source/tutorial.rst:360 msgid "dependency injection" msgstr "" -#: ../../source/tutorial.rst:360 +#: ../../source/tutorial.rst:364 msgid "" "In some cases, you need to execute some asynchronous code before the " "service starts, for example, to pass a database connection to the service" @@ -255,10 +268,10 @@ msgid "" msgstr "" "В некоторых случаях перед запуском службы необходимо выполнить некоторый " "асинхронный код, например, чтобы передать соединение с базой данных " -"экземпляру сервиса. Или если вы хотите использовать один экземпляр какой-то " -"сущности для нескольких сервисов." +"экземпляру сервиса. Или если вы хотите использовать один экземпляр " +"какой-то сущности для нескольких сервисов." -#: ../../source/tutorial.rst:364 +#: ../../source/tutorial.rst:368 msgid "" "For such complex configurations, there is `aiomisc-dependency`_ plugin " "which is distributed as a independent separate package." @@ -266,7 +279,7 @@ msgstr "" "Для таких сложных конфигураций существует плагин `aiomisc-dependency`_, " "который распространяется как независимый отдельный пакет." -#: ../../source/tutorial.rst:367 +#: ../../source/tutorial.rst:371 msgid "" "Look at the examples in the documentation, `aiomisc-dependency`_ are " "transparently integrates with the ``entrypoint``." @@ -274,11 +287,11 @@ msgstr "" "Посмотрите на примеры в документации, `aiomisc-dependency`_ прозрачно " "интегрируется с ``entrypoint``." -#: ../../source/tutorial.rst:371 +#: ../../source/tutorial.rst:375 msgid "``entrypoint``" msgstr "" -#: ../../source/tutorial.rst:373 +#: ../../source/tutorial.rst:377 msgid "" "So the service abstraction is declared, what's next? ``asyncio.run`` does" " not know how to work with them, calling them manually has not become " @@ -287,7 +300,7 @@ msgstr "" "Итак сервисы описаны, что дальше? ``asyncio.run`` не умеет с ними " "работать, вызывать их вручную не стало проще, что тут можно предложить?" -#: ../../source/tutorial.rst:377 +#: ../../source/tutorial.rst:381 msgid "" "Probably the most magical, complex, and at the same time quite well-" "tested code in the library is ``entrypoint``. Initially, the idea of " @@ -299,11 +312,11 @@ msgstr "" "``entrypoint`` было избавление от рутины: настройка логов, настройка пула" " потоков, ну и запуск и корректная остановка сервисов." -#: ../../source/tutorial.rst:382 +#: ../../source/tutorial.rst:386 msgid "Lets check an example:" msgstr "Давайте посмотрим на пример:" -#: ../../source/tutorial.rst:397 +#: ../../source/tutorial.rst:401 msgid "" "In this example, we will launch the two services described above and " "continue execution until the user interrupts them. Next, thanks to the " @@ -313,16 +326,17 @@ msgstr "" "выполнение до тех пор пока пользователь его не прервёт. Далее, благодаря " "контекстному менеджеру, мы корректно завершаем все экземпляры сервисов." -#: ../../source/tutorial.rst:403 +#: ../../source/tutorial.rst:407 msgid "" "Entrypoint calls all the ``start()`` methods in all services " "concurrently, and if at least one of them fails, then all services will " "be stopped." msgstr "" "Entrypoint вызывает все методы ``start()`` во всех сервисах конкурентно, " -"и если хотя-бы один из них упадет, все остальные сервисы будут остановлены." +"и если хотя-бы один из них упадет, все остальные сервисы будут " +"остановлены." -#: ../../source/tutorial.rst:406 +#: ../../source/tutorial.rst:410 msgid "" "As mentioned above I just wanted to remove a lot of routine, let's look " "at the same example, just pass all the default parameters to the " @@ -332,7 +346,7 @@ msgstr "" "пример, только передадим явно все параметры по умолчанию в " "``entrypoint``." -#: ../../source/tutorial.rst:433 +#: ../../source/tutorial.rst:437 msgid "" "Let's not describe what each parameter does. But in general, " "``entrypoint`` has create an event-loop, a four threads pool, set it for " @@ -344,7 +358,7 @@ msgstr "" "настроила его для текущего цикла событий, настроила логгер с \"цветным\" " "буферизованным выводом и запустила два сервиса." -#: ../../source/tutorial.rst:438 +#: ../../source/tutorial.rst:442 msgid "" "You can also run the ``entrypoint`` without services, just configure " "logging and so on.:" @@ -352,7 +366,7 @@ msgstr "" "Также вы можете запустить ``entrypoint`` без сервисов, просто " "сконфигурировать логирование и прочее:" -#: ../../source/tutorial.rst:457 +#: ../../source/tutorial.rst:461 msgid "" "It is also worth paying attention to the ``aiomisc.run``, which is " "similar by its purpose to ``asyncio.run`` while supporting the start and " @@ -362,7 +376,7 @@ msgstr "" "назначению на ``asyncio.run`` при этом поддерживает запуск и остановку " "сервисов и прочее." -#: ../../source/tutorial.rst:489 +#: ../../source/tutorial.rst:493 msgid "" "As I mentioned above, the library contains lots of already realized " "abstract services that you can use in your project by simply implement " @@ -372,7 +386,7 @@ msgstr "" "абстрактных сервисов, которые вы можете использовать в своем проекте, " "просто реализовав несколько методов." -#: ../../source/tutorial.rst:493 +#: ../../source/tutorial.rst:497 msgid "" "A full list of services and usage examples can be found on the on the " ":doc:`Services page `." @@ -380,11 +394,11 @@ msgstr "" "Полный список сервисов и примеры их использования можно найти на странице" " :doc:`Сервисы `." -#: ../../source/tutorial.rst:497 +#: ../../source/tutorial.rst:501 msgid "Executing code in thread or process-pools" msgstr "Выполнение кода в пуле потоков или процессов" -#: ../../source/tutorial.rst:501 +#: ../../source/tutorial.rst:505 msgid "" "As explained in `working with threads`_ section in official python " "documentation asyncio event loop starts thread pool." @@ -392,7 +406,7 @@ msgstr "" "Как объясняется в разделе `working with threads`_ в официальной " "документации по Python, eventloop в asyncio запускает пул потоков." -#: ../../source/tutorial.rst:504 +#: ../../source/tutorial.rst:508 msgid "" "This pool is needed in order to run, for example, name resolution and not" " blocks the event loop while low-level ``gethostbyname`` call works." @@ -401,7 +415,7 @@ msgstr "" "блокировать eventloop, пока работает низкоуровневый вызов " "`gethostbyname`." -#: ../../source/tutorial.rst:507 +#: ../../source/tutorial.rst:511 msgid "" "The size of this thread pool should be configured at application startup," " otherwise you may run into all sorts of problems when this pool is too " @@ -411,7 +425,7 @@ msgstr "" "иначе вы можете столкнуться со всевозможными проблемами, когда этот пул " "слишком велик или слишком мал." -#: ../../source/tutorial.rst:511 +#: ../../source/tutorial.rst:515 msgid "" "By default, the ``entrypoint`` creates a thread pool with size equal to " "the number of CPU cores, but not less than 4 and no more than 32 threads." @@ -421,11 +435,11 @@ msgstr "" "количеству ядер процессора (минимум — 4, и максимум — 32). Конечно, вы " "можете указать столько, сколько вам нужно." -#: ../../source/tutorial.rst:516 +#: ../../source/tutorial.rst:520 msgid "``@aiomisc.threaded`` decorator" msgstr "Декоратор ``@aiomisc.threaded``" -#: ../../source/tutorial.rst:518 +#: ../../source/tutorial.rst:522 msgid "" "The following recommendations for calling blocking functions in threads " "given in `working with threads`_ section in official Python " @@ -434,11 +448,11 @@ msgstr "" "В разделе `working with threads`_ официальной документации по python " "даются следующие рекомендации по вызову блокирующих функций в потоках:" -#: ../../source/tutorial.rst:536 +#: ../../source/tutorial.rst:540 msgid "This library provides a very simple way to do the same:" msgstr "Эта библиотека содержит очень простой способ сделать тоже самое:" -#: ../../source/tutorial.rst:552 +#: ../../source/tutorial.rst:556 msgid "" "As you can see in this example, it is enough to wrap the function with a " "decorator ``aiomisc.threaded``, after that it will return an awaitable " @@ -449,11 +463,11 @@ msgstr "" "``aiomisc.threaded``, и она начнет возвращать awaitable объект, но код " "внутри функции будет отправлен в пул потоков по умолчанию." -#: ../../source/tutorial.rst:558 +#: ../../source/tutorial.rst:562 msgid "``@aiomisc.threaded_separate`` decorator" msgstr "Декоратор ``@aiomisc.threaded_separate``" -#: ../../source/tutorial.rst:560 +#: ../../source/tutorial.rst:564 msgid "" "If the blocking function runs for a long time, or even indefinitely, in " "other words, if the cost of creating a thread is insignificant compared " @@ -465,7 +479,7 @@ msgstr "" "сколько функция работает, то можно попробовать использовать декоратор " "``aiomisc.threaded_separate``." -#: ../../source/tutorial.rst:564 +#: ../../source/tutorial.rst:568 msgid "" "The decorator starts a new thread not associated with any pool. Тhe " "thread will be terminated after the function execution is done." @@ -473,7 +487,7 @@ msgstr "" "Декоратор запускает новый поток, не связанный с каким-либо пулом потоков." " Поток завершится после выхода из функции." -#: ../../source/tutorial.rst:591 +#: ../../source/tutorial.rst:595 msgid "" "This approach allows you not to occupy threads in the pool for a long " "time, but at the same time does not limit the number of created threads " @@ -482,15 +496,15 @@ msgstr "" "Такой подход позволяет не занимать потоки в пуле надолго, но при этом " "никак не ограничивает количество создаваемых потоков." -#: ../../source/tutorial.rst:595 +#: ../../source/tutorial.rst:599 msgid "More examples you can be found in :doc:`/threads`." msgstr "Больше примеров можно найти на странице :doc:`/threads`" -#: ../../source/tutorial.rst:598 +#: ../../source/tutorial.rst:602 msgid "``@aiomisc.threaded_iterable`` decorator" msgstr "Декоратор ``@aiomisc.threaded_iterable``" -#: ../../source/tutorial.rst:600 +#: ../../source/tutorial.rst:604 msgid "" "If a generator needs to be executed in a thread, there are problems with " "synchronization of the thread and the eventloop. This library provides a " @@ -502,7 +516,7 @@ msgstr "" "пользовательский декоратор, предназначенный для превращения синхронного " "генератора в асинхронный." -#: ../../source/tutorial.rst:605 +#: ../../source/tutorial.rst:609 msgid "" "This is very useful if, for example, a queue or database driver has " "written synchronous, but you want to use it efficiently in asynchronous " @@ -511,7 +525,7 @@ msgstr "" "Это очень полезно, если, например, драйвер очереди или базы данных " "синхронный, но вы хотите эффективно использовать его в асинхронном коде." -#: ../../source/tutorial.rst:628 +#: ../../source/tutorial.rst:632 msgid "" "Under the hood, this decorator returns a special object that has a queue," " and asynchronous iterator interface provides access to that queue." @@ -519,7 +533,7 @@ msgstr "" "Под капотом этот декоратор возвращает специальный объект с очередью, а " "интерфейс асинхронного итератора обеспечивает доступ к этой очереди." -#: ../../source/tutorial.rst:631 +#: ../../source/tutorial.rst:635 msgid "" "You should always specify the ``max_size`` parameter, which limits the " "size of this queue and prevents threaded code from sending too much items" @@ -531,4 +545,3 @@ msgstr "" "потоке, слишком большого количества элементов в асинхронный код, в случае" " асинхронной итерации в случае, если асинхронный итератор забирает " "элементы из этой очереди реже чем они поступают." - diff --git a/docs/source/services.rst b/docs/source/services.rst index e1795e3e..3f8e096a 100644 --- a/docs/source/services.rst +++ b/docs/source/services.rst @@ -49,6 +49,9 @@ and after that, all running tasks will be canceled (including ``start()``). This package contains some useful base classes for simple services writing. + +.. _tcp-server: + ``TCPServer`` +++++++++++++ @@ -94,6 +97,8 @@ Just implement ``handle_client(reader, writer)`` to use it. loop.run_until_complete(echo_client("::1", 8901)) +.. _udp-server: + ``UDPServer`` +++++++++++++ @@ -138,6 +143,8 @@ Just implement ``handle_client(reader, writer)`` to use it. loop.run_forever() +.. _tcp-client: + ``TCPClient`` +++++++++++++ @@ -349,6 +356,9 @@ Just implement ``handle_connection(reader, writer)`` to use it. ) as loop: loop.run_until_complete(asyncio.sleep(0.1)) + +.. _periodic-service: + ``PeriodicService`` +++++++++++++++++++ @@ -377,16 +387,18 @@ optional ``delay`` argument - periodic execution delay in seconds (0 by default) loop.run_forever() +.. _cron-service: + ``CronService`` +++++++++++++++ -.. _croniter: https://github.com/taichino/croniter - ``CronService`` runs ``CronCallback's`` as a service and waits for running callbacks to complete on the stop method. It's based on croniter_. You can register async coroutine method with ``spec`` argument - cron like format: +.. _croniter: https://github.com/taichino/croniter + .. warning:: requires installed croniter_: @@ -524,6 +536,8 @@ to ``self`` as attributes. loop.run_forever() +.. _aiohttp-service: + aiohttp service +++++++++++++++ @@ -588,6 +602,8 @@ Class ``AIOHTTPSSLService`` is similar to ``AIOHTTPService`` but creates an HTTP server. You must pass SSL-required options (see ``TLSServer`` class). +.. _asgi-service: + asgi service ++++++++++++ @@ -649,6 +665,9 @@ Any ASGI-like application can be started as a service: Class ``ASGIHTTPSSLService`` is similar to ``ASGIHTTPService`` but creates HTTPS server. You must pass SSL-required options (see ``TLSServer`` class). + +.. _memory-tracer: + Memory Tracer +++++++++++++ @@ -697,6 +716,8 @@ Output example: 14 | 14 | 2.4KiB | 2.4KiB | aiomisc/periodic.py:40 +.. _profiler: + Profiler ++++++++ @@ -739,6 +760,8 @@ Output example: 1 0.000 0.000 0.000 0.000 <...>/lib/python3.7/cProfile.py:50(create_stats) +.. _raven-service: + Raven service +++++++++++++ @@ -857,7 +880,7 @@ You will find the full specification of options in the `Raven documentation`_. ``SDWatchdogService`` +++++++++++++++++++++ -Service just adding to your entrypoint and notifying SystemD +Ready to use service just adding to your entrypoint and notifying SystemD service watchdog timer. This can be safely added at any time, since if the service does not detect @@ -913,6 +936,9 @@ Example of systemd service file: FinalKillSignal=SIGKILL SendSIGKILL=yes + +.. _process-service: + ``ProcessService`` ++++++++++++++++++ @@ -987,4 +1013,3 @@ unexpectedly exited this will be respawned. if __name__ == '__main__': with aiomisc.entrypoint(SuicideService()) as loop: loop.run_forever() - diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst index ec999eed..b42438ab 100644 --- a/docs/source/tutorial.rst +++ b/docs/source/tutorial.rst @@ -2,8 +2,10 @@ Tutorial ======== -``aiomisc`` - is a one library collection of utilities that helps -you write asynchronous services. +``aiomisc`` is a Python library that provides a set of utilities for building +asynchronous services. It allows you to split your program into smaller, +independent services that can run concurrently, improving the overall +performance and scalability of your application. The main approach in this library is to split your program into independent services that can work concurrently in asynchronous mode. The library also @@ -15,6 +17,8 @@ to the principles outlined in this manual. This means that if you don't plan to modify your code too much, but only use a few useful functions or classes, then everything should work. +Overall, aiomisc is a powerful tool for developers looking to build efficient +and scalable asynchronous services in Python. Services ++++++++ diff --git a/poetry.lock b/poetry.lock index f93c02de..79a14056 100644 --- a/poetry.lock +++ b/poetry.lock @@ -112,6 +112,18 @@ docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +[[package]] +name = "autodoc" +version = "0.5.0" +description = "Autodoc Python implementation." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +decorator = "*" +webtest = "*" + [[package]] name = "autoflake" version = "1.4" @@ -134,6 +146,21 @@ python-versions = ">=3.6" [package.dependencies] pytz = ">=2015.7" +[[package]] +name = "beautifulsoup4" +version = "4.11.1" +description = "Screen-scraping library" +category = "dev" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + [[package]] name = "certifi" version = "2022.12.7" @@ -258,6 +285,14 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] python-dateutil = "*" +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +category = "dev" +optional = false +python-versions = ">=3.5" + [[package]] name = "distlib" version = "0.3.6" @@ -342,6 +377,20 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "furo" +version = "2022.12.7" +description = "A clean customisable Sphinx documentation theme." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +beautifulsoup4 = "*" +pygments = ">=2.7" +sphinx = ">=5.0,<7.0" +sphinx-basic-ng = "*" + [[package]] name = "identify" version = "2.5.11" @@ -825,6 +874,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "soupsieve" +version = "2.3.2.post1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "sphinx" version = "5.3.0" @@ -873,6 +930,20 @@ sphinx = "*" [package.extras] test = ["pytest", "pytest-cov"] +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b1" +description = "A modern skeleton for Sphinx themes." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +sphinx = ">=4.0" + +[package.extras] +docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"] + [[package]] name = "sphinx-intl" version = "2.0.1" @@ -1085,6 +1156,47 @@ platformdirs = ">=2.4,<3" docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] +[[package]] +name = "waitress" +version = "2.1.2" +description = "Waitress WSGI server" +category = "dev" +optional = false +python-versions = ">=3.7.0" + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] +testing = ["coverage (>=5.0)", "pytest", "pytest-cover"] + +[[package]] +name = "webob" +version = "1.8.7" +description = "WSGI request and response object" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" + +[package.extras] +docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] +testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "webtest" +version = "3.0.0" +description = "Helper to test WSGI applications" +category = "dev" +optional = false +python-versions = ">=3.6, <4" + +[package.dependencies] +beautifulsoup4 = "*" +waitress = ">=0.8.5" +WebOb = ">=1.2" + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.8)"] +tests = ["PasteDeploy", "WSGIProxy2", "coverage", "pyquery", "pytest", "pytest-cov"] + [[package]] name = "yarl" version = "1.8.2" @@ -1116,12 +1228,13 @@ asgi = [] carbon = [] cron = [] raven = [] +rich = [] uvloop = [] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "e7d96179f1acc89c2737b91f845f0f348c4a9db025054e7e77a6f23ab83d3761" +content-hash = "66f7693da6c5fadd973d50b2d381906ff979d1781e560713d7d27819dce04333" [metadata.files] aiocontextvars = [ @@ -1245,6 +1358,9 @@ attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] +autodoc = [ + {file = "autodoc-0.5.0.tar.gz", hash = "sha256:c4387c5a0f1c09b055bb2e384542ee1e016542f313b2a33d904ca77f0460ded3"}, +] autoflake = [ {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, ] @@ -1252,6 +1368,10 @@ babel = [ {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, ] +beautifulsoup4 = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, +] certifi = [ {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, @@ -1343,6 +1463,10 @@ croniter = [ {file = "croniter-1.3.8-py2.py3-none-any.whl", hash = "sha256:d6ed8386d5f4bbb29419dc1b65c4909c04a2322bd15ec0dc5b2877bfa1b75c7a"}, {file = "croniter-1.3.8.tar.gz", hash = "sha256:32a5ec04e97ec0837bcdf013767abd2e71cceeefd3c2e14c804098ce51ad6cd9"}, ] +decorator = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] distlib = [ {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, @@ -1446,6 +1570,10 @@ frozenlist = [ {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, ] +furo = [ + {file = "furo-2022.12.7-py3-none-any.whl", hash = "sha256:7cb76c12a25ef65db85ab0743df907573d03027a33631f17d267e598ebb191f7"}, + {file = "furo-2022.12.7.tar.gz", hash = "sha256:d8008f8efbe7587a97ba533c8b2df1f9c21ee9b3e5cad0d27f61193d38b1a986"}, +] identify = [ {file = "identify-2.5.11-py2.py3-none-any.whl", hash = "sha256:e7db36b772b188099616aaf2accbee122949d1c6a1bac4f38196720d6f9f06db"}, {file = "identify-2.5.11.tar.gz", hash = "sha256:14b7076b29c99b1b0b8b08e96d448c7b877a9b07683cd8cfda2ea06af85ffa1c"}, @@ -1876,6 +2004,10 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] +soupsieve = [ + {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, + {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, +] sphinx = [ {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"}, {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"}, @@ -1884,6 +2016,10 @@ sphinx-autobuild = [ {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, ] +sphinx-basic-ng = [ + {file = "sphinx_basic_ng-1.0.0b1-py3-none-any.whl", hash = "sha256:ade597a3029c7865b24ad0eda88318766bcc2f9f4cef60df7e28126fde94db2a"}, + {file = "sphinx_basic_ng-1.0.0b1.tar.gz", hash = "sha256:89374bd3ccd9452a301786781e28c8718e99960f2d4f411845ea75fc7bb5a9b0"}, +] sphinx-intl = [ {file = "sphinx-intl-2.0.1.tar.gz", hash = "sha256:b25a6ec169347909e8d983eefe2d8adecb3edc2f27760db79b965c69950638b4"}, ] @@ -2017,6 +2153,18 @@ virtualenv = [ {file = "virtualenv-20.17.1-py3-none-any.whl", hash = "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4"}, {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, ] +waitress = [ + {file = "waitress-2.1.2-py3-none-any.whl", hash = "sha256:7500c9625927c8ec60f54377d590f67b30c8e70ef4b8894214ac6e4cad233d2a"}, + {file = "waitress-2.1.2.tar.gz", hash = "sha256:780a4082c5fbc0fde6a2fcfe5e26e6efc1e8f425730863c04085769781f51eba"}, +] +webob = [ + {file = "WebOb-1.8.7-py2.py3-none-any.whl", hash = "sha256:73aae30359291c14fa3b956f8b5ca31960e420c28c1bec002547fb04928cf89b"}, + {file = "WebOb-1.8.7.tar.gz", hash = "sha256:b64ef5141be559cfade448f044fa45c2260351edcb6a8ef6b7e00c7dcef0c323"}, +] +webtest = [ + {file = "WebTest-3.0.0-py3-none-any.whl", hash = "sha256:2a001a9efa40d2a7e5d9cd8d1527c75f41814eb6afce2c3d207402547b1e5ead"}, + {file = "WebTest-3.0.0.tar.gz", hash = "sha256:54bd969725838d9861a9fa27f8d971f79d275d94ae255f5c501f53bb6d9929eb"}, +] yarl = [ {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5"}, {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:47d49ac96156f0928f002e2424299b2c91d9db73e08c4cd6742923a086f1c863"}, diff --git a/pyproject.toml b/pyproject.toml index fc8a5882..3ab6cc2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,6 @@ [tool.poetry] name = "aiomisc" +# This is a dummy version which will be rewritten with poem-plugins version = "16.3.0" description = "aiomisc - miscellaneous utils for asyncio" authors = ["Dmitry Orlov "] @@ -66,6 +67,8 @@ timeout-decorator = "^0.5.0" types-croniter = "^1.3" types-setuptools = "^65.6.0.1" pylama = "^8.4.1" +furo = "^2022.12.7" +autodoc = "^0.5.0" [tool.poetry.group.uvloop.dependencies] uvloop = "^0.17.0" @@ -77,14 +80,20 @@ aiomisc = "aiomisc_pytest.pytest_plugin" aiohttp = ["aiohttp"] asgi = ["aiohttp-asgi~=0.4.3"] carbon = ["aiocarbon~=0.15"] +cron = ["croniter~=1.3.8"] raven = ["aiohttp', 'raven"] +rich = ["rich"] uvloop = ["uvloop>=0.14,<1"] -cron = ["croniter~=1.3.8"] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" +[tool.poem-plugins.version] +provider = "git" +update_pyproject = true +write_version_file = true + [tool.mypy] check_untyped_defs = true disallow_any_generics = false @@ -106,7 +115,6 @@ files = [ "tests", ] - [[tool.mypy.overrides]] module = ["tests.*"] check_untyped_defs = true From 2c605e2dca5bd5db380433f49535ee48e19c475d Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 29 Dec 2022 09:02:59 +0300 Subject: [PATCH 31/45] rework publish action --- .github/workflows/publish.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6c03b53f..506c4e31 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,6 +1,3 @@ -# This workflow will install Python dependencies, run tests and lint with a single version of Python -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - name: publish on: @@ -27,17 +24,16 @@ jobs: - name: Resetting git to master run: git fetch --unshallow --tags || true - - name: Bump package version - run: python3 bump.py aiomisc/version.py + - name: Install poetry + run: python3 -m pip install poetry - - name: Install requires - run: python3 -m pip install twine wheel + - name: Install poem-plugins + run: poetry self add poem-plugins - - name: Build source package - run: python3 setup.py sdist bdist_wheel + - name: Install package + run: poetry install - name: Publishing to pypi - run: twine upload --skip-existing --disable-progress-bar dist/*.tar.gz dist/*.whl + run: poetry publish --build env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} + POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} From 192cf297a24f934beff823ff0e851ec14906a9ac Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 29 Dec 2022 13:06:30 +0300 Subject: [PATCH 32/45] improve docs --- LICENSE.md => COPYING | 3 +- MANIFEST.in | 5 - Makefile | 53 +- aiomisc/version.py | 4 +- docs/source/conf.py | 1 + docs/source/index.rst | 54 +- .../source/locale/ru/LC_MESSAGES/aggregate.po | 43 +- .../locale/ru/LC_MESSAGES/aiomisc.log.po | 15 +- .../locale/ru/LC_MESSAGES/api/aiomisc.po | 518 +++++---- .../locale/ru/LC_MESSAGES/api/aiomisc_log.po | 10 +- .../locale/ru/LC_MESSAGES/async_backoff.po | 147 ++- .../locale/ru/LC_MESSAGES/circuit_breaker.po | 192 ++- docs/source/locale/ru/LC_MESSAGES/context.po | 83 +- .../locale/ru/LC_MESSAGES/entrypoint.po | 305 ++++- docs/source/locale/ru/LC_MESSAGES/index.po | 248 ++-- docs/source/locale/ru/LC_MESSAGES/io.po | 75 +- docs/source/locale/ru/LC_MESSAGES/logging.po | 175 ++- docs/source/locale/ru/LC_MESSAGES/plugins.po | 44 +- docs/source/locale/ru/LC_MESSAGES/pool.po | 43 +- .../locale/ru/LC_MESSAGES/process_pool.po | 35 +- docs/source/locale/ru/LC_MESSAGES/pytest.po | 421 ++++++- docs/source/locale/ru/LC_MESSAGES/services.po | 1035 ++++++++++++++++- docs/source/locale/ru/LC_MESSAGES/signal.po | 55 +- .../source/locale/ru/LC_MESSAGES/statistic.po | 41 +- docs/source/locale/ru/LC_MESSAGES/threads.po | 616 +++++++++- docs/source/locale/ru/LC_MESSAGES/timeout.po | 14 +- docs/source/locale/ru/LC_MESSAGES/tutorial.po | 706 ++++++++++- docs/source/locale/ru/LC_MESSAGES/utils.po | 266 ++++- .../locale/ru/LC_MESSAGES/worker_pool.po | 159 ++- docs/source/tutorial.rst | 9 + poetry.toml | 5 + pyproject.toml | 2 +- 32 files changed, 4915 insertions(+), 467 deletions(-) rename LICENSE.md => COPYING (95%) delete mode 100644 MANIFEST.in create mode 100644 poetry.toml diff --git a/LICENSE.md b/COPYING similarity index 95% rename from LICENSE.md rename to COPYING index 8f269006..ba25bccd 100644 --- a/LICENSE.md +++ b/COPYING @@ -1,7 +1,7 @@ The MIT License (MIT) ===================== -Copyright © `2020` `Dmitry Orlov ` +Copyright © 2022 Dmitry Orlov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -23,4 +23,3 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index abd538e4..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -include README.rst -include aiomisc/py.typed -include requirements.dev.txt -include requirements.txt -recursive-exclude tests *.* diff --git a/Makefile b/Makefile index df3a20d4..6ed7c688 100644 --- a/Makefile +++ b/Makefile @@ -3,50 +3,59 @@ all: bump clean sdist test upload NAME:=$(shell poetry version -n | awk '{print $1}') VERSION:=$(shell poetry version -n | awk '{print $2}') +clean: + rm -vrf *.egg-info dist build + bump: poetry build + +install: + poetry install + + +upload: clean sdist + poetry publish + + +.venv/bin/python: install +.venv: .venv/bin/python + + uml: - docker run --rm -v $(shell pwd):/mnt hrektts/plantuml \ + docker run --rm -v $(shell pwd):/mnt -w /mnt hrektts/plantuml \ java -jar /usr/local/share/java/plantuml.jar \ - -tsvg -o /mnt/docs/source/_static '/mnt/resources/uml/*/**.puml' + -tsvg -o docs/source/_static 'resources/uml/*/**.puml' sdist: bump uml rm -fr dist python3 setup.py sdist bdist_wheel -upload: clean sdist - twine upload dist/* - -test: - tox -test-docker: - docker run --rm -i -v $(shell pwd):/mnt -w /mnt \ - snakepacker/python:all tox --workdir /tmp +test: .venv + poetry run pytest -vv -clean: - rm -fr *.egg-info .tox dist build develop: clean - python3 -m venv .venv - .venv/bin/pip install pre-commit gray pylava - .venv/bin/pre-commit install - .venv/bin/pip install -Ue '.' - .venv/bin/pip install -Ue '.[develop]' + poetry install + poetry run pre-commit install + mypy: - mypy aiomisc aiomisc_log aiomisc_worker + poetry run mypy + -translate: bump +reformat: + poetry run gray aiomisc* + + +translate: .venv make -C docs/ gettext sphinx-intl update -p docs/build/gettext -l ru -d docs/source/locale + docs: translate make -C docs/ -e BUILDDIR="build/en" html make -C docs/ -e SPHINXOPTS="-D language='ru'" -e BUILDDIR="build/ru" html python -m webbrowser -t "file://$(shell pwd)/docs/build/en/html/index.html" python -m webbrowser -t "file://$(shell pwd)/docs/build/ru/html/index.html" - -gray: - gray aiomisc* diff --git a/aiomisc/version.py b/aiomisc/version.py index b819a46a..01b3e0a0 100644 --- a/aiomisc/version.py +++ b/aiomisc/version.py @@ -1,5 +1,5 @@ # THIS FILE WAS GENERATED BY "poem_plugins.general.version.drivers.git.GitVersionDriver" # NEWER EDIT THIS FILE MANUALLY -version_info = (16, 3, 0) -__version__ = "16.3.0" +version_info = (16, 3, 2) +__version__ = "16.3.2" diff --git a/docs/source/conf.py b/docs/source/conf.py index cbc58947..80078af9 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -244,3 +244,4 @@ locale_dirs = ["locale/"] # path is example but recommended. gettext_compact = False # optional. +gettext_additional_targets = ["literal-block"] diff --git a/docs/source/index.rst b/docs/source/index.rst index 0ec82a18..6c5237d1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -42,7 +42,7 @@ and retry mechanisms such as :doc:`asyncbackoff ` and :ref:`asyncretry ` to make your asyncio code more robust and easier to maintain. In this documentation, we'll take a closer look at what ``aiomisc`` has to offer and how it can help you streamline your asyncio -development. +service development. Installation ------------ @@ -85,23 +85,23 @@ With aiohttp_: Complete table of extras bellow: -+-----------------------------------+-------------------+------------------------------------------------+ -| example | dependencies | description | -+===================================+===================+================================================+ -| ``pip install aiomisc[aiohttp]`` | ``aiohttp`` | For running aiohttp_ applications. | -+-----------------------------------+-------------------+------------------------------------------------+ -| ``pip install aiomisc[asgi]`` | ``aiohttp-asgi`` | For running ASGI_ applications | -+-----------------------------------+-------------------+------------------------------------------------+ -| ``pip install aiomisc[carbon]`` | ``aiocarbon`` | Sending metrics to carbon_ (part of graphite_) | -+-----------------------------------+-------------------+------------------------------------------------+ -| ``pip install aiomisc[cron]`` | ``croniter`` | use croniter_ for sheduling tasks | -+-----------------------------------+-------------------+------------------------------------------------+ -| ``pip install aiomisc[raven]`` | ``raven`` | Sending exceptions to sentry_ using raven_ | -+-----------------------------------+-------------------+------------------------------------------------+ -| ``pip install aiomisc[rich]`` | ``rich`` | You might using rich_ for logging | -+-----------------------------------+-------------------+------------------------------------------------+ -| ``pip install aiomisc[uvloop]`` | ``uvloop`` | use uvloop_ as a default event loop | -+-----------------------------------+-------------------+------------------------------------------------+ ++-----------------------------------+------------------------------------------------+ +| example | description | ++===================================+================================================+ +| ``pip install aiomisc[aiohttp]`` | For running aiohttp_ applications. | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[asgi]`` | For running ASGI_ applications | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[carbon]`` | Sending metrics to carbon_ (part of graphite_) | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[cron]`` | use croniter_ for sheduling tasks | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[raven]`` | Sending exceptions to sentry_ using raven_ | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[rich]`` | You might using rich_ for logging | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[uvloop]`` | use uvloop_ as a default event loop | ++-----------------------------------+------------------------------------------------+ .. _ASGI: https://asgi.readthedocs.io/en/latest/ .. _PyPI: https://pypi.org/ @@ -114,6 +114,13 @@ Complete table of extras bellow: .. _sentry: https://sentry.io/ .. _uvloop: https://pypi.org/project/uvloop +You can combine extras values by separating them with commas, for example: + +.. code-block:: bash + + pip3 install "aiomisc[aiohttp,cron,rich,uvloop]" + + Quick Start ----------- @@ -293,16 +300,19 @@ How to develop? Should be installed: -* `virtualenv` -* GNU Make as `make` -* Python 3.7+ as `python3` +* ``virtualenv`` +* GNU Make as ``make`` +* Python 3.7+ as ``python3`` +* Installed Poetry_ as ``poetry`` + +.. _Poetry: https://python-poetry.org/docs/ For setting up developer environment just type .. code-block:: - make develop + poetry install .. _Semantic Versioning: http://semver.org/ diff --git a/docs/source/locale/ru/LC_MESSAGES/aggregate.po b/docs/source/locale/ru/LC_MESSAGES/aggregate.po index 88a9a038..0a7e7217 100644 --- a/docs/source/locale/ru/LC_MESSAGES/aggregate.po +++ b/docs/source/locale/ru/LC_MESSAGES/aggregate.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 12.1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-03 16:54+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Tzoiker tzoiker@gmail.com\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\@n" #: ../../source/aggregate.rst:2 msgid "``@aiomisc.aggregate``" @@ -70,6 +70,23 @@ msgstr "" " с 10% увеличением задержки (до 110 ms) количество запросов к БД упадёт в" " 10 раз (до 100 QPS) " +#: ../../source/aggregate.rst:27 +msgid "" +"import asyncio\n" +"import math\n" +"from aiomisc import aggregate, entrypoint\n" +"\n" +"@aggregate(leeway_ms=10, max_count=2)\n" +"async def pow(*nums: float, power: float = 2.0):\n" +" return [math.pow(num, power) for num in nums]\n" +"\n" +"async def main():\n" +" await asyncio.gather(pow(1.0), pow(2.0))\n" +"\n" +"with entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + #: ../../source/aggregate.rst:44 msgid "" "To employ a more low-level approach one can use `aggregate_async` " @@ -84,6 +101,22 @@ msgstr "" "`value` и футуру `future`. Функция ответственна за выставление " "результатов работы для всех футур (вместо обычного возврата результатов)." -#~ msgid "Aggregate decorator" -#~ msgstr "" - +#: ../../source/aggregate.rst:49 +msgid "" +"import asyncio\n" +"import math\n" +"from aiomisc import aggregate_async, entrypoint\n" +"from aiomisc.aggregate import Arg\n" +"\n" +"\n" +"@aggregate_async(leeway_ms=10, max_count=2)\n" +"async def pow(*args: Arg, power: float = 2.0):\n" +" for arg in args:\n" +" arg.future.set_result(math.pow(arg.value, power))\n" +"\n" +"async def main():\n" +" await asyncio.gather(pow(1), pow(2))\n" +"\n" +"with entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/aiomisc.log.po b/docs/source/locale/ru/LC_MESSAGES/aiomisc.log.po index 3f6f0166..f424258d 100644 --- a/docs/source/locale/ru/LC_MESSAGES/aiomisc.log.po +++ b/docs/source/locale/ru/LC_MESSAGES/aiomisc.log.po @@ -17,30 +17,29 @@ msgstr "" #: ../../source/aiomisc.log.rst:2 msgid "aiomisc.log package" -msgstr "" +msgstr "Пакет aiomisc.log" #: ../../source/aiomisc.log.rst:5 msgid "Subpackages" -msgstr "" +msgstr "Подпакеты" #: ../../source/aiomisc.log.rst:13 msgid "Submodules" -msgstr "" +msgstr "Подмодули" #: aiomisc.log.enum.DateFormat:1 of msgid "Bases: :class:`enum.Enum`" -msgstr "" +msgstr "Базовый класс: :class:`enum.Enum`" #: aiomisc.log.enum.DateFormat:1 aiomisc.log.enum.LogFormat:1 #: aiomisc.log.enum.LogLevel:1 of msgid "An enumeration." -msgstr "" +msgstr "Перечисление" #: aiomisc.log.enum.LogFormat:1 aiomisc.log.enum.LogLevel:1 of msgid "Bases: :class:`enum.IntEnum`" -msgstr "" +msgstr "Базовый класс: :class:`enum.IntEnum`" #: ../../source/aiomisc.log.rst:34 msgid "Module contents" -msgstr "" - +msgstr "Содержимое модуля" diff --git a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po index e34302a0..b00a0449 100644 --- a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po +++ b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 16.1.16\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-03 19:00+0300\n" +"POT-Creation-Date: 2022-12-29 11:05+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/api/aiomisc.rst:2 msgid "``aiomisc`` module" @@ -223,12 +223,6 @@ msgstr "" msgid "minimum time in passing state (seconds)" msgstr "" -#: aiomisc.circuit_breaker.CircuitBreakerStates:1 -#: aiomisc.circuit_breaker.CounterKey:1 aiomisc_log.enum.LogFormat:1 -#: aiomisc_log.enum.LogLevel:1 of -msgid "An enumeration." -msgstr "" - #: ../../source/api/aiomisc.rst:26 msgid "``aiomisc.compat`` module" msgstr "Модуль ``aiomisc.compat``" @@ -313,237 +307,6 @@ msgstr "" msgid "``aiomisc.io`` module" msgstr "Модуль ``aiomisc.io``" -#: io.open:1 of -msgid "Open file and return a stream. Raise OSError upon failure." -msgstr "Модуль " - -#: io.open:3 of -msgid "" -"file is either a text or byte string giving the name (and the path if the" -" file isn't in the current working directory) of the file to be opened or" -" an integer file descriptor of the file to be wrapped. (If a file " -"descriptor is given, it is closed when the returned I/O object is closed," -" unless closefd is set to False.)" -msgstr "" - -#: io.open:9 of -msgid "" -"mode is an optional string that specifies the mode in which the file is " -"opened. It defaults to 'r' which means open for reading in text mode. " -"Other common values are 'w' for writing (truncating the file if it " -"already exists), 'x' for creating and writing to a new file, and 'a' for " -"appending (which on some Unix systems, means that all writes append to " -"the end of the file regardless of the current seek position). In text " -"mode, if encoding is not specified the encoding used is platform " -"dependent: locale.getpreferredencoding(False) is called to get the " -"current locale encoding. (For reading and writing raw bytes use binary " -"mode and leave encoding unspecified.) The available modes are:" -msgstr "" - -#: io.open:21 of -msgid "Character" -msgstr "" - -#: io.open:21 of -msgid "Meaning" -msgstr "" - -#: io.open:23 of -msgid "'r'" -msgstr "" - -#: io.open:23 of -msgid "open for reading (default)" -msgstr "" - -#: io.open:24 of -msgid "'w'" -msgstr "" - -#: io.open:24 of -msgid "open for writing, truncating the file first" -msgstr "" - -#: io.open:25 of -msgid "'x'" -msgstr "" - -#: io.open:25 of -msgid "create a new file and open it for writing" -msgstr "" - -#: io.open:26 of -msgid "'a'" -msgstr "" - -#: io.open:26 of -msgid "open for writing, appending to the end of the file if it exists" -msgstr "" - -#: io.open:27 of -msgid "'b'" -msgstr "" - -#: io.open:27 of -msgid "binary mode" -msgstr "" - -#: io.open:28 of -msgid "'t'" -msgstr "" - -#: io.open:28 of -msgid "text mode (default)" -msgstr "" - -#: io.open:29 of -msgid "'+'" -msgstr "" - -#: io.open:29 of -msgid "open a disk file for updating (reading and writing)" -msgstr "" - -#: io.open:30 of -msgid "'U'" -msgstr "" - -#: io.open:30 of -msgid "universal newline mode (deprecated)" -msgstr "" - -#: io.open:33 of -msgid "" -"The default mode is 'rt' (open for reading text). For binary random " -"access, the mode 'w+b' opens and truncates the file to 0 bytes, while " -"'r+b' opens the file without truncation. The 'x' mode implies 'w' and " -"raises an `FileExistsError` if the file already exists." -msgstr "" - -#: io.open:38 of -msgid "" -"Python distinguishes between files opened in binary and text modes, even " -"when the underlying operating system doesn't. Files opened in binary mode" -" (appending 'b' to the mode argument) return contents as bytes objects " -"without any decoding. In text mode (the default, or when 't' is appended " -"to the mode argument), the contents of the file are returned as strings, " -"the bytes having been first decoded using a platform-dependent encoding " -"or using the specified encoding if given." -msgstr "" - -#: io.open:46 of -msgid "" -"'U' mode is deprecated and will raise an exception in future versions of " -"Python. It has no effect in Python 3. Use newline to control universal " -"newlines mode." -msgstr "" - -#: io.open:50 of -msgid "" -"buffering is an optional integer used to set the buffering policy. Pass 0" -" to switch buffering off (only allowed in binary mode), 1 to select line " -"buffering (only usable in text mode), and an integer > 1 to indicate the " -"size of a fixed-size chunk buffer. When no buffering argument is given, " -"the default buffering policy works as follows:" -msgstr "" - -#: io.open:56 of -msgid "" -"Binary files are buffered in fixed-size chunks; the size of the buffer is" -" chosen using a heuristic trying to determine the underlying device's " -"\"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`. On many " -"systems, the buffer will typically be 4096 or 8192 bytes long." -msgstr "" - -#: io.open:61 of -msgid "" -"\"Interactive\" text files (files for which isatty() returns True) use " -"line buffering. Other text files use the policy described above for " -"binary files." -msgstr "" - -#: io.open:65 of -msgid "" -"encoding is the name of the encoding used to decode or encode the file. " -"This should only be used in text mode. The default encoding is platform " -"dependent, but any encoding supported by Python can be passed. See the " -"codecs module for the list of supported encodings." -msgstr "" - -#: io.open:70 of -msgid "" -"errors is an optional string that specifies how encoding errors are to be" -" handled---this argument should not be used in binary mode. Pass 'strict'" -" to raise a ValueError exception if there is an encoding error (the " -"default of None has the same effect), or pass 'ignore' to ignore errors. " -"(Note that ignoring encoding errors can lead to data loss.) See the " -"documentation for codecs.register or run 'help(codecs.Codec)' for a list " -"of the permitted encoding error strings." -msgstr "" - -#: io.open:78 of -msgid "" -"newline controls how universal newlines works (it only applies to text " -"mode). It can be None, '', '\\n', '\\r', and '\\r\\n'. It works as " -"follows:" -msgstr "" - -#: io.open:82 of -msgid "" -"On input, if newline is None, universal newlines mode is enabled. Lines " -"in the input can end in '\\n', '\\r', or '\\r\\n', and these are " -"translated into '\\n' before being returned to the caller. If it is '', " -"universal newline mode is enabled, but line endings are returned to the " -"caller untranslated. If it has any of the other legal values, input lines" -" are only terminated by the given string, and the line ending is returned" -" to the caller untranslated." -msgstr "" - -#: io.open:90 of -msgid "" -"On output, if newline is None, any '\\n' characters written are " -"translated to the system default line separator, os.linesep. If newline " -"is '' or '\\n', no translation takes place. If newline is any of the " -"other legal values, any '\\n' characters written are translated to the " -"given string." -msgstr "" - -#: io.open:96 of -msgid "" -"If closefd is False, the underlying file descriptor will be kept open " -"when the file is closed. This does not work when a file name is given and" -" must be True in that case." -msgstr "" - -#: io.open:100 of -msgid "" -"A custom opener can be used by passing a callable as *opener*. The " -"underlying file descriptor for the file object is then obtained by " -"calling *opener* with (*file*, *flags*). *opener* must return an open " -"file descriptor (passing os.open as *opener* results in functionality " -"similar to passing None)." -msgstr "" - -#: io.open:106 of -msgid "" -"open() returns a file object whose type depends on the mode, and through " -"which the standard file operations such as reading and writing are " -"performed. When open() is used to open a file in a text mode ('w', 'r', " -"'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open a file " -"in a binary mode, the returned class varies: in read binary mode, it " -"returns a BufferedReader; in write binary and append binary modes, it " -"returns a BufferedWriter, and in read/write mode, it returns a " -"BufferedRandom." -msgstr "" - -#: io.open:115 of -msgid "" -"It is also possible to use a string or bytearray as a file for both " -"reading and writing. For strings StringIO can be used like a file opened " -"in a text mode, and for bytes a BytesIO can be used like a file opened in" -" a binary mode." -msgstr "" - #: ../../source/api/aiomisc.rst:68 msgid "``aiomisc.iterator_wrapper`` module" msgstr "Модуль ``aiomisc.iterator_wrapper``" @@ -791,3 +554,280 @@ msgstr "Модуль ``aiomisc.worker_pool``" #~ "False.)" #~ msgstr "" +#~ msgid "An enumeration." +#~ msgstr "" + +#~ msgid "Open file and return a stream. Raise OSError upon failure." +#~ msgstr "Модуль " + +#~ msgid "" +#~ "file is either a text or byte " +#~ "string giving the name (and the " +#~ "path if the file isn't in the " +#~ "current working directory) of the file" +#~ " to be opened or an integer " +#~ "file descriptor of the file to be" +#~ " wrapped. (If a file descriptor is" +#~ " given, it is closed when the " +#~ "returned I/O object is closed, unless" +#~ " closefd is set to False.)" +#~ msgstr "" + +#~ msgid "" +#~ "mode is an optional string that " +#~ "specifies the mode in which the " +#~ "file is opened. It defaults to 'r'" +#~ " which means open for reading in " +#~ "text mode. Other common values are " +#~ "'w' for writing (truncating the file " +#~ "if it already exists), 'x' for " +#~ "creating and writing to a new " +#~ "file, and 'a' for appending (which " +#~ "on some Unix systems, means that " +#~ "all writes append to the end of" +#~ " the file regardless of the current" +#~ " seek position). In text mode, if " +#~ "encoding is not specified the encoding" +#~ " used is platform dependent: " +#~ "locale.getpreferredencoding(False) is called to " +#~ "get the current locale encoding. (For" +#~ " reading and writing raw bytes use" +#~ " binary mode and leave encoding " +#~ "unspecified.) The available modes are:" +#~ msgstr "" + +#~ msgid "Character" +#~ msgstr "" + +#~ msgid "Meaning" +#~ msgstr "" + +#~ msgid "'r'" +#~ msgstr "" + +#~ msgid "open for reading (default)" +#~ msgstr "" + +#~ msgid "'w'" +#~ msgstr "" + +#~ msgid "open for writing, truncating the file first" +#~ msgstr "" + +#~ msgid "'x'" +#~ msgstr "" + +#~ msgid "create a new file and open it for writing" +#~ msgstr "" + +#~ msgid "'a'" +#~ msgstr "" + +#~ msgid "open for writing, appending to the end of the file if it exists" +#~ msgstr "" + +#~ msgid "'b'" +#~ msgstr "" + +#~ msgid "binary mode" +#~ msgstr "" + +#~ msgid "'t'" +#~ msgstr "" + +#~ msgid "text mode (default)" +#~ msgstr "" + +#~ msgid "'+'" +#~ msgstr "" + +#~ msgid "open a disk file for updating (reading and writing)" +#~ msgstr "" + +#~ msgid "'U'" +#~ msgstr "" + +#~ msgid "universal newline mode (deprecated)" +#~ msgstr "" + +#~ msgid "" +#~ "The default mode is 'rt' (open for" +#~ " reading text). For binary random " +#~ "access, the mode 'w+b' opens and " +#~ "truncates the file to 0 bytes, " +#~ "while 'r+b' opens the file without " +#~ "truncation. The 'x' mode implies 'w' " +#~ "and raises an `FileExistsError` if the" +#~ " file already exists." +#~ msgstr "" + +#~ msgid "" +#~ "Python distinguishes between files opened " +#~ "in binary and text modes, even " +#~ "when the underlying operating system " +#~ "doesn't. Files opened in binary mode " +#~ "(appending 'b' to the mode argument) " +#~ "return contents as bytes objects without" +#~ " any decoding. In text mode (the " +#~ "default, or when 't' is appended " +#~ "to the mode argument), the contents " +#~ "of the file are returned as " +#~ "strings, the bytes having been first " +#~ "decoded using a platform-dependent " +#~ "encoding or using the specified encoding" +#~ " if given." +#~ msgstr "" + +#~ msgid "" +#~ "'U' mode is deprecated and will " +#~ "raise an exception in future versions" +#~ " of Python. It has no effect " +#~ "in Python 3. Use newline to " +#~ "control universal newlines mode." +#~ msgstr "" + +#~ msgid "" +#~ "buffering is an optional integer used" +#~ " to set the buffering policy. Pass" +#~ " 0 to switch buffering off (only " +#~ "allowed in binary mode), 1 to " +#~ "select line buffering (only usable in" +#~ " text mode), and an integer > 1" +#~ " to indicate the size of a " +#~ "fixed-size chunk buffer. When no " +#~ "buffering argument is given, the default" +#~ " buffering policy works as follows:" +#~ msgstr "" + +#~ msgid "" +#~ "Binary files are buffered in fixed-" +#~ "size chunks; the size of the " +#~ "buffer is chosen using a heuristic " +#~ "trying to determine the underlying " +#~ "device's \"block size\" and falling back" +#~ " on `io.DEFAULT_BUFFER_SIZE`. On many " +#~ "systems, the buffer will typically be" +#~ " 4096 or 8192 bytes long." +#~ msgstr "" + +#~ msgid "" +#~ "\"Interactive\" text files (files for " +#~ "which isatty() returns True) use line" +#~ " buffering. Other text files use the" +#~ " policy described above for binary " +#~ "files." +#~ msgstr "" + +#~ msgid "" +#~ "encoding is the name of the " +#~ "encoding used to decode or encode " +#~ "the file. This should only be used" +#~ " in text mode. The default encoding" +#~ " is platform dependent, but any " +#~ "encoding supported by Python can be " +#~ "passed. See the codecs module for " +#~ "the list of supported encodings." +#~ msgstr "" + +#~ msgid "" +#~ "errors is an optional string that " +#~ "specifies how encoding errors are to " +#~ "be handled---this argument should not" +#~ " be used in binary mode. Pass " +#~ "'strict' to raise a ValueError exception" +#~ " if there is an encoding error " +#~ "(the default of None has the same" +#~ " effect), or pass 'ignore' to ignore" +#~ " errors. (Note that ignoring encoding " +#~ "errors can lead to data loss.) See" +#~ " the documentation for codecs.register or" +#~ " run 'help(codecs.Codec)' for a list " +#~ "of the permitted encoding error strings." +#~ msgstr "" + +#~ msgid "" +#~ "newline controls how universal newlines " +#~ "works (it only applies to text " +#~ "mode). It can be None, '', '\\n'," +#~ " '\\r', and '\\r\\n'. It works as" +#~ " follows:" +#~ msgstr "" + +#~ msgid "" +#~ "On input, if newline is None, " +#~ "universal newlines mode is enabled. " +#~ "Lines in the input can end in " +#~ "'\\n', '\\r', or '\\r\\n', and these " +#~ "are translated into '\\n' before being" +#~ " returned to the caller. If it " +#~ "is '', universal newline mode is " +#~ "enabled, but line endings are returned" +#~ " to the caller untranslated. If it" +#~ " has any of the other legal " +#~ "values, input lines are only terminated" +#~ " by the given string, and the " +#~ "line ending is returned to the " +#~ "caller untranslated." +#~ msgstr "" + +#~ msgid "" +#~ "On output, if newline is None, any" +#~ " '\\n' characters written are translated" +#~ " to the system default line " +#~ "separator, os.linesep. If newline is ''" +#~ " or '\\n', no translation takes " +#~ "place. If newline is any of the" +#~ " other legal values, any '\\n' " +#~ "characters written are translated to the" +#~ " given string." +#~ msgstr "" + +#~ msgid "" +#~ "If closefd is False, the underlying " +#~ "file descriptor will be kept open " +#~ "when the file is closed. This does" +#~ " not work when a file name is" +#~ " given and must be True in that" +#~ " case." +#~ msgstr "" + +#~ msgid "" +#~ "A custom opener can be used by " +#~ "passing a callable as *opener*. The " +#~ "underlying file descriptor for the file" +#~ " object is then obtained by calling" +#~ " *opener* with (*file*, *flags*). *opener*" +#~ " must return an open file descriptor" +#~ " (passing os.open as *opener* results " +#~ "in functionality similar to passing " +#~ "None)." +#~ msgstr "" + +#~ msgid "" +#~ "open() returns a file object whose " +#~ "type depends on the mode, and " +#~ "through which the standard file " +#~ "operations such as reading and writing" +#~ " are performed. When open() is used" +#~ " to open a file in a text " +#~ "mode ('w', 'r', 'wt', 'rt', etc.), " +#~ "it returns a TextIOWrapper. When used" +#~ " to open a file in a binary " +#~ "mode, the returned class varies: in " +#~ "read binary mode, it returns a " +#~ "BufferedReader; in write binary and " +#~ "append binary modes, it returns a " +#~ "BufferedWriter, and in read/write mode, " +#~ "it returns a BufferedRandom." +#~ msgstr "" + +#~ msgid "" +#~ "It is also possible to use a " +#~ "string or bytearray as a file for" +#~ " both reading and writing. For " +#~ "strings StringIO can be used like " +#~ "a file opened in a text mode, " +#~ "and for bytes a BytesIO can be " +#~ "used like a file opened in a " +#~ "binary mode." +#~ msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc_log.po b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc_log.po index 3d950c7e..a69f61d4 100644 --- a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc_log.po +++ b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc_log.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 16.1.16\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-10 15:17+0300\n" +"POT-Creation-Date: 2022-12-29 11:05+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/api/aiomisc_log.rst:2 msgid "``aiomisc_log`` module" @@ -108,7 +108,5 @@ msgstr "Модуль ``aiomisc_log.formatter.rich.py``" msgid "``aiomisc_log.enum`` module" msgstr "Модуль ``aiomisc_log.enum``" -#: aiomisc_log.enum.DateFormat:1 aiomisc_log.enum.LogFormat:1 -#: aiomisc_log.enum.LogLevel:1 of -msgid "An enumeration." -msgstr "" +#~ msgid "An enumeration." +#~ msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/async_backoff.po b/docs/source/locale/ru/LC_MESSAGES/async_backoff.po index 871a595c..183a5751 100644 --- a/docs/source/locale/ru/LC_MESSAGES/async_backoff.po +++ b/docs/source/locale/ru/LC_MESSAGES/async_backoff.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 12.1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-03 16:53+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov me@mosquito.su\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/async_backoff.rst:2 msgid "``@aiomisc.asyncbackoff``" @@ -132,15 +132,139 @@ msgstr "" msgid "Position arguments notation:" msgstr "Объявление через позиционные аргументы:" +#: ../../source/async_backoff.rst:38 +msgid "" +"import aiomisc\n" +"\n" +"attempt_timeout = 0.1\n" +"deadline = 1\n" +"pause = 0.1\n" +"\n" +"@aiomisc.asyncbackoff(attempt_timeout, deadline, pause)\n" +"async def db_fetch():\n" +" ...\n" +"\n" +"\n" +"@aiomisc.asyncbackoff(0.1, 1, 0.1)\n" +"async def db_save(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Passing exceptions for handling\n" +"@aiomisc.asyncbackoff(0.1, 1, 0.1, TypeError, RuntimeError, ValueError)\n" +"async def db_fetch(data: dict):\n" +" ..." +msgstr "" +"import aiomisc\n" +"\n" +"attempt_timeout = 0.1\n" +"deadline = 1\n" +"pause = 0.1\n" +"\n" +"@aiomisc.asyncbackoff(attempt_timeout, deadline, pause)\n" +"async def db_fetch():\n" +" ...\n" +"\n" +"\n" +"@aiomisc.asyncbackoff(0.1, 1, 0.1)\n" +"async def db_save(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Передаем список исключений\n" +"@aiomisc.asyncbackoff(0.1, 1, 0.1, TypeError, RuntimeError, ValueError)\n" +"async def db_fetch(data: dict):\n" +" ..." + #: ../../source/async_backoff.rst:62 msgid "Keyword arguments notation:" msgstr "Объявление через именованные аргументы" -#: ../../source/async_backoff.rst:107 -msgid "``asyncretry``" +#: ../../source/async_backoff.rst:64 +msgid "" +"import aiomisc\n" +"\n" +"attempt_timeout = 0.1\n" +"deadline = 1\n" +"pause = 0.1\n" +"\n" +"@aiomisc.asyncbackoff(attempt_timeout=attempt_timeout,\n" +" deadline=deadline, pause=pause)\n" +"async def db_fetch():\n" +" ...\n" +"\n" +"\n" +"@aiomisc.asyncbackoff(attempt_timeout=0.1, deadline=1, pause=0.1)\n" +"async def db_save(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Passing exceptions for handling\n" +"@aiomisc.asyncbackoff(attempt_timeout=0.1, deadline=1, pause=0.1,\n" +" exceptions=[TypeError, RuntimeError, ValueError])\n" +"async def db_fetch(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Will be retried no more than 2 times (3 tries total)\n" +"@aiomisc.asyncbackoff(attempt_timeout=0.5, deadline=1,\n" +" pause=0.1, max_tries=3,\n" +" exceptions=[TypeError, RuntimeError, ValueError])\n" +"async def db_fetch(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Will be retried only on connection abort (on POSIX systems)\n" +"@asyncbackoff(attempt_timeout=0.5, deadline=1, pause=0.1,\n" +" exceptions=[OSError],\n" +" giveup=lambda e: e.errno != errno.ECONNABORTED)\n" +"async def db_fetch(data: dict):\n" +" ..." msgstr "" +"import aiomisc\n" +"\n" +"attempt_timeout = 0.1\n" +"deadline = 1\n" +"pause = 0.1\n" +"\n" +"@aiomisc.asyncbackoff(attempt_timeout=attempt_timeout,\n" +" deadline=deadline, pause=pause)\n" +"async def db_fetch():\n" +" ...\n" +"\n" +"\n" +"@aiomisc.asyncbackoff(attempt_timeout=0.1, deadline=1, pause=0.1)\n" +"async def db_save(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Передаем список исключений\n" +"@aiomisc.asyncbackoff(attempt_timeout=0.1, deadline=1, pause=0.1,\n" +" exceptions=[TypeError, RuntimeError, ValueError])\n" +"async def db_fetch(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Будет повторено не больше чем 2 раза (всего 3 попытки)\n" +"@aiomisc.asyncbackoff(attempt_timeout=0.5, deadline=1,\n" +" pause=0.1, max_tries=3,\n" +" exceptions=[TypeError, RuntimeError, ValueError])\n" +"async def db_fetch(data: dict):\n" +" ...\n" +"\n" +"\n" +"# Повторы будут только если соединение было сброшено (только POSIX системы)\n" +"@asyncbackoff(attempt_timeout=0.5, deadline=1, pause=0.1,\n" +" exceptions=[OSError],\n" +" giveup=lambda e: e.errno != errno.ECONNABORTED)\n" +"async def db_fetch(data: dict):\n" +" ..." #: ../../source/async_backoff.rst:109 +msgid "``asyncretry``" +msgstr "" + +#: ../../source/async_backoff.rst:111 msgid "" "Shortcut of ``asyncbackoff(None, None, 0, *args, **kwargs)``. Just " "retries ``max_tries`` times." @@ -148,7 +272,7 @@ msgstr "" "Аналог ``asyncbackoff(None, None, 0, *args, **kwargs)``. Прсто повторяет " "выполнение функции ``max_tries`` раз." -#: ../../source/async_backoff.rst:114 +#: ../../source/async_backoff.rst:116 msgid "" "By default will be retry when any Exception. It's very simple and useful " "in generic cases, but you should specify an exception list when you're " @@ -161,3 +285,16 @@ msgstr "" "исключений тогда, когда обернутые функции вызывают сотни раз в секунду, " "потому что у вас есть риск быть причиной отказа в обслуживании в случае, " "если ваша функция вызывает какой-то сервис по сети." + +#: ../../source/async_backoff.rst:121 +msgid "" +"from aiomisc import asyncretry\n" +"\n" +"@asyncretry(5)\n" +"async def try_download_file(url):\n" +" ...\n" +"\n" +"@asyncretry(3, exceptions=(ConnectionError,))\n" +"async def get_cluster_lock():\n" +" ..." +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/circuit_breaker.po b/docs/source/locale/ru/LC_MESSAGES/circuit_breaker.po index 6e70029e..262b65c6 100644 --- a/docs/source/locale/ru/LC_MESSAGES/circuit_breaker.po +++ b/docs/source/locale/ru/LC_MESSAGES/circuit_breaker.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-10-15 17:18+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/circuit_breaker.rst:2 msgid "Circuit Breaker" @@ -51,6 +51,103 @@ msgstr "" msgid "Usage example:" msgstr "Пример использования:" +#: ../../source/circuit_breaker.rst:18 +#, python-format +msgid "" +"from aiohttp import web, ClientSession\n" +"from aiomisc.service.aiohttp import AIOHTTPService\n" +"import aiohttp\n" +"import aiomisc\n" +"\n" +"\n" +"async def public_gists(request):\n" +" async with aiohttp.ClientSession() as session:\n" +" # Using as context manager\n" +" with request.app[\"github_cb\"].context():\n" +" url = 'https://api.github.com/gists/public'\n" +" async with session.get(url) as response:\n" +" data = await response.text()\n" +"\n" +" return web.Response(\n" +" text=data,\n" +" headers={\"Content-Type\": \"application/json\"}\n" +" )\n" +"\n" +"\n" +"class API(AIOHTTPService):\n" +" async def create_application(self):\n" +" app = web.Application()\n" +" app.add_routes([web.get('/', public_gists)])\n" +"\n" +" # When 30% errors in 20 seconds\n" +" # Will be broken for 5 seconds\n" +" app[\"github_cb\"] = aiomisc.CircuitBreaker(\n" +" error_ratio=0.2,\n" +" response_time=20,\n" +" exceptions=[aiohttp.ClientError],\n" +" broken_time=5\n" +" )\n" +"\n" +" return app\n" +"\n" +"\n" +"async def main():\n" +" async with ClientSession() as session:\n" +" async with session.get(\"http://localhost:8080/\") as response:\n" +" assert response.headers\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint(API(port=8080)) as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"from aiohttp import web, ClientSession\n" +"from aiomisc.service.aiohttp import AIOHTTPService\n" +"import aiohttp\n" +"import aiomisc\n" +"\n" +"\n" +"async def public_gists(request):\n" +" async with aiohttp.ClientSession() as session:\n" +" # Используем как контекстный менеджер\n" +" with request.app[\"github_cb\"].context():\n" +" url = 'https://api.github.com/gists/public'\n" +" async with session.get(url) as response:\n" +" data = await response.text()\n" +"\n" +" return web.Response(\n" +" text=data,\n" +" headers={\"Content-Type\": \"application/json\"}\n" +" )\n" +"\n" +"\n" +"class API(AIOHTTPService):\n" +" async def create_application(self):\n" +" app = web.Application()\n" +" app.add_routes([web.get('/', public_gists)])\n" +"\n" +" # Если ошибок 30% за 20 секунд\n" +" # Сломаемся на 5 секунд\n" +" app[\"github_cb\"] = aiomisc.CircuitBreaker(\n" +" error_ratio=0.2,\n" +" response_time=20,\n" +" exceptions=[aiohttp.ClientError],\n" +" broken_time=5\n" +" )\n" +"\n" +" return app\n" +"\n" +"\n" +"async def main():\n" +" async with ClientSession() as session:\n" +" async with session.get(\"http://localhost:8080/\") as response:\n" +" assert response.headers\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint(API(port=8080)) as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/circuit_breaker.rst:72 msgid "The `CircuitBreaker` object might be one of three states:" msgstr "Объект `CircuitBreaker` может находится в одном из трех состояний:" @@ -135,3 +232,94 @@ msgstr "" "Декоратор оборачивающий функцию таким образом, что все вызовы проходят " "через предохраннитель, а именно через экземпляр ``CircuitBreaker`` для " "этой функции." + +#: ../../source/circuit_breaker.rst:113 +#, python-format +msgid "" +"from aiohttp import web, ClientSession\n" +"from aiomisc.service.aiohttp import AIOHTTPService\n" +"import aiohttp\n" +"import aiomisc\n" +"\n" +"\n" +"# When 20% errors in 30 seconds\n" +"# Will be broken on 30 seconds\n" +"@aiomisc.cutout(0.2, 30, aiohttp.ClientError)\n" +"async def fetch(session, url):\n" +" async with session.get(url) as response:\n" +" return await response.text()\n" +"\n" +"\n" +"async def public_gists(request):\n" +" async with aiohttp.ClientSession() as session:\n" +" data = await fetch(\n" +" session,\n" +" 'https://api.github.com/gists/public'\n" +" )\n" +"\n" +" return web.Response(\n" +" text=data,\n" +" headers={\"Content-Type\": \"application/json\"}\n" +" )\n" +"\n" +"\n" +"class API(AIOHTTPService):\n" +" async def create_application(self):\n" +" app = web.Application()\n" +" app.add_routes([web.get('/', public_gists)])\n" +" return app\n" +"\n" +"\n" +"async def main():\n" +" async with ClientSession() as session:\n" +" async with session.get(\"http://localhost:8080/\") as response:\n" +" assert response.headers\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint(API(port=8080)) as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"from aiohttp import web, ClientSession\n" +"from aiomisc.service.aiohttp import AIOHTTPService\n" +"import aiohttp\n" +"import aiomisc\n" +"\n" +"\n" +"# Если 20% ошибок за 30 секунд\n" +"# Сломаемся на 30 секунд\n" +"@aiomisc.cutout(0.2, 30, aiohttp.ClientError)\n" +"async def fetch(session, url):\n" +" async with session.get(url) as response:\n" +" return await response.text()\n" +"\n" +"\n" +"async def public_gists(request):\n" +" async with aiohttp.ClientSession() as session:\n" +" data = await fetch(\n" +" session,\n" +" 'https://api.github.com/gists/public'\n" +" )\n" +"\n" +" return web.Response(\n" +" text=data,\n" +" headers={\"Content-Type\": \"application/json\"}\n" +" )\n" +"\n" +"\n" +"class API(AIOHTTPService):\n" +" async def create_application(self):\n" +" app = web.Application()\n" +" app.add_routes([web.get('/', public_gists)])\n" +" return app\n" +"\n" +"\n" +"async def main():\n" +" async with ClientSession() as session:\n" +" async with session.get(\"http://localhost:8080/\") as response:\n" +" assert response.headers\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint(API(port=8080)) as loop:\n" +" loop.run_until_complete(main())" diff --git a/docs/source/locale/ru/LC_MESSAGES/context.po b/docs/source/locale/ru/LC_MESSAGES/context.po index 88ea09f7..e12932c2 100644 --- a/docs/source/locale/ru/LC_MESSAGES/context.po +++ b/docs/source/locale/ru/LC_MESSAGES/context.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-10-15 17:18+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/context.rst:2 msgid "Context" @@ -59,6 +59,84 @@ msgstr "" "Entrypoint. В других случаях функция ``get_context()`` возвращает текущий" " контекст." +#: ../../source/context.rst:17 +msgid "" +"import asyncio\n" +"from random import random, randint\n" +"\n" +"from aiomisc import entrypoint, get_context, Service\n" +"\n" +"\n" +"class LoggingService(Service):\n" +" async def start(self):\n" +" context = get_context()\n" +"\n" +" wait_time = await context['wait_time']\n" +"\n" +" print('Wait time is', wait_time)\n" +" self.start_event.set()\n" +"\n" +" while True:\n" +" print('Hello from service', self.name)\n" +" await asyncio.sleep(wait_time)\n" +"\n" +"\n" +"class RemoteConfiguration(Service):\n" +" async def start(self):\n" +" # querying from remote server\n" +" await asyncio.sleep(random())\n" +"\n" +" self.context['wait_time'] = randint(1, 5)\n" +"\n" +"\n" +"services = (\n" +" LoggingService(name='#1'),\n" +" LoggingService(name='#2'),\n" +" LoggingService(name='#3'),\n" +" RemoteConfiguration()\n" +")\n" +"\n" +"with entrypoint(*services) as loop:\n" +" pass" +msgstr "" +"import asyncio\n" +"from random import random, randint\n" +"\n" +"from aiomisc import entrypoint, get_context, Service\n" +"\n" +"\n" +"class LoggingService(Service):\n" +" async def start(self):\n" +" context = get_context()\n" +"\n" +" wait_time = await context['wait_time']\n" +"\n" +" print('Wait time is', wait_time)\n" +" self.start_event.set()\n" +"\n" +" while True:\n" +" print('Hello from service', self.name)\n" +" await asyncio.sleep(wait_time)\n" +"\n" +"\n" +"class RemoteConfiguration(Service):\n" +" async def start(self):\n" +" # Понарошку делаем запрос с удаленного сервера\n" +" await asyncio.sleep(random())\n" +"\n" +" self.context['wait_time'] = randint(1, 5)\n" +"\n" +"\n" +"services = (\n" +" LoggingService(name='#1'),\n" +" LoggingService(name='#2'),\n" +" LoggingService(name='#3'),\n" +" RemoteConfiguration()\n" +")\n" +"\n" +"with entrypoint(*services) as loop:\n" +" pass" + #: ../../source/context.rst:61 msgid "" "It's not a silver bullet. In base case services can be configured by " @@ -66,4 +144,3 @@ msgid "" msgstr "" "Это не панацея. В простом случае службы можно настроить, передав kwargs в" " ``__init__``." - diff --git a/docs/source/locale/ru/LC_MESSAGES/entrypoint.po b/docs/source/locale/ru/LC_MESSAGES/entrypoint.po index 926f86f5..e47853c8 100644 --- a/docs/source/locale/ru/LC_MESSAGES/entrypoint.po +++ b/docs/source/locale/ru/LC_MESSAGES/entrypoint.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-10 18:01+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/entrypoint.rst:2 msgid "entrypoint" @@ -27,14 +27,124 @@ msgstr "" "В общем случае точка входа это сущность помогающая создать event loop и " "закрыть все еще запущенные корутины при выходе." +#: ../../source/entrypoint.rst:7 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"async def main():\n" +" await asyncio.sleep(1)\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + #: ../../source/entrypoint.rst:20 msgid "Complete example:" msgstr "Пример целиком:" +#: ../../source/entrypoint.rst:22 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"import logging\n" +"\n" +"async def main():\n" +" await asyncio.sleep(1)\n" +" logging.info(\"Hello there\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" pool_size=2,\n" +" log_level='info',\n" +" log_format='color', # default when \"rich\" " +"absent\n" +" log_buffer_size=1024, # default\n" +" log_flush_interval=0.2, # default\n" +" log_config=True, # default\n" +" policy=asyncio.DefaultEventLoopPolicy(), # default\n" +" debug=False, # default\n" +") as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"import asyncio\n" +"import aiomisc\n" +"import logging\n" +"\n" +"async def main():\n" +" await asyncio.sleep(1)\n" +" logging.info(\"Hello there\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" pool_size=2,\n" +" log_level='info',\n" +" log_format='color', # по умолчанию если \"rich\" " +"не установлен\n" +" log_buffer_size=1024, # по умолчанию\n" +" log_flush_interval=0.2, # по умолчанию\n" +" log_config=True, # по умолчанию\n" +" policy=asyncio.DefaultEventLoopPolicy(), # по умолчанию\n" +" debug=False, # по умолчанию\n" +") as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/entrypoint.rst:45 msgid "Running entrypoint from async code" msgstr "Запуск точки входа (`entrypoint`) из асинхронного кода" +#: ../../source/entrypoint.rst:47 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"import logging\n" +"from aiomisc.service.periodic import PeriodicService\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"class MyPeriodicService(PeriodicService):\n" +" async def callback(self):\n" +" log.info('Running periodic callback')\n" +" # ...\n" +"\n" +"async def main():\n" +" service = MyPeriodicService(interval=1, delay=0) # once per minute\n" +"\n" +" # returns an entrypoint instance because event-loop\n" +" # already running and might be get via asyncio.get_event_loop()\n" +" async with aiomisc.entrypoint(service) as ep:\n" +" try:\n" +" await asyncio.wait_for(ep.closing(), timeout=1)\n" +" except asyncio.TimeoutError:\n" +" pass\n" +"\n" +"\n" +"asyncio.run(main())" +msgstr "" +"import asyncio\n" +"import aiomisc\n" +"import logging\n" +"from aiomisc.service.periodic import PeriodicService\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"class MyPeriodicService(PeriodicService):\n" +" async def callback(self):\n" +" log.info('Running periodic callback')\n" +" # ...\n" +"\n" +"async def main():\n" +" service = MyPeriodicService(interval=1, delay=0) # once per minute\n" +"\n" +" # вернет экземпляр entrypoint потому, что event-loop\n" +" # уже запущен и может быть получен через asyncio.get_event_loop()\n" +" async with aiomisc.entrypoint(service) as ep:\n" +" try:\n" +" await asyncio.wait_for(ep.closing(), timeout=1)\n" +" except asyncio.TimeoutError:\n" +" pass\n" +"\n" +"\n" +"asyncio.run(main())" + #: ../../source/entrypoint.rst:77 msgid "Configuration from environment" msgstr "Конфигурация из переменных окружения" @@ -86,6 +196,21 @@ msgstr "" "управляет сервисами ``aiomisc.Service`` и принимает прочие аргументы " "entrypoint." +#: ../../source/entrypoint.rst:97 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"async def main():\n" +" loop = asyncio.get_event_loop()\n" +" now = loop.time()\n" +" await asyncio.sleep(0.1)\n" +" assert now < loop.time()\n" +"\n" +"\n" +"aiomisc.run(main())" +msgstr "" + #: ../../source/entrypoint.rst:113 msgid "Logging configuration" msgstr "Конфигурация журналов" @@ -144,10 +269,10 @@ msgid "" "Alternatively you can call ``aiomisc.log.basic_config`` function manually" " passing it already created eventloop." msgstr "" -"``entrypoint`` вызовет ``aiomisc.log.basic_config`` " -"неявно используя пеараметры ``log_level=`` и ``log_format=``. " -"Как альтернатива, вы можете вызвать ``aiomisc.log.basic_config`` вручную " -"передав ей экземпляр ``eventloop``." +"``entrypoint`` вызовет ``aiomisc.log.basic_config`` неявно используя " +"пеараметры ``log_level=`` и ``log_format=``. Как альтернатива, вы можете " +"вызвать ``aiomisc.log.basic_config`` вручную передав ей экземпляр " +"``eventloop``." #: ../../source/entrypoint.rst:133 msgid "" @@ -158,10 +283,21 @@ msgid "" " the handler there to flush it into the separate thread." msgstr "" "Однако вы можете настроить логирование раньше, используя " -"``aiomisc_log.basic_config``, но вы потеряете буферизацию и запись в буфер " -"отдельном потоке. Эта функция фактически вызывается во время настройки " -"ведения журнала, ``entrypoint`` передает обертку для logging handler, " -"чтобы он записывал в буфер в отдельном потоке." +"``aiomisc_log.basic_config``, но вы потеряете буферизацию и запись в " +"буфер отдельном потоке. Эта функция фактически вызывается во время " +"настройки ведения журнала, ``entrypoint`` передает обертку для logging " +"handler, чтобы он записывал в буфер в отдельном потоке." + +#: ../../source/entrypoint.rst:139 +msgid "" +"import logging\n" +"\n" +"from aiomisc_log import basic_config\n" +"\n" +"\n" +"basic_config(log_format=\"color\")\n" +"logging.info(\"Hello\")" +msgstr "" #: ../../source/entrypoint.rst:149 msgid "" @@ -173,6 +309,26 @@ msgstr "" "например, после разбора аргументов, это безопасно настроить его дважды " "(или больше)." +#: ../../source/entrypoint.rst:153 +msgid "" +"import logging\n" +"\n" +"import aiomisc\n" +"from aiomisc_log import basic_config\n" +"\n" +"\n" +"basic_config(log_format=\"color\")\n" +"logging.info(\"Hello from usual python\")\n" +"\n" +"\n" +"async def main():\n" +" logging.info(\"Hello from async python\")\n" +"\n" +"\n" +"with aiomisc.entrypoint(log_format=\"color\") as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + #: ../../source/entrypoint.rst:173 msgid "" "Sometimes you want to configure logging manually, the following example " @@ -180,3 +336,132 @@ msgid "" msgstr "" "Иногда вы хотите настроить ведение журнала самостоятельно, пример ниже " "демонстрирует, как это сделать:" + +#: ../../source/entrypoint.rst:176 +#, python-format +msgid "" +"import os\n" +"import logging\n" +"from logging.handlers import RotatingFileHandler\n" +"from gzip import GzipFile\n" +"\n" +"import aiomisc\n" +"\n" +"\n" +"class GzipLogFile(GzipFile):\n" +" def write(self, data) -> int:\n" +" if isinstance(data, str):\n" +" data = data.encode()\n" +" return super().write(data)\n" +"\n" +"\n" +"class RotatingGzipFileHandler(RotatingFileHandler):\n" +" \"\"\" Really added just for example you have to test it properly " +"\"\"\"\n" +"\n" +" def shouldRollover(self, record):\n" +" if not os.path.isfile(self.baseFilename):\n" +" return False\n" +" if self.stream is None:\n" +" self.stream = self._open()\n" +" return 0 < self.maxBytes < os.stat(self.baseFilename).st_size\n" +"\n" +" def _open(self):\n" +" return GzipLogFile(filename=self.baseFilename, mode=self.mode)\n" +"\n" +"\n" +"async def main():\n" +" for _ in range(1_000):\n" +" logging.info(\"Hello world\")\n" +"\n" +"\n" +"with aiomisc.entrypoint(log_config=False) as loop:\n" +" gzip_handler = RotatingGzipFileHandler(\n" +" \"app.log.gz\",\n" +" # Maximum 100 files by 10 megabytes\n" +" maxBytes=10 * 2 ** 20, backupCount=100\n" +" )\n" +" stream_handler = logging.StreamHandler()\n" +"\n" +" formatter = logging.Formatter(\n" +" \"[%(asctime)s] <%(levelname)s> \"\n" +" \"%(filename)s:%(lineno)d (%(threadName)s): %(message)s\"\n" +" )\n" +"\n" +" gzip_handler.setFormatter(formatter)\n" +" stream_handler.setFormatter(formatter)\n" +"\n" +" logging.basicConfig(\n" +" level=logging.INFO,\n" +" # Wrapping all handlers in separate streams will not block the\n" +" # event-loop even if gzip takes a long time to open the\n" +" # file.\n" +" handlers=map(\n" +" aiomisc.log.wrap_logging_handler,\n" +" (gzip_handler, stream_handler)\n" +" )\n" +" )\n" +" loop.run_until_complete(main())" +msgstr "" +"import os\n" +"import logging\n" +"from logging.handlers import RotatingFileHandler\n" +"from gzip import GzipFile\n" +"\n" +"import aiomisc\n" +"\n" +"\n" +"class GzipLogFile(GzipFile):\n" +" def write(self, data) -> int:\n" +" if isinstance(data, str):\n" +" data = data.encode()\n" +" return super().write(data)\n" +"\n" +"\n" +"class RotatingGzipFileHandler(RotatingFileHandler):\n" +" \"\"\" Really added just for example you have to test it properly " +"\"\"\"\n" +"\n" +" def shouldRollover(self, record):\n" +" if not os.path.isfile(self.baseFilename):\n" +" return False\n" +" if self.stream is None:\n" +" self.stream = self._open()\n" +" return 0 < self.maxBytes < os.stat(self.baseFilename).st_size\n" +"\n" +" def _open(self):\n" +" return GzipLogFile(filename=self.baseFilename, mode=self.mode)\n" +"\n" +"\n" +"async def main():\n" +" for _ in range(1_000):\n" +" logging.info(\"Hello world\")\n" +"\n" +"\n" +"with aiomisc.entrypoint(log_config=False) as loop:\n" +" gzip_handler = RotatingGzipFileHandler(\n" +" \"app.log.gz\",\n" +" # Максимум 100 файлов по 10 мегабайт\n" +" maxBytes=10 * 2 ** 20, backupCount=100\n" +" )\n" +" stream_handler = logging.StreamHandler()\n" +"\n" +" formatter = logging.Formatter(\n" +" \"[%(asctime)s] <%(levelname)s> \"\n" +" \"%(filename)s:%(lineno)d (%(threadName)s): %(message)s\"\n" +" )\n" +"\n" +" gzip_handler.setFormatter(formatter)\n" +" stream_handler.setFormatter(formatter)\n" +"\n" +" logging.basicConfig(\n" +" level=logging.INFO,\n" +" # Обертывание всех обработчиков в отдельные потоки не заблокирует\n" +" # event-loop даже если gzip занимает много времени, чтобы открыть\n" +" # файл.\n" +" handlers=map(\n" +" aiomisc.log.wrap_logging_handler,\n" +" (gzip_handler, stream_handler)\n" +" )\n" +" )\n" +" loop.run_until_complete(main())" diff --git a/docs/source/locale/ru/LC_MESSAGES/index.po b/docs/source/locale/ru/LC_MESSAGES/index.po index 57c74584..2fef2275 100644 --- a/docs/source/locale/ru/LC_MESSAGES/index.po +++ b/docs/source/locale/ru/LC_MESSAGES/index.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-12-29 08:57+0300\n" +"POT-Creation-Date: 2022-12-29 12:06+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -71,13 +71,16 @@ msgid "" "` to make your asyncio code more robust and easier to " "maintain. In this documentation, we'll take a closer look at what " "``aiomisc`` has to offer and how it can help you streamline your asyncio " -"development." +"service development." msgstr "" "С aiomisc вы можете воспользоваться такими мощными функциями, как: " ":doc:`worker пул `, :doc:`connection пул `, " ":doc:`шаблон «предохранитель» `, и механизмы повторов " "такие как :doc:`asyncbackoff ` и :ref:`asyncretry " -"" +"` чтобы сделать ваш асинхронный код более надежным и простым " +"в обслуживании. В этой документации мы более подробно рассмотрим, что " +"может предложить ``aiomisc`` и как он может помочь вам упростить " +"разработку сервисов с asyncio." #: ../../source/index.rst:48 msgid "Installation" @@ -95,10 +98,24 @@ msgstr "" msgid "Installing from PyPI_:" msgstr "Установка с PyPI_:" +#: ../../source/index.rst:55 +msgid "pip3 install aiomisc" +msgstr "" + #: ../../source/index.rst:59 msgid "Installing from github.com:" msgstr "Установка из репозитория на github.com:" +#: ../../source/index.rst:61 +msgid "" +"# Using git tool\n" +"pip3 install git+https://github.com/aiokitchen/aiomisc.git\n" +"\n" +"# Alternative way using http\n" +"pip3 install \\\n" +" https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip" +msgstr "" + #: ../../source/index.rst:70 msgid "" "The package contains several extras and you can install additional " @@ -111,10 +128,18 @@ msgstr "" msgid "With uvloop_:" msgstr "Вместе с uvloop_" +#: ../../source/index.rst:75 +msgid "pip3 install \"aiomisc[uvloop]\"" +msgstr "" + #: ../../source/index.rst:80 msgid "With aiohttp_:" msgstr "Вместе с aiohttp_:" +#: ../../source/index.rst:82 +msgid "pip3 install \"aiomisc[aiohttp]\"" +msgstr "" + #: ../../source/index.rst:86 msgid "Complete table of extras bellow:" msgstr "Полная таблица дополнений ниже:" @@ -123,10 +148,6 @@ msgstr "Полная таблица дополнений ниже:" msgid "example" msgstr "пример" -#: ../../source/index.rst:89 -msgid "dependencies" -msgstr "зависимости" - #: ../../source/index.rst:89 msgid "description" msgstr "описание" @@ -135,10 +156,6 @@ msgstr "описание" msgid "``pip install aiomisc[aiohttp]``" msgstr "" -#: ../../source/index.rst:91 -msgid "``aiohttp``" -msgstr "" - #: ../../source/index.rst:91 msgid "For running aiohttp_ applications." msgstr "Для запуска приложений написанных с aiohttp_." @@ -147,10 +164,6 @@ msgstr "Для запуска приложений написанных с aioht msgid "``pip install aiomisc[asgi]``" msgstr "" -#: ../../source/index.rst:93 -msgid "``aiohttp-asgi``" -msgstr "" - #: ../../source/index.rst:93 msgid "For running ASGI_ applications" msgstr "Для запуска ASGI_ приложений" @@ -159,10 +172,6 @@ msgstr "Для запуска ASGI_ приложений" msgid "``pip install aiomisc[carbon]``" msgstr "" -#: ../../source/index.rst:95 -msgid "``aiocarbon``" -msgstr "" - #: ../../source/index.rst:95 msgid "Sending metrics to carbon_ (part of graphite_)" msgstr "Чтобы посылать метрики в carbon_ (часть graphite_)" @@ -171,10 +180,6 @@ msgstr "Чтобы посылать метрики в carbon_ (часть graphi msgid "``pip install aiomisc[cron]``" msgstr "" -#: ../../source/index.rst:97 -msgid "``croniter``" -msgstr "" - #: ../../source/index.rst:97 msgid "use croniter_ for sheduling tasks" msgstr "планирование задачи с croniter_" @@ -183,10 +188,6 @@ msgstr "планирование задачи с croniter_" msgid "``pip install aiomisc[raven]``" msgstr "" -#: ../../source/index.rst:99 -msgid "``raven``" -msgstr "" - #: ../../source/index.rst:99 msgid "Sending exceptions to sentry_ using raven_" msgstr "Чтобы посылать исключения в sentry_ используя raven_" @@ -195,10 +196,6 @@ msgstr "Чтобы посылать исключения в sentry_ исполь msgid "``pip install aiomisc[rich]``" msgstr "" -#: ../../source/index.rst:101 -msgid "``rich``" -msgstr "" - #: ../../source/index.rst:101 msgid "You might using rich_ for logging" msgstr "Можете использовать rich_ для логирования" @@ -207,19 +204,23 @@ msgstr "Можете использовать rich_ для логировани msgid "``pip install aiomisc[uvloop]``" msgstr "" -#: ../../source/index.rst:103 -msgid "``uvloop``" -msgstr "" - #: ../../source/index.rst:103 msgid "use uvloop_ as a default event loop" msgstr "используйте uvloop_ как основной event-loop" -#: ../../source/index.rst:118 +#: ../../source/index.rst:117 +msgid "You can combine extras values by separating them with commas, for example:" +msgstr "Вы можете комбинировать эти значения разделяя их запятыми, пример:" + +#: ../../source/index.rst:119 +msgid "pip3 install \"aiomisc[aiohttp,cron,rich,uvloop]\"" +msgstr "" + +#: ../../source/index.rst:125 msgid "Quick Start" msgstr "Быстрый старт" -#: ../../source/index.rst:120 +#: ../../source/index.rst:127 msgid "" "This section will cover how this library creates and uses the event loop " "and creates services. Of course, you can't write about everything here, " @@ -233,15 +234,35 @@ msgstr "" "всегда можно обратиться к разделу :doc:`/modules` и разделу " ":doc:`/api/index` для справки." -#: ../../source/index.rst:126 +#: ../../source/index.rst:133 msgid "Event-loop and entrypoint" msgstr "Eventloop и entrypoint" -#: ../../source/index.rst:128 +#: ../../source/index.rst:135 msgid "Let's look at this simple example first:" msgstr "Сначала рассмотрим этот простой пример:" -#: ../../source/index.rst:150 +#: ../../source/index.rst:137 +msgid "" +"import asyncio\n" +"import logging\n" +"\n" +"import aiomisc\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"async def main():\n" +" log.info('Starting')\n" +" await asyncio.sleep(3)\n" +" log.info('Exiting')\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with entrypoint(log_level=\"info\", log_format=\"color\") as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + +#: ../../source/index.rst:157 msgid "" "This code declares an asynchronous ``main()`` function that exits after 3" " seconds. It would seem nothing interesting, but the whole point is in " @@ -251,7 +272,7 @@ msgstr "" "через 3 секунды. Казалось бы, ничего интересного, но все дело в " "``entrypoint``." -#: ../../source/index.rst:154 +#: ../../source/index.rst:161 msgid "" "What does the ``entrypoint`` do, it would seem not so much, it creates an" " event-loop and transfers control to the user. However, under the hood, " @@ -264,7 +285,7 @@ msgstr "" "настраивается журналирование в отдельном потоке, создается пул потоков, " "запускаются сервисы, но об этом позже и сервисов в данном примере нет." -#: ../../source/index.rst:160 +#: ../../source/index.rst:167 msgid "" "Alternatively, you can choose not to use an entrypoint, just create an " "event-loop and set this as a default event loop for current thread:" @@ -272,7 +293,27 @@ msgstr "" "В принципе вы можете не использовать точку входа, а просто создать " "eventloop и установите его по умолчанию для текущего потока:" -#: ../../source/index.rst:182 +#: ../../source/index.rst:170 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"# * Installs uvloop event loop is it's has been installed.\n" +"# * Creates and set `aiomisc.thread_pool.ThreadPoolExecutor`\n" +"# as a default executor\n" +"# * Sets just created event-loop as a current event-loop for this thread." +"\n" +"aiomisc.new_event_loop()\n" +"\n" +"async def main():\n" +" await asyncio.sleep(1)\n" +"\n" +"if __name__ == '__main__':\n" +" loop = asyncio.get_event_loop()\n" +" loop.run_until_complete(main())" +msgstr "" + +#: ../../source/index.rst:189 msgid "" "The example above is useful if your code is already using an implicitly " "created event loop, you will have to modify less code, just add " @@ -284,7 +325,7 @@ msgstr "" "кода, просто добавьте ``aiomisc.new_event_loop()`` и все вызовы " "``asyncio.get_event_loop()`` вернет созданный экземпляр." -#: ../../source/index.rst:187 +#: ../../source/index.rst:194 msgid "" "However, you can do with one call. Following example closes implicitly " "created asyncio event loop and install a new one:" @@ -292,11 +333,24 @@ msgstr "" "Однако можно обойтись и одним вызовом. Следующий пример закрывает неявно " "созданный eventloop asyncio и устанавливает новый:" -#: ../../source/index.rst:204 +#: ../../source/index.rst:197 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"async def main():\n" +" await asyncio.sleep(3)\n" +"\n" +"if __name__ == '__main__':\n" +" loop = aiomisc.new_event_loop()\n" +" loop.run_until_complete(main())" +msgstr "" + +#: ../../source/index.rst:211 msgid "Services" msgstr "Сервисы" -#: ../../source/index.rst:206 +#: ../../source/index.rst:213 msgid "" "The main thing that an ``entrypoint`` does is start and gracefully stop " "services." @@ -304,7 +358,7 @@ msgstr "" "Главное, что делает точка входа, — это запускает и корректно " "останавливает «Сервисы»." -#: ../../source/index.rst:209 +#: ../../source/index.rst:216 msgid "" "The service concept within this library means a class derived from the " "``aiosmic.Service`` class and implementing the ``async def start(self) ->" @@ -316,7 +370,7 @@ msgstr "" " None`` и, опционально, метод ``async def stop(self, exc: Optional[ " "Exception]) -> None``." -#: ../../source/index.rst:214 +#: ../../source/index.rst:221 #, fuzzy msgid "" "The concept of stopping a service is not necessarily is pressing " @@ -327,11 +381,27 @@ msgstr "" "пользователем клавиш ``Ctrl+C``, на самом деле это просто выход из " "контекстного менеджера ``entrypoint``." -#: ../../source/index.rst:217 +#: ../../source/index.rst:224 msgid "The example below shows what your service might look like:" msgstr "Пример ниже иллюстрирует, как может выглядеть ваш сервис:" -#: ../../source/index.rst:234 +#: ../../source/index.rst:226 +msgid "" +"from aiomisc import entrypoint, Service\n" +"\n" +"class MyService(Service):\n" +" async def start(self):\n" +" do_something_when_start()\n" +"\n" +" async def stop(self, exc):\n" +" do_graceful_shutdown()\n" +"\n" +"\n" +"with entrypoint(MyService()) as loop:\n" +" loop.run_forever()" +msgstr "" + +#: ../../source/index.rst:241 msgid "" "The entry point can start as many instances of the service as it likes, " "and all of them will start concurrently." @@ -339,7 +409,7 @@ msgstr "" "Точка входа может запускать любое количество экземпляров службы, и все " "они будут запускаться конкурентно." -#: ../../source/index.rst:237 +#: ../../source/index.rst:244 msgid "" "There is also a way if the ``start`` method is a payload for a service, " "and then there is no need to implement the stop method, since the running" @@ -353,11 +423,30 @@ msgstr "" " Но в этом случае вам придется уведомить ``entrypoint`` о том, что " "инициализация экземпляра службы завершена и ее можно продолжить." -#: ../../source/index.rst:243 +#: ../../source/index.rst:250 msgid "Like this:" msgstr "Примерно так:" -#: ../../source/index.rst:265 +#: ../../source/index.rst:252 +msgid "" +"import asyncio\n" +"from threading import Event\n" +"from aiomisc import entrypoint, Service\n" +"\n" +"event = Event()\n" +"\n" +"class MyService(Service):\n" +" async def start(self):\n" +" # Send signal to entrypoint for continue running\n" +" self.start_event.set()\n" +" await asyncio.sleep(3600)\n" +"\n" +"\n" +"with entrypoint(MyService()) as loop:\n" +" assert event.is_set()" +msgstr "" + +#: ../../source/index.rst:272 msgid "" "The ``entrypoint`` passes control to the body of the context manager only" " after all service instances have started. As mentioned above, a start is" @@ -369,7 +458,7 @@ msgstr "" "стартом считается завершение метода ``start`` или установка стартового " "события с помощью ``self.start_event.set()``." -#: ../../source/index.rst:270 +#: ../../source/index.rst:277 msgid "" "The whole power of this library is in the set of already implemented or " "abstract services. Such as: :ref:`AIOHTTPService `, " @@ -385,7 +474,7 @@ msgstr "" ":ref:`PeriodicService `, :ref:`CronService ` и так далее." -#: ../../source/index.rst:278 +#: ../../source/index.rst:285 msgid "" "Unfortunately in this section it is not possible to pay more attention to" " this, please pay attention to the :doc:`/tutorial` section section, " @@ -394,46 +483,55 @@ msgid "" "authors have tried to make the source code as clear and simple as " "possible, so feel free to explore it." msgstr "" -"К сожалению в данном разделе нет возможности уделить этому больше внимания, " -"обратите внимание на раздел :doc:`/tutorial`, там больше примеров и " -"пояснений, ну и конечно вы всегда можете узнать ответ на :doc:`/api/index` " -"или в исходном коде. Авторы постарались сделать исходный код максимально " -"понятным и простым, поэтому не стесняйтесь исследовать его." +"К сожалению в данном разделе нет возможности уделить этому больше " +"внимания, обратите внимание на раздел :doc:`/tutorial`, там больше " +"примеров и пояснений, ну и конечно вы всегда можете узнать ответ на " +":doc:`/api/index` или в исходном коде. Авторы постарались сделать " +"исходный код максимально понятным и простым, поэтому не стесняйтесь " +"исследовать его." -#: ../../source/index.rst:286 +#: ../../source/index.rst:293 msgid "Versioning" msgstr "Версионирование" -#: ../../source/index.rst:288 +#: ../../source/index.rst:295 msgid "This software follows `Semantic Versioning`_" msgstr "" "Это программное обеспечение следует методологиии `Семантического " "Версионирования`_" -#: ../../source/index.rst:292 +#: ../../source/index.rst:299 msgid "How to develop?" msgstr "Как начать разработку?" -#: ../../source/index.rst:294 +#: ../../source/index.rst:301 msgid "Should be installed:" msgstr "Должно быть установлено" -#: ../../source/index.rst:296 -msgid "`virtualenv`" -msgstr "`virtualenv`" +#: ../../source/index.rst:303 +msgid "``virtualenv``" +msgstr "``virtualenv``" -#: ../../source/index.rst:297 -msgid "GNU Make as `make`" -msgstr "GNU Make как `make`" +#: ../../source/index.rst:304 +msgid "GNU Make as ``make``" +msgstr "GNU Make как ``make``" -#: ../../source/index.rst:298 -msgid "Python 3.7+ as `python3`" -msgstr "Python 3.7+ как `python3`" +#: ../../source/index.rst:305 +msgid "Python 3.7+ as ``python3``" +msgstr "Python 3.7+ как ``python3``" -#: ../../source/index.rst:301 +#: ../../source/index.rst:306 +msgid "Installed Poetry_ as ``poetry``" +msgstr "Установлен Poetry_ как ``poetry``" + +#: ../../source/index.rst:311 msgid "For setting up developer environment just type" msgstr "Для настройки окружения разработчика просто наберите" -#: ../../source/index.rst:311 +#: ../../source/index.rst:313 +msgid "poetry install" +msgstr "" + +#: ../../source/index.rst:321 msgid "Table Of Contents" msgstr "Содержание" diff --git a/docs/source/locale/ru/LC_MESSAGES/io.po b/docs/source/locale/ru/LC_MESSAGES/io.po index 945b8723..79e68d4e 100644 --- a/docs/source/locale/ru/LC_MESSAGES/io.po +++ b/docs/source/locale/ru/LC_MESSAGES/io.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-10-15 17:18+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/io.rst:2 msgid "asynchronous file operations" @@ -25,6 +25,30 @@ msgstr "" "Асинхронные файловые операции запускающиеся в пуле потоков \"под " "капотом\"." +#: ../../source/io.rst:6 +msgid "" +"import aiomisc\n" +"import tempfile\n" +"from pathlib import Path\n" +"\n" +"\n" +"async def file_write():\n" +" with tempfile.TemporaryDirectory() as tmp:\n" +" fname = Path(tmp) / 'test.txt'\n" +"\n" +" async with aiomisc.io.async_open(fname, 'w+') as afp:\n" +" await afp.write(\"Hello\")\n" +" await afp.write(\" \")\n" +" await afp.write(\"world\")\n" +"\n" +" await afp.seek(0)\n" +" print(await afp.read())\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(file_write())" +msgstr "" + #: ../../source/io.rst:31 msgid "" "This is the way to working with files based on threads. It's very similar" @@ -87,3 +111,50 @@ msgid "" msgstr "" "Просто попробуйте завернуть все блокирующие вызовы в отдельные функции и " "вызывайте их используя пул потоков (см. пример ниже):" + +#: ../../source/io.rst:53 +msgid "" +"import os\n" +"import aiomisc\n" +"import hashlib\n" +"import tempfile\n" +"from pathlib import Path\n" +"\n" +"\n" +"@aiomisc.threaded\n" +"def hash_file(filename, chunk_size=65535, hash_func=hashlib.blake2b):\n" +" hasher = hash_func()\n" +"\n" +" with open(filename, \"rb\") as fp:\n" +" for chunk in iter(lambda: fp.read(chunk_size), b\"\"):\n" +" hasher.update(chunk)\n" +"\n" +" return hasher.hexdigest()\n" +"\n" +"\n" +"@aiomisc.threaded\n" +"def fill_random_file(filename, size, chunk_size=65535):\n" +" with open(filename, \"wb\") as fp:\n" +" while fp.tell() < size:\n" +" fp.write(os.urandom(chunk_size))\n" +"\n" +" return fp.tell()\n" +"\n" +"\n" +"async def main(path):\n" +" filename = path / \"one\"\n" +" await fill_random_file(filename, 1024 * 1024)\n" +" first_hash = await hash_file(filename)\n" +"\n" +" filename = path / \"two\"\n" +" await fill_random_file(filename, 1024 * 1024)\n" +" second_hash = await hash_file(filename)\n" +"\n" +" assert first_hash != second_hash\n" +"\n" +"\n" +"with tempfile.TemporaryDirectory(prefix=\"random.\") as path:\n" +" aiomisc.run(\n" +" main(Path(path))\n" +" )" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/logging.po b/docs/source/locale/ru/LC_MESSAGES/logging.po index 5e6226dc..838218b2 100644 --- a/docs/source/locale/ru/LC_MESSAGES/logging.po +++ b/docs/source/locale/ru/LC_MESSAGES/logging.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-10-15 17:18+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/logging.rst:2 msgid "Logging configuration" @@ -24,8 +24,8 @@ msgid "" "Default logging configuration might be configured by setting environment " "variables:" msgstr "" -"Конфигурация логирования по умолчанию может быть осуществлена " -"через переменные окружения:" +"Конфигурация логирования по умолчанию может быть осуществлена через " +"переменные окружения:" #: ../../source/logging.rst:6 msgid "`AIOMISC_LOG_LEVEL` - default logging level" @@ -47,6 +47,12 @@ msgstr "`AIOMISC_LOG_FLUSH` - интервал сброса буфера лог msgid "`AIOMISC_LOG_BUFFER` - maximum log buffer size" msgstr "`AIOMISC_LOG_BUFFER` - максимальный размер буфера логов" +#: ../../source/logging.rst:12 +msgid "" +"$ export AIOMISC_LOG_LEVEL=debug\n" +"$ export AIOMISC_LOG_FORMAT=rich" +msgstr "" + #: ../../source/logging.rst:19 msgid "Color" msgstr "Color" @@ -55,6 +61,16 @@ msgstr "Color" msgid "Setting up colorized logs:" msgstr "Настройка цветных логов:" +#: ../../source/logging.rst:23 +msgid "" +"import logging\n" +"from aiomisc.log import basic_config\n" +"\n" +"\n" +"# Configure logging\n" +"basic_config(level=logging.INFO, buffered=False, log_format='color')" +msgstr "" + #: ../../source/logging.rst:34 msgid "JSON" msgstr "JSON" @@ -63,6 +79,16 @@ msgstr "JSON" msgid "Setting up json logs:" msgstr "Настройка json логов:" +#: ../../source/logging.rst:38 +msgid "" +"import logging\n" +"from aiomisc.log import basic_config\n" +"\n" +"\n" +"# Configure logging\n" +"basic_config(level=logging.INFO, buffered=False, log_format='json')" +msgstr "" + #: ../../source/logging.rst:49 msgid "JournalD" msgstr "JournalD" @@ -80,43 +106,92 @@ msgid "" "This handler is the default when the program starting as a systemd " "service." msgstr "" -"Этот обработчик выбирается по умолчанию если программа запускается как systemd " -"сервис." +"Этот обработчик выбирается по умолчанию если программа запускается как " +"systemd сервис." #: ../../source/logging.rst:58 msgid "`aiomisc.log.LogFormat.default()` will returns `journald` in this case." msgstr "`aiomisc.log.LogFormat.default()` вернет `journald` в этом случае." -#: ../../source/logging.rst:73 +#: ../../source/logging.rst:60 +msgid "" +"import logging\n" +"from aiomisc.log import basic_config\n" +"\n" +"# Configure rich log handler\n" +"basic_config(level=logging.INFO, buffered=False, log_format='journald')\n" +"\n" +"logging.info(\"JournalD log record\")" +msgstr "" + +#: ../../source/logging.rst:74 msgid "Rich" msgstr "Rich" -#: ../../source/logging.rst:75 +#: ../../source/logging.rst:76 msgid "" "`Rich`_ is a Python library for rich text and beautiful formatting in the" " terminal." msgstr "" -"`Rich`_ это Python библиотека которая делает форматирование в " -"терминал прекрасным." +"`Rich`_ это Python библиотека которая делает форматирование в терминал " +"прекрасным." -#: ../../source/logging.rst:77 +#: ../../source/logging.rst:78 msgid "" "`aiomisc.basic_config` has support for using `Rich`_ as a logging " "handler. But it isn't dependency and you have to install `Rich`_ " "manually." msgstr "" -"`aiomisc.basic_config` может использовать `Rich`_ для логирования. " -"Но это не обязательно, поэтому вам придется установить `Rich`_ самостоятельно." +"`aiomisc.basic_config` может использовать `Rich`_ для логирования. Но это" +" не обязательно, поэтому вам придется установить `Rich`_ самостоятельно." + +#: ../../source/logging.rst:81 +msgid "pip install rich" +msgstr "" -#: ../../source/logging.rst:86 +#: ../../source/logging.rst:87 msgid "This handler is the default when the `Rich` has been installed." msgstr "Этот обработчик будет обработчиком по умолчанию если `Rich` установлен." -#: ../../source/logging.rst:111 +#: ../../source/logging.rst:89 +msgid "" +"import logging\n" +"from aiomisc.log import basic_config\n" +"\n" +"# Configure rich log handler\n" +"basic_config(level=logging.INFO, buffered=False, log_format='rich')\n" +"\n" +"logging.info(\"Rich logger\")\n" +"\n" +"# Configure rich log handler with rich tracebacks display\n" +"basic_config(level=logging.INFO, buffered=False, log_format='rich_tb')\n" +"\n" +"try:\n" +" 1 / 0\n" +"except:\n" +" logging.exception(\"Rich traceback logger\")" +msgstr "" +"import logging\n" +"from aiomisc.log import basic_config\n" +"\n" +"# Конфигурируем rich обработчик для журналов\n" +"basic_config(level=logging.INFO, buffered=False, log_format='rich')\n" +"\n" +"logging.info(\"Rich logger\")\n" +"\n" +"# Конфигурируем rich обработчик для журналов но с показом трейсбеков\n" +"basic_config(level=logging.INFO, buffered=False, log_format='rich_tb')\n" +"\n" +"try:\n" +" 1 / 0\n" +"except:\n" +" logging.exception(\"Rich traceback logger\")" + +#: ../../source/logging.rst:112 msgid "Buffered log handler" msgstr "Буфферизирующий лог-хендлер" -#: ../../source/logging.rst:113 +#: ../../source/logging.rst:114 msgid "" "Parameter `buffered=True` enables a memory buffer that flushes logs in a " "thread." @@ -124,17 +199,79 @@ msgstr "" "Параметр `buffered=True` включает буферизацию логов в памяти, отдельный " "поток переодически сбрасывает логи в поток." -#: ../../source/logging.rst:151 +#: ../../source/logging.rst:116 +#, python-format +msgid "" +"import asyncio\n" +"import logging\n" +"from aiomisc.log import basic_config\n" +"from aiomisc.periodic import PeriodicCallback\n" +"from aiomisc.utils import new_event_loop\n" +"\n" +"\n" +"# Configure logging globally\n" +"basic_config(level=logging.INFO, buffered=False, log_format='json')\n" +"\n" +"async def write_log(loop):\n" +" logging.info(\"Hello %f\", loop.time())\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" # Configure\n" +" basic_config(\n" +" level=logging.INFO,\n" +" buffered=True,\n" +" log_format='color',\n" +" flush_interval=0.5\n" +" )\n" +"\n" +" periodic = PeriodicCallback(write_log, loop)\n" +" periodic.start(0.3)\n" +"\n" +" # Wait for flush just for example\n" +" loop.run_until_complete(asyncio.sleep(1))" +msgstr "" +"import asyncio\n" +"import logging\n" +"from aiomisc.log import basic_config\n" +"from aiomisc.periodic import PeriodicCallback\n" +"from aiomisc.utils import new_event_loop\n" +"\n" +"\n" +"# Глобально конфигурируем журналы\n" +"basic_config(level=logging.INFO, buffered=False, log_format='json')\n" +"\n" +"async def write_log(loop):\n" +" logging.info(\"Hello %f\", loop.time())\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" # Конфигурируем\n" +" basic_config(\n" +" level=logging.INFO,\n" +" buffered=True,\n" +" log_format='color',\n" +" flush_interval=0.5\n" +" )\n" +"\n" +" periodic = PeriodicCallback(write_log, loop)\n" +" periodic.start(0.3)\n" +"\n" +" # Ждем пока журналы не попадут в журнал\n" +" loop.run_until_complete(asyncio.sleep(1))" + +#: ../../source/logging.rst:152 msgid "``entrypoint`` accepts ``log_format`` parameter for configure it." msgstr "" "``entrypoint`` принимает аргумент ``log_format`` через который можно это " "настроить." -#: ../../source/logging.rst:153 +#: ../../source/logging.rst:154 msgid "" "List of all supported log formats is available from " "``aiomisc.log.LogFormat.choices()``" msgstr "" "Список всех поддерживаемых форматов журналов доступен через " "``aiomisc.log.LogFormat.choices()``" - diff --git a/docs/source/locale/ru/LC_MESSAGES/plugins.po b/docs/source/locale/ru/LC_MESSAGES/plugins.po index 9b15f36f..94365b51 100644 --- a/docs/source/locale/ru/LC_MESSAGES/plugins.po +++ b/docs/source/locale/ru/LC_MESSAGES/plugins.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-10-15 17:18+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/plugins.rst:2 msgid "Plugins" @@ -37,6 +37,19 @@ msgstr "" "должны добавить запись ``aiomisc.plugins`` к записи аргумента " "``entry_points`` вызова ``setup`` в ``setup.py`` вашего python пакета." +#: ../../source/plugins.rst:13 +msgid "" +"# setup.py\n" +"\n" +"setup(\n" +" # ...\n" +" entry_points={\n" +" \"aiomisc.plugins\": [\"myplugin = aiomisc_myplugin.plugin\"]\n" +" },\n" +" # ...\n" +")" +msgstr "" + #: ../../source/plugins.rst:26 msgid "" "Modules provided in ``entry_points`` should have ``setup`` function. " @@ -45,3 +58,30 @@ msgid "" msgstr "" "Модули, представленные в `entry_points``, должны иметь функцию ``setup``." " Эти функции будут вызываться aiomisc и должны поддерживать сигналы." + +#: ../../source/plugins.rst:29 +msgid "" +"from aiomisc import entrypoint\n" +"from threading import Event\n" +"\n" +"\n" +"event = Event()\n" +"\n" +"\n" +"async def hello(entrypoint, services):\n" +" print('Hello from aiomisc plugin')\n" +" event.set()\n" +"\n" +"\n" +"def setup():\n" +" entrypoint.PRE_START.connect(hello)\n" +"\n" +"setup()\n" +"\n" +"assert not event.is_set()\n" +"\n" +"with entrypoint() as loop:\n" +" pass\n" +"\n" +"assert event.is_set()" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/pool.po b/docs/source/locale/ru/LC_MESSAGES/pool.po index d56d307d..e7d91e5e 100644 --- a/docs/source/locale/ru/LC_MESSAGES/pool.po +++ b/docs/source/locale/ru/LC_MESSAGES/pool.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-10-15 17:18+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/pool.rst:2 msgid "Abstract connection pool" @@ -31,3 +31,42 @@ msgstr "" msgid "Example for ``aioredis``:" msgstr "Пример для ``aioredis``:" +#: ../../source/pool.rst:10 +msgid "" +"import asyncio\n" +"import aioredis\n" +"import aiomisc\n" +"\n" +"\n" +"class RedisPool(aiomisc.PoolBase):\n" +" def __init__(self, uri, maxsize=10, recycle=60):\n" +" super().__init__(maxsize=maxsize, recycle=recycle)\n" +" self.uri = uri\n" +"\n" +" async def _create_instance(self):\n" +" return await aioredis.create_redis(self.uri)\n" +"\n" +" async def _destroy_instance(self, instance: aioredis.Redis):\n" +" instance.close()\n" +" await instance.wait_closed()\n" +"\n" +" async def _check_instance(self, instance: aioredis.Redis):\n" +" try:\n" +" await asyncio.wait_for(instance.ping(1), timeout=0.5)\n" +" except:\n" +" return False\n" +"\n" +" return True\n" +"\n" +"\n" +"async def main():\n" +" pool = RedisPool(\"redis://localhost\")\n" +" async with pool.acquire() as connection:\n" +" await connection.set(\"foo\", \"bar\")\n" +"\n" +" async with pool.acquire() as connection:\n" +" print(await connection.get(\"foo\"))\n" +"\n" +"\n" +"asyncio.run(main())" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/process_pool.po b/docs/source/locale/ru/LC_MESSAGES/process_pool.po index dbb9c9e4..ece83618 100644 --- a/docs/source/locale/ru/LC_MESSAGES/process_pool.po +++ b/docs/source/locale/ru/LC_MESSAGES/process_pool.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-03 16:55+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/process_pool.rst:2 msgid "``ProcessPoolExecutor``" @@ -27,3 +27,34 @@ msgstr "Это простая реализация пула процессов." msgid "Example:" msgstr "Пример:" +#: ../../source/process_pool.rst:8 +msgid "" +"import asyncio\n" +"import time\n" +"import os\n" +"from aiomisc import ProcessPoolExecutor\n" +"\n" +"def process_inner():\n" +" for _ in range(10):\n" +" print(os.getpid())\n" +" time.sleep(1)\n" +"\n" +" return os.getpid()\n" +"\n" +"\n" +"loop = asyncio.get_event_loop()\n" +"process_pool = ProcessPoolExecutor(4)\n" +"\n" +"\n" +"async def main():\n" +" print(\n" +" await asyncio.gather(\n" +" loop.run_in_executor(process_pool, process_inner),\n" +" loop.run_in_executor(process_pool, process_inner),\n" +" loop.run_in_executor(process_pool, process_inner),\n" +" loop.run_in_executor(process_pool, process_inner),\n" +" )\n" +" )\n" +"\n" +"loop.run_until_complete(main())" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/pytest.po b/docs/source/locale/ru/LC_MESSAGES/pytest.po index 32aad4a6..d43ac64b 100644 --- a/docs/source/locale/ru/LC_MESSAGES/pytest.po +++ b/docs/source/locale/ru/LC_MESSAGES/pytest.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-12-14 22:58+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/pytest.rst:2 msgid "Pytest plugin" @@ -31,10 +31,37 @@ msgstr "Простой пример" msgid "Simple usage example:" msgstr "Простой пример использования:" +#: ../../source/pytest.rst:11 +msgid "" +"import asyncio\n" +"import pytest\n" +"\n" +"\n" +"async def test_sample(loop):\n" +" f = loop.crete_future()\n" +" loop.call_soon(f.set_result, True)\n" +"\n" +" assert await f" +msgstr "" + #: ../../source/pytest.rst:24 msgid "asynchronous fixture example:" msgstr "пример асинхронной фикстуры:" +#: ../../source/pytest.rst:27 +msgid "" +"import asyncio\n" +"import pytest\n" +"\n" +"\n" +"@pytest.fixture\n" +"async def my_fixture(loop):\n" +" await asyncio.sleep(0)\n" +"\n" +" # Requires python 3.6+\n" +" yield" +msgstr "" + #: ../../source/pytest.rst:40 msgid "" "In case you have to save an instance of an async fixture between tests, " @@ -47,16 +74,48 @@ msgid "" " the solution is to redefine the ``loop`` fixture with the required scope" " and custom fixture with the required scope." msgstr "" -"В случае, если вам необходимо сохранить экземпляр асинхронной фиксуры между " -"тестами, неправильным решением будет просто изменить scope фикстуры." -"Но почему это не сработает? Это связано с тем, что в базовом сценарии " -"фикстура ``loop`` создает новый экземпляр event-loop для каждого теста, и он " -"будет закрыт по завершении теста. Когда нужно использовать " -"асинхронную фикстуру, любой вызов ``asyncio.get_event_loop()`` вернет текущий " -"экземпляр event-loop, который будет закрыт, и следующий тест будет " -"выполняться в другом экземпляре event-loop." -"Таким образом, решение заключается в переопределении фикстуры ``loop`` " -"с требуемым scope и пользовательской фиктуры." +"В случае, если вам необходимо сохранить экземпляр асинхронной фиксуры " +"между тестами, неправильным решением будет просто изменить scope " +"фикстуры.Но почему это не сработает? Это связано с тем, что в базовом " +"сценарии фикстура ``loop`` создает новый экземпляр event-loop для каждого" +" теста, и он будет закрыт по завершении теста. Когда нужно использовать " +"асинхронную фикстуру, любой вызов ``asyncio.get_event_loop()`` вернет " +"текущий экземпляр event-loop, который будет закрыт, и следующий тест " +"будет выполняться в другом экземпляре event-loop.Таким образом, решение " +"заключается в переопределении фикстуры ``loop`` с требуемым scope и " +"пользовательской фиктуры." + +#: ../../source/pytest.rst:50 +msgid "" +"import asyncio\n" +"import pytest\n" +"from aiomisc import entrypoint\n" +"\n" +"\n" +"@pytest.fixture(scope='module')\n" +"def loop():\n" +" with entrypoint() as loop:\n" +" asyncio.set_event_loop(loop)\n" +" yield loop\n" +"\n" +"\n" +"@pytest.fixture(scope='module')\n" +"async def sample_fixture(loop):\n" +" yield 1\n" +"\n" +"\n" +"LOOP_ID = None\n" +"\n" +"\n" +"async def test_using_fixture(sample_fixture):\n" +" global LOOP_ID\n" +" LOOP_ID = id(asyncio.get_event_loop())\n" +" assert sample_fixture == 1\n" +"\n" +"\n" +"async def test_not_using_fixture(loop):\n" +" assert id(loop) == LOOP_ID" +msgstr "" #: ../../source/pytest.rst:83 msgid "pytest markers" @@ -82,10 +141,81 @@ msgstr "" "``forbid_get_event_loop`` - запрещает вызов ``asyncio.get_event_loop`` " "при прогоне теста." +#: ../../source/pytest.rst:91 +msgid "" +"import pytest\n" +"\n" +"\n" +"# Test will be failed\n" +"@pytest.mark.forbid_get_event_loop\n" +"async def test_with_get_loop():\n" +" def switch_context():\n" +" loop = get_event_loop()\n" +" future = loop.create_future()\n" +" loop.call_soon(future.set_result, True)\n" +" return future\n" +"\n" +" with pytest.raises(Failed):\n" +" await switch_context()\n" +"\n" +"\n" +"# Test will be failed\n" +"@pytest.mark.catch_loop_exceptions\n" +"async def test_with_errors(loop):\n" +" async def fail():\n" +" # switch context\n" +" await asyncio.sleep(0)\n" +" raise Exception()\n" +"\n" +" loop.create_task(fail())\n" +" await asyncio.sleep(0.1)\n" +" return" +msgstr "" +"import pytest\n" +"\n" +"\n" +"# Тест упадет\n" +"@pytest.mark.forbid_get_event_loop\n" +"async def test_with_get_loop():\n" +" def switch_context():\n" +" loop = get_event_loop()\n" +" future = loop.create_future()\n" +" loop.call_soon(future.set_result, True)\n" +" return future\n" +"\n" +" with pytest.raises(Failed):\n" +" await switch_context()\n" +"\n" +"\n" +"# Тест упадет\n" +"@pytest.mark.catch_loop_exceptions\n" +"async def test_with_errors(loop):\n" +" async def fail():\n" +" # переключаем контекст\n" +" await asyncio.sleep(0)\n" +" raise Exception()\n" +"\n" +" loop.create_task(fail())\n" +" await asyncio.sleep(0.1)\n" +" return" + #: ../../source/pytest.rst:123 msgid "Passing default context" msgstr "Передача контекста по умолчанию" +#: ../../source/pytest.rst:125 +msgid "" +"import pytest\n" +"\n" +"\n" +"@pytest.fixture\n" +"def default_context():\n" +" return {\n" +" 'foo': 'bar',\n" +" 'bar': 'foo',\n" +" }" +msgstr "" + #: ../../source/pytest.rst:139 msgid "Testing services" msgstr "Тестирование сервисов" @@ -94,22 +224,104 @@ msgstr "Тестирование сервисов" msgid "Redefine ``services`` fixture in your test module:" msgstr "Переопределите фикстуру ``services`` в вашем тестовом модуле:" +#: ../../source/pytest.rst:143 +msgid "" +"@pytest.fixture\n" +"def services(aiomisc_unused_port, handlers):\n" +" return [\n" +" RPCServer(\n" +" handlers={'foo': lambda: 'bar'},\n" +" address='localhost',\n" +" port=aiomisc_unused_port\n" +" )\n" +" ]" +msgstr "" + #: ../../source/pytest.rst:157 msgid "Event loop policy overriding" msgstr "Переопределение политики создания цикла событий" +#: ../../source/pytest.rst:159 +msgid "" +"import uvloop\n" +"import tokio\n" +"\n" +"policy_ids = ('uvloop', 'asyncio', 'tokio')\n" +"policies = (uvloop.EventLoopPolicy(),\n" +" asyncio.DefaultEventLoopPolicy(),\n" +" tokio.EventLoopPolicy())\n" +"\n" +"@pytest.fixture(params=policies, ids=policy_ids)\n" +"def event_loop_policy(request):\n" +" return request.param" +msgstr "" + #: ../../source/pytest.rst:175 msgid "Thread pool overriding" msgstr "Переопределение пула потоков" +#: ../../source/pytest.rst:177 +msgid "" +"thread_pool_ids = ('aiomisc pool', 'default pool')\n" +"thread_pool_implementation = (ThreadPoolExecutor,\n" +" concurrent.futures.ThreadPoolExecutor)\n" +"\n" +"\n" +"@pytest.fixture(params=thread_pool_implementation, ids=thread_pool_ids)\n" +"def thread_pool_executor(request):\n" +" return request.param" +msgstr "" + #: ../../source/pytest.rst:190 msgid "entrypoint arguments" msgstr "агрументы entrypoint" +#: ../../source/pytest.rst:192 +msgid "" +"import pytest\n" +"\n" +"@pytest.fixture\n" +"def entrypoint_kwargs() -> dict:\n" +" return dict(log_config=False)" +msgstr "" + #: ../../source/pytest.rst:202 msgid "aiohttp test client" msgstr "тестовый класс для aiohttp" +#: ../../source/pytest.rst:204 +msgid "" +"import pytest\n" +"from myapp.services.rest import REST\n" +"\n" +"\n" +"@pytest.fixture\n" +"def rest_port(aiomisc_unused_port_factory):\n" +" return aiomisc_unused_port_factory()\n" +"\n" +"\n" +"@pytest.fixture\n" +"def rest_service(rest_port):\n" +" return REST(port=rest_port)\n" +"\n" +"\n" +"@pytest.fixture\n" +"def services(rest_service):\n" +" return [rest_service]\n" +"\n" +"\n" +"@pytest.fixture\n" +"def api_client(api_service):\n" +" test_srv = TestServer(\n" +" app=rest_service.app,\n" +" port=arguments.port,\n" +" )\n" +"\n" +" return TestClient(test_srv)\n" +"\n" +"..." +msgstr "" + #: ../../source/pytest.rst:238 msgid "TCPProxy" msgstr "TCPProxy" @@ -126,3 +338,188 @@ msgstr "" msgid "Examples:" msgstr "Примеры:" +#: ../../source/pytest.rst:245 +msgid "" +"import asyncio\n" +"import time\n" +"\n" +"import pytest\n" +"\n" +"import aiomisc\n" +"\n" +"\n" +"class EchoServer(aiomisc.service.TCPServer):\n" +" async def handle_client(\n" +" self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter\n" +" ):\n" +" chunk = await reader.read(65534)\n" +" while chunk:\n" +" writer.write(chunk)\n" +" chunk = await reader.read(65534)\n" +"\n" +" writer.close()\n" +" await writer.wait_closed()\n" +"\n" +"\n" +"@pytest.fixture()\n" +"def server_port(aiomisc_unused_port_factory) -> int:\n" +" return aiomisc_unused_port_factory()\n" +"\n" +"\n" +"@pytest.fixture()\n" +"def services(server_port, localhost):\n" +" return [EchoServer(port=server_port, address=localhost)]\n" +"\n" +"\n" +"@pytest.fixture()\n" +"async def proxy(tcp_proxy, localhost, server_port):\n" +" async with tcp_proxy(localhost, server_port) as proxy:\n" +" yield proxy\n" +"\n" +"\n" +"async def test_proxy_client_close(proxy):\n" +" reader, writer = await proxy.create_client()\n" +" payload = b\"Hello world\"\n" +"\n" +" writer.write(payload)\n" +" response = await asyncio.wait_for(reader.read(1024), timeout=1)\n" +"\n" +" assert response == payload\n" +"\n" +" assert not reader.at_eof()\n" +" await proxy.disconnect_all()\n" +"\n" +" assert await asyncio.wait_for(reader.read(), timeout=1) == b\"\"\n" +" assert reader.at_eof()\n" +"\n" +"\n" +"async def test_proxy_client_slow(proxy):\n" +" read_delay = 0.1\n" +" write_delay = 0.2\n" +"\n" +" # Emulation of asymmetric and slow ISP\n" +" with proxy.slowdown(read_delay, write_delay):\n" +" reader, writer = await proxy.create_client()\n" +" payload = b\"Hello world\"\n" +"\n" +" delta = -time.monotonic()\n" +"\n" +" writer.write(payload)\n" +" await asyncio.wait_for(reader.read(1024), timeout=2)\n" +"\n" +" delta += time.monotonic()\n" +"\n" +" assert delta >= read_delay + write_delay\n" +"\n" +"\n" +"async def test_proxy_client_with_processor(proxy):\n" +" processed_request = b\"Never say hello\"\n" +"\n" +" # Patching protocol functions\n" +" proxy.set_content_processors(\n" +" # Process data from client to server\n" +" lambda _: processed_request,\n" +"\n" +" # Process data from server to client\n" +" lambda chunk: chunk[::-1],\n" +" )\n" +"\n" +" reader, writer = await proxy.create_client()\n" +" writer.write(b'nevermind')\n" +"\n" +" response = await reader.read(16)\n" +"\n" +" assert response == processed_request[::-1]" +msgstr "" +"import asyncio\n" +"import time\n" +"\n" +"import pytest\n" +"\n" +"import aiomisc\n" +"\n" +"\n" +"class EchoServer(aiomisc.service.TCPServer):\n" +" async def handle_client(\n" +" self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter\n" +" ):\n" +" chunk = await reader.read(65534)\n" +" while chunk:\n" +" writer.write(chunk)\n" +" chunk = await reader.read(65534)\n" +"\n" +" writer.close()\n" +" await writer.wait_closed()\n" +"\n" +"\n" +"@pytest.fixture()\n" +"def server_port(aiomisc_unused_port_factory) -> int:\n" +" return aiomisc_unused_port_factory()\n" +"\n" +"\n" +"@pytest.fixture()\n" +"def services(server_port, localhost):\n" +" return [EchoServer(port=server_port, address=localhost)]\n" +"\n" +"\n" +"@pytest.fixture()\n" +"async def proxy(tcp_proxy, localhost, server_port):\n" +" async with tcp_proxy(localhost, server_port) as proxy:\n" +" yield proxy\n" +"\n" +"\n" +"async def test_proxy_client_close(proxy):\n" +" reader, writer = await proxy.create_client()\n" +" payload = b\"Hello world\"\n" +"\n" +" writer.write(payload)\n" +" response = await asyncio.wait_for(reader.read(1024), timeout=1)\n" +"\n" +" assert response == payload\n" +"\n" +" assert not reader.at_eof()\n" +" await proxy.disconnect_all()\n" +"\n" +" assert await asyncio.wait_for(reader.read(), timeout=1) == b\"\"\n" +" assert reader.at_eof()\n" +"\n" +"\n" +"async def test_proxy_client_slow(proxy):\n" +" read_delay = 0.1\n" +" write_delay = 0.2\n" +"\n" +" # Эмулируем работу ассиметричного и медленного интернет провайдера\n" +" with proxy.slowdown(read_delay, write_delay):\n" +" reader, writer = await proxy.create_client()\n" +" payload = b\"Hello world\"\n" +"\n" +" delta = -time.monotonic()\n" +"\n" +" writer.write(payload)\n" +" await asyncio.wait_for(reader.read(1024), timeout=2)\n" +"\n" +" delta += time.monotonic()\n" +"\n" +" assert delta >= read_delay + write_delay\n" +"\n" +"\n" +"async def test_proxy_client_with_processor(proxy):\n" +" processed_request = b\"Never say hello\"\n" +"\n" +" # Патчим функции протокола\n" +" proxy.set_content_processors(\n" +" # Тут обработаем данные от клиента к серверу\n" +" lambda _: processed_request,\n" +"\n" +" # Тут обработаем данные от сервера к клиенту\n" +" lambda chunk: chunk[::-1],\n" +" )\n" +"\n" +" reader, writer = await proxy.create_client()\n" +" writer.write(b'nevermind')\n" +"\n" +" response = await reader.read(16)\n" +"\n" +" assert response == processed_request[::-1]" diff --git a/docs/source/locale/ru/LC_MESSAGES/services.po b/docs/source/locale/ru/LC_MESSAGES/services.po index eeca674b..a0304011 100644 --- a/docs/source/locale/ru/LC_MESSAGES/services.po +++ b/docs/source/locale/ru/LC_MESSAGES/services.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-12-29 08:09+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -54,6 +54,46 @@ msgstr "" "внутри метода ``start()``. Вместо этого используйте атрибут сервиса " "``self.loop``:" +#: ../../source/services.rst:19 +msgid "" +"import asyncio\n" +"from threading import Event\n" +"from aiomisc import entrypoint, Service\n" +"\n" +"event = Event()\n" +"\n" +"class MyService(Service):\n" +" async def start(self):\n" +" # Send signal to entrypoint for continue running\n" +" self.start_event.set()\n" +"\n" +" event.set()\n" +" # Start service task\n" +" await asyncio.sleep(3600)\n" +"\n" +"\n" +"with entrypoint(MyService()) as loop:\n" +" assert event.is_set()" +msgstr "" +"import asyncio\n" +"from threading import Event\n" +"from aiomisc import entrypoint, Service\n" +"\n" +"event = Event()\n" +"\n" +"class MyService(Service):\n" +" async def start(self):\n" +" # Отправляем сигнал в entrypoint что можно продолжать\n" +" self.start_event.set()\n" +"\n" +" event.set()\n" +" # Запуск чего-то полезного\n" +" await asyncio.sleep(3600)\n" +"\n" +"\n" +"with entrypoint(MyService()) as loop:\n" +" assert event.is_set()" + #: ../../source/services.rst:42 msgid "" "Method ``start()`` creates as a separate task that can run forever. But " @@ -94,6 +134,44 @@ msgstr "" "реализуйте ``handle_client(reader, writer)``, чтобы принимать TCP " "соединения." +#: ../../source/services.rst:61 +msgid "" +"import asyncio\n" +"import logging\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import TCPServer\n" +"\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"\n" +"class EchoServer(TCPServer):\n" +" async def handle_client(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter):\n" +" while not reader.at_eof():\n" +" writer.write(await reader.read(255))\n" +"\n" +" log.info(\"Client connection closed\")\n" +"\n" +"\n" +"async def echo_client(host, port):\n" +" reader, writer = await asyncio.open_connection(host=host, port=port)\n" +" writer.write(b\"hello\\n\")\n" +" assert await reader.readline() == b\"hello\\n\"\n" +"\n" +" writer.write(b\"world\\n\")\n" +" assert await reader.readline() == b\"world\\n\"\n" +"\n" +" writer.close()\n" +" await writer.wait_closed()\n" +"\n" +"\n" +"with entrypoint(\n" +" EchoServer(address='::1', port=8901),\n" +") as loop:\n" +" loop.run_until_complete(echo_client(\"::1\", 8901))" +msgstr "" + #: ../../source/services.rst:103 msgid "``UDPServer``" msgstr "Класс ``UDPServer``" @@ -107,6 +185,17 @@ msgstr "" "реализуйте ``handle_datagram(data, addr)``, чтобы принимать UDP " "соединения." +#: ../../source/services.rst:108 +msgid "" +"class UDPPrinter(UDPServer):\n" +" async def handle_datagram(self, data: bytes, addr):\n" +" print(addr, '->', data)\n" +"\n" +"\n" +"with entrypoint(UDPPrinter(address='::1', port=3000)) as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/services.rst:120 msgid "``TLSServer``" msgstr "Класс ``TLSServer``" @@ -119,6 +208,27 @@ msgstr "" "TLSServer - это базовый класс для написания TCP-серверов с использованием" " TLS. Просто реализуйте ``handle_client(reader, writer)``." +#: ../../source/services.rst:125 +msgid "" +"class SecureEchoServer(TLSServer):\n" +" async def handle_client(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter):\n" +" while True:\n" +" writer.write(await reader.readline())\n" +"\n" +"service = SecureEchoServer(\n" +" address='::1',\n" +" port=8900,\n" +" ca='ca.pem',\n" +" cert='cert.pem',\n" +" key='key.pem',\n" +" verify=False,\n" +")\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/services.rst:149 msgid "``TCPClient``" msgstr "" @@ -132,6 +242,47 @@ msgstr "" "реализуйте ``handle_client(reader, writer)``, чтобы принимать TCP " "соединения." +#: ../../source/services.rst:154 +msgid "" +"import asyncio\n" +"import logging\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import TCPServer, TCPClient\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"\n" +"class EchoServer(TCPServer):\n" +" async def handle_client(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter):\n" +" while not reader.at_eof():\n" +" writer.write(await reader.read(255))\n" +"\n" +" log.info(\"Client connection closed\")\n" +"\n" +"\n" +"class EchoClient(TCPClient):\n" +"\n" +" async def handle_connection(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter) -> None:\n" +" writer.write(b\"hello\\n\")\n" +" assert await reader.readline() == b\"hello\\n\"\n" +"\n" +" writer.write(b\"world\\n\")\n" +" assert await reader.readline() == b\"world\\n\"\n" +"\n" +" writer.write_eof()\n" +" writer.close()\n" +" await writer.wait_closed()\n" +"\n" +"\n" +"with entrypoint(\n" +" EchoServer(address='::1', port=8901),\n" +" EchoClient(address='::1', port=8901),\n" +") as loop:\n" +" loop.run_until_complete(asyncio.sleep(0.1))" +msgstr "" + #: ../../source/services.rst:197 msgid "``TLSClient``" msgstr "" @@ -145,6 +296,57 @@ msgstr "" "реализуйте ``handle_client(reader, writer)``, чтобы принимать TCP " "соединения." +#: ../../source/services.rst:202 +msgid "" +"import asyncio\n" +"import logging\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import TCPServer, TCPClient\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"\n" +"class EchoServer(TLSServer):\n" +" async def handle_client(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter):\n" +" while not reader.at_eof():\n" +" writer.write(await reader.read(255))\n" +"\n" +" log.info(\"Client connection closed\")\n" +"\n" +"\n" +"class EchoClient(TLSClient):\n" +"\n" +" async def handle_connection(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter) -> None:\n" +" writer.write(b\"hello\\n\")\n" +" assert await reader.readline() == b\"hello\\n\"\n" +"\n" +" writer.write(b\"world\\n\")\n" +" assert await reader.readline() == b\"world\\n\"\n" +"\n" +" writer.write_eof()\n" +" writer.close()\n" +" await writer.wait_closed()\n" +"\n" +"\n" +"with entrypoint(\n" +" EchoServer(\n" +" address='::1', port=8901,\n" +" ca='ca.pem',\n" +" cert='server.pem',\n" +" key='server.key',\n" +" ),\n" +" EchoClient(\n" +" address='::1', port=8901,\n" +" ca='ca.pem',\n" +" cert='client.pem',\n" +" key='client.key',\n" +" ),\n" +") as loop:\n" +" loop.run_until_complete(asyncio.sleep(0.1))" +msgstr "" + #: ../../source/services.rst:254 msgid "``RobustTCPClient``" msgstr "" @@ -158,6 +360,47 @@ msgstr "" "TLSServer - это базовый класс для написания TCP-серверов с использованием" " TLS. Просто реализуйте ``handle_client(reader, writer)``." +#: ../../source/services.rst:260 +msgid "" +"import asyncio\n" +"import logging\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import TCPServer, RobustTCPClient\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"\n" +"class EchoServer(TCPServer):\n" +" async def handle_client(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter):\n" +" while not reader.at_eof():\n" +" writer.write(await reader.read(255))\n" +"\n" +" log.info(\"Client connection closed\")\n" +"\n" +"\n" +"class EchoClient(RobustTCPClient):\n" +"\n" +" async def handle_connection(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter) -> None:\n" +" writer.write(b\"hello\\n\")\n" +" assert await reader.readline() == b\"hello\\n\"\n" +"\n" +" writer.write(b\"world\\n\")\n" +" assert await reader.readline() == b\"world\\n\"\n" +"\n" +" writer.write_eof()\n" +" writer.close()\n" +" await writer.wait_closed()\n" +"\n" +"\n" +"with entrypoint(\n" +" EchoServer(address='::1', port=8901),\n" +" EchoClient(address='::1', port=8901),\n" +") as loop:\n" +" loop.run_until_complete(asyncio.sleep(0.1))" +msgstr "" + #: ../../source/services.rst:303 msgid "``RobustTLSClient``" msgstr "" @@ -171,6 +414,57 @@ msgstr "" "TLSServer - это базовый класс для написания TCP-серверов с использованием" " TLS. Просто реализуйте ``handle_client(reader, writer)``." +#: ../../source/services.rst:309 +msgid "" +"import asyncio\n" +"import logging\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import TCPServer, RobustTCPClient\n" +"\n" +"log = logging.getLogger(__name__)\n" +"\n" +"\n" +"class EchoServer(TLSServer):\n" +" async def handle_client(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter):\n" +" while not reader.at_eof():\n" +" writer.write(await reader.read(255))\n" +"\n" +" log.info(\"Client connection closed\")\n" +"\n" +"\n" +"class EchoClient(RobustTLSClient):\n" +"\n" +" async def handle_connection(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter) -> None:\n" +" writer.write(b\"hello\\n\")\n" +" assert await reader.readline() == b\"hello\\n\"\n" +"\n" +" writer.write(b\"world\\n\")\n" +" assert await reader.readline() == b\"world\\n\"\n" +"\n" +" writer.write_eof()\n" +" writer.close()\n" +" await writer.wait_closed()\n" +"\n" +"\n" +"with entrypoint(\n" +" EchoServer(\n" +" address='::1', port=8901,\n" +" ca='ca.pem',\n" +" cert='server.pem',\n" +" key='server.key',\n" +" ),\n" +" EchoClient(\n" +" address='::1', port=8901,\n" +" ca='ca.pem',\n" +" cert='client.pem',\n" +" key='client.key',\n" +" ),\n" +") as loop:\n" +" loop.run_until_complete(asyncio.sleep(0.1))" +msgstr "" + #: ../../source/services.rst:363 msgid "``PeriodicService``" msgstr "Класс ``PeriodicService``" @@ -197,6 +491,36 @@ msgstr "" "запуска в секундах и необязательный аргумент ``delay`` - задержку первого" " выполнения в секундах (по умолчанию 0)." +#: ../../source/services.rst:373 +msgid "" +"import aiomisc\n" +"from aiomisc.service.periodic import PeriodicService\n" +"\n" +"\n" +"class MyPeriodicService(PeriodicService):\n" +" async def callback(self):\n" +" log.info('Running periodic callback')\n" +" # ...\n" +"\n" +"service = MyPeriodicService(interval=3600, delay=0) # once per hour\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" +msgstr "" +"import aiomisc\n" +"from aiomisc.service.periodic import PeriodicService\n" +"\n" +"\n" +"class MyPeriodicService(PeriodicService):\n" +" async def callback(self):\n" +" log.info('Running periodic callback')\n" +" # ...\n" +"\n" +"service = MyPeriodicService(interval=3600, delay=0) # раз в час\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" + #: ../../source/services.rst:393 msgid "``CronService``" msgstr "Класс ``CronService``" @@ -221,11 +545,52 @@ msgstr "" msgid "requires installed croniter_:" msgstr "необходимо установить библиотеку croniter_:" +#: ../../source/services.rst:406 +#, fuzzy +msgid "pip install croniter" +msgstr "необходимо установить библиотеку croniter_:" + #: ../../source/services.rst:410 ../../source/services.rst:552 #: ../../source/services.rst:618 msgid "or using extras:" msgstr "или как дополнительную зависимость" +#: ../../source/services.rst:412 +msgid "pip install aiomisc[cron]" +msgstr "" + +#: ../../source/services.rst:417 +msgid "" +"import aiomisc\n" +"from aiomisc.service.cron import CronService\n" +"\n" +"\n" +"async def callback():\n" +" log.info('Running cron callback')\n" +" # ...\n" +"\n" +"service = CronService()\n" +"service.register(callback, spec=\"0 * * * *\") # every hour at zero " +"minutes\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" +msgstr "" +"import aiomisc\n" +"from aiomisc.service.cron import CronService\n" +"\n" +"\n" +"async def callback():\n" +" log.info('Running cron callback')\n" +" # ...\n" +"\n" +"service = CronService()\n" +"service.register(callback, spec=\"0 * * * *\") # каждый час в 0 минут " +"minutes\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" + #: ../../source/services.rst:434 msgid "" "You can also inherit from ``CronService``, but remember that callback " @@ -234,6 +599,27 @@ msgstr "" "Вы также можете наследовать от ``CronService``, но помните, что " "регистрация обратного вызова должна выполняться до запуска" +#: ../../source/services.rst:437 +msgid "" +"import aiomisc\n" +"from aiomisc.service.cron import CronService\n" +"\n" +"\n" +"class MyCronService(CronService):\n" +" async def callback(self):\n" +" log.info('Running cron callback')\n" +" # ...\n" +"\n" +" async def start(self):\n" +" self.register(self.callback, spec=\"0 * * * *\")\n" +" await super().start()\n" +"\n" +"service = MyCronService()\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/services.rst:459 msgid "Multiple services" msgstr "Несколько сервисов" @@ -249,6 +635,41 @@ msgstr "" "корректно закрыты вызовом метода ``stop()`` или через отмену метода " "``start()``." +#: ../../source/services.rst:464 +msgid "" +"import asyncio\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import Service, TCPServer, UDPServer\n" +"\n" +"\n" +"class LoggingService(PeriodicService):\n" +" async def callabck(self):\n" +" print('Hello from service', self.name)\n" +"\n" +"\n" +"class EchoServer(TCPServer):\n" +" async def handle_client(self, reader: asyncio.StreamReader,\n" +" writer: asyncio.StreamWriter):\n" +" while True:\n" +" writer.write(await reader.readline())\n" +"\n" +"\n" +"class UDPPrinter(UDPServer):\n" +" async def handle_datagram(self, data: bytes, addr):\n" +" print(addr, '->', data)\n" +"\n" +"\n" +"services = (\n" +" LoggingService(name='#1', interval=1),\n" +" EchoServer(address='::1', port=8901),\n" +" UDPPrinter(address='::1', port=3000),\n" +")\n" +"\n" +"\n" +"with entrypoint(*services) as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/services.rst:500 msgid "Configuration" msgstr "Конфигурация" @@ -261,18 +682,132 @@ msgstr "" "Метакласс ``Service`` принимает все именованные аргументы в ``__init__`` " "и устанавливает из как атрибуты в ``self``." +#: ../../source/services.rst:505 +msgid "" +"import asyncio\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import Service, TCPServer, UDPServer\n" +"\n" +"\n" +"class LoggingService(Service):\n" +" # required kwargs\n" +" __required__ = frozenset({'name'})\n" +"\n" +" # default value\n" +" delay: int = 1\n" +"\n" +" async def start(self):\n" +" self.start_event.set()\n" +" while True:\n" +" # attribute ``name`` from kwargs\n" +" # must be defined when instance initializes\n" +" print('Hello from service', self.name)\n" +"\n" +" # attribute ``delay`` from kwargs\n" +" await asyncio.sleep(self.delay)\n" +"\n" +"services = (\n" +" LoggingService(name='#1'),\n" +" LoggingService(name='#2', delay=3),\n" +")\n" +"\n" +"\n" +"with entrypoint(*services) as loop:\n" +" loop.run_forever()" +msgstr "" +"import asyncio\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import Service, TCPServer, UDPServer\n" +"\n" +"\n" +"class LoggingService(Service):\n" +" # обязательные именованные аргументы \n" +" __required__ = frozenset({'name'})\n" +"\n" +" # default value\n" +" delay: int = 1\n" +"\n" +" async def start(self):\n" +" self.start_event.set()\n" +" while True:\n" +" # аттрибут ``name`` из именованных аргументов\n" +" # должен быть передан при создании экземпляра\n" +" print('Hello from service', self.name)\n" +"\n" +" # аттрибут ``delay`` из именованных аргументов\n" +" await asyncio.sleep(self.delay)\n" +"\n" +"services = (\n" +" LoggingService(name='#1'),\n" +" LoggingService(name='#2', delay=3),\n" +")\n" +"\n" +"\n" +"with entrypoint(*services) as loop:\n" +" loop.run_forever()" + #: ../../source/services.rst:542 msgid "aiohttp service" msgstr "aiohttp сервис" #: ../../source/services.rst:546 msgid "requires installed aiohttp:" -msgstr "требуется установленная библиоткеа aiohttp" +msgstr "требуется установленная библиотека aiohttp" + +#: ../../source/services.rst:548 +#, fuzzy +msgid "pip install aiohttp" +msgstr "требуется установленная библиотека aiohttp" + +#: ../../source/services.rst:554 +#, fuzzy +msgid "pip install aiomisc[aiohttp]" +msgstr "требуется установленная библиотека aiohttp" #: ../../source/services.rst:559 msgid "aiohttp application can be started as a service:" msgstr "Приложение aiohttp может быть запущено как сервис:" +#: ../../source/services.rst:561 +msgid "" +"import aiohttp.web\n" +"import argparse\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service.aiohttp import AIOHTTPService\n" +"\n" +"parser = argparse.ArgumentParser()\n" +"group = parser.add_argument_group('HTTP options')\n" +"\n" +"group.add_argument(\"-l\", \"--address\", default=\"::\",\n" +" help=\"Listen HTTP address\")\n" +"group.add_argument(\"-p\", \"--port\", type=int, default=8080,\n" +" help=\"Listen HTTP port\")\n" +"\n" +"\n" +"async def handle(request):\n" +" name = request.match_info.get('name', \"Anonymous\")\n" +" text = \"Hello, \" + name\n" +" return aiohttp.web.Response(text=text)\n" +"\n" +"\n" +"class REST(AIOHTTPService):\n" +" async def create_application(self):\n" +" app = aiohttp.web.Application()\n" +"\n" +" app.add_routes([\n" +" aiohttp.web.get('/', handle),\n" +" aiohttp.web.get('/{name}', handle)\n" +" ])\n" +"\n" +" return app\n" +"\n" +"arguments = parser.parse_args()\n" +"service = REST(address=arguments.address, port=arguments.port)\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/services.rst:601 msgid "" "Class ``AIOHTTPSSLService`` is similar to ``AIOHTTPService`` but creates " @@ -289,12 +824,59 @@ msgstr "asgi сервис" #: ../../source/services.rst:612 msgid "requires installed aiohttp-asgi:" -msgstr "требуется установленная библиоткеа aiohttp-asgi:" +msgstr "требуется установленная библиотека aiohttp-asgi:" + +#: ../../source/services.rst:614 +#, fuzzy +msgid "pip install aiohttp-asgi" +msgstr "требуется установленная библиотека aiohttp-asgi:" + +#: ../../source/services.rst:620 +msgid "pip install aiomisc[asgi]" +msgstr "" #: ../../source/services.rst:625 msgid "Any ASGI-like application can be started as a service:" msgstr "Любое ASGI совместимое приложение может быть запущено как сервис:" +#: ../../source/services.rst:627 +msgid "" +"import argparse\n" +"\n" +"from fastapi import FastAPI\n" +"\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service.asgi import ASGIHTTPService, ASGIApplicationType\n" +"\n" +"parser = argparse.ArgumentParser()\n" +"group = parser.add_argument_group('HTTP options')\n" +"\n" +"group.add_argument(\"-l\", \"--address\", default=\"::\",\n" +" help=\"Listen HTTP address\")\n" +"group.add_argument(\"-p\", \"--port\", type=int, default=8080,\n" +" help=\"Listen HTTP port\")\n" +"\n" +"\n" +"app = FastAPI()\n" +"\n" +"\n" +"@app.get(\"/\")\n" +"async def root():\n" +" return {\"message\": \"Hello World\"}\n" +"\n" +"\n" +"class REST(ASGIHTTPService):\n" +" async def create_asgi_app(self) -> ASGIApplicationType:\n" +" return app\n" +"\n" +"\n" +"arguments = parser.parse_args()\n" +"service = REST(address=arguments.address, port=arguments.port)\n" +"\n" +"with entrypoint(service) as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/services.rst:665 msgid "" "Class ``ASGIHTTPSSLService`` is similar to ``ASGIHTTPService`` but " @@ -317,10 +899,52 @@ msgstr "" "Простой и полезный сервис для логирования больших объектов Python, " "размещенных в памяти." +#: ../../source/services.rst:678 +msgid "" +"import asyncio\n" +"import os\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import MemoryTracer\n" +"\n" +"\n" +"async def main():\n" +" leaking = []\n" +"\n" +" while True:\n" +" leaking.append(os.urandom(128))\n" +" await asyncio.sleep(0)\n" +"\n" +"\n" +"with entrypoint(MemoryTracer(interval=1, top_results=5)) as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + #: ../../source/services.rst:698 ../../source/services.rst:747 msgid "Output example:" msgstr "Пример вывода:" +#: ../../source/services.rst:700 +msgid "" +"[T:[1] Thread Pool] INFO:aiomisc.service.tracer: Top memory usage:\n" +" Objects | Obj.Diff | Memory | Mem.Diff | Traceback\n" +" 12 | 12 | 1.9KiB | 1.9KiB | aiomisc/periodic.py:40\n" +" 12 | 12 | 1.8KiB | 1.8KiB | aiomisc/entrypoint.py:93\n" +" 6 | 6 | 1.1KiB | 1.1KiB | aiomisc/thread_pool.py:71\n" +" 2 | 2 | 976.0B | 976.0B | aiomisc/thread_pool.py:44\n" +" 5 | 5 | 712.0B | 712.0B | aiomisc/thread_pool.py:52\n" +"\n" +"[T:[6] Thread Pool] INFO:aiomisc.service.tracer: Top memory usage:\n" +" Objects | Obj.Diff | Memory | Mem.Diff | Traceback\n" +" 43999 | 43999 | 7.1MiB | 7.1MiB | scratches/scratch_8.py:11\n" +" 47 | 47 | 4.7KiB | 4.7KiB | " +"env/bin/../lib/python3.7/abc.py:143\n" +" 33 | 33 | 2.8KiB | 2.8KiB | " +"3.7/lib/python3.7/tracemalloc.py:113\n" +" 44 | 44 | 2.4KiB | 2.4KiB | " +"3.7/lib/python3.7/tracemalloc.py:185\n" +" 14 | 14 | 2.4KiB | 2.4KiB | aiomisc/periodic.py:40" +msgstr "" + #: ../../source/services.rst:722 msgid "Profiler" msgstr "``Profiler`` - профилировщик" @@ -337,6 +961,41 @@ msgstr "" "позже могут быть использованы, например, snakeviz. Также можно изменить " "порядок с аргументом ``order`` (по умолчанию \"cumulative\")." +#: ../../source/services.rst:730 +msgid "" +"import asyncio\n" +"import os\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service import Profiler\n" +"\n" +"\n" +"async def main():\n" +" for i in range(100):\n" +" time.sleep(0.01)\n" +"\n" +"\n" +"with entrypoint(Profiler(interval=0.1, top_results=5)) as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + +#: ../../source/services.rst:749 +msgid "" +"108 function calls in 1.117 seconds\n" +"\n" +"Ordered by: cumulative time\n" +"\n" +"ncalls tottime percall cumtime percall filename:lineno(function)\n" +" 100 1.117 0.011 1.117 0.011 {built-in method time.sleep}\n" +" 1 0.000 0.000 0.000 0.000 " +"<...>/lib/python3.7/pstats.py:89(__init__)\n" +" 1 0.000 0.000 0.000 0.000 " +"<...>/lib/python3.7/pstats.py:99(init)\n" +" 1 0.000 0.000 0.000 0.000 " +"<...>/lib/python3.7/pstats.py:118(load_stats)\n" +" 1 0.000 0.000 0.000 0.000 " +"<...>/lib/python3.7/cProfile.py:50(create_stats)" +msgstr "" + #: ../../source/services.rst:766 msgid "Raven service" msgstr "Raven сервис" @@ -351,10 +1010,206 @@ msgstr "Простой сервис для отправки необработа msgid "Simple example:" msgstr "Простой пример:" +#: ../../source/services.rst:775 +msgid "" +"import asyncio\n" +"import logging\n" +"import sys\n" +"\n" +"from aiomisc import entrypoint\n" +"from aiomisc.version import __version__\n" +"from aiomisc.service.raven import RavenSender\n" +"\n" +"\n" +"async def main():\n" +" while True:\n" +" await asyncio.sleep(1)\n" +"\n" +" try:\n" +" 1 / 0\n" +" except ZeroDivisionError:\n" +" logging.exception(\"Exception\")\n" +"\n" +"\n" +"raven_sender = RavenSender(\n" +" sentry_dsn=(\n" +" " +"\"https://583ca3b555054f80873e751e8139e22a@o429974.ingest.sentry.io/\"\n" +" \"5530251\"\n" +" ),\n" +" client_options=dict(\n" +" # Got environment variable SENTRY_NAME by default\n" +" name=\"example-from-aiomisc\",\n" +" # Got environment variable SENTRY_ENVIRONMENT by default\n" +" environment=\"simple_example\",\n" +" # Got environment variable SENTRY_RELEASE by default\n" +" release=__version__,\n" +" )\n" +")\n" +"\n" +"\n" +"with entrypoint(raven_sender) as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"import asyncio\n" +"import logging\n" +"import sys\n" +"\n" +"from aiomisc import entrypoint\n" +"from aiomisc.version import __version__\n" +"from aiomisc.service.raven import RavenSender\n" +"\n" +"\n" +"async def main():\n" +" while True:\n" +" await asyncio.sleep(1)\n" +"\n" +" try:\n" +" 1 / 0\n" +" except ZeroDivisionError:\n" +" logging.exception(\"Exception\")\n" +"\n" +"\n" +"raven_sender = RavenSender(\n" +" sentry_dsn=(\n" +" " +"\"https://583ca3b555054f80873e751e8139e22a@o429974.ingest.sentry.io/\"\n" +" \"5530251\"\n" +" ),\n" +" client_options=dict(\n" +" # По умолчанию возьмет значение переменной окружения SENTRY_NAME\n" +" name=\"example-from-aiomisc\",\n" +" # По умолчанию возьмет значение переменной окружения SENTRY_ENVIRONMENT\n" +" environment=\"simple_example\",\n" +" # По умолчанию возьмет значение переменной окружения SENTRY_RELEASE\n" +" release=__version__,\n" +" )\n" +")\n" +"\n" +"\n" +"with entrypoint(raven_sender) as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/services.rst:815 msgid "Full configuration:" msgstr "Все опции для клиента:" +#: ../../source/services.rst:817 +msgid "" +"import asyncio\n" +"import logging\n" +"import sys\n" +"\n" +"from aiomisc import entrypoint\n" +"from aiomisc.version import __version__\n" +"from aiomisc.service.raven import RavenSender\n" +"\n" +"\n" +"async def main():\n" +" while True:\n" +" await asyncio.sleep(1)\n" +"\n" +" try:\n" +" 1 / 0\n" +" except ZeroDivisionError:\n" +" logging.exception(\"Exception\")\n" +"\n" +"\n" +"raven_sender = RavenSender(\n" +" sentry_dsn=(\n" +" " +"\"https://583ca3b555054f80873e751e8139e22a@o429974.ingest.sentry.io/\"\n" +" \"5530251\"\n" +" ),\n" +" client_options=dict(\n" +" # Got environment variable SENTRY_NAME by default\n" +" name=\"\",\n" +" # Got environment variable SENTRY_ENVIRONMENT by default\n" +" environment=\"full_example\",\n" +" # Got environment variable SENTRY_RELEASE by default\n" +" release=__version__,\n" +"\n" +" # Default options values\n" +" include_paths=set(),\n" +" exclude_paths=set(),\n" +" auto_log_stacks=True,\n" +" capture_locals=True,\n" +" string_max_length=400,\n" +" list_max_length=50,\n" +" site=None,\n" +" include_versions=True,\n" +" processors=(\n" +" 'raven.processors.SanitizePasswordsProcessor',\n" +" ),\n" +" sanitize_keys=None,\n" +" context={'sys.argv': getattr(sys, 'argv', [])[:]},\n" +" tags={},\n" +" sample_rate=1,\n" +" ignore_exceptions=(),\n" +" )\n" +")\n" +"\n" +"\n" +"with entrypoint(raven_sender) as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"import asyncio\n" +"import logging\n" +"import sys\n" +"\n" +"from aiomisc import entrypoint\n" +"from aiomisc.version import __version__\n" +"from aiomisc.service.raven import RavenSender\n" +"\n" +"\n" +"async def main():\n" +" while True:\n" +" await asyncio.sleep(1)\n" +"\n" +" try:\n" +" 1 / 0\n" +" except ZeroDivisionError:\n" +" logging.exception(\"Exception\")\n" +"\n" +"\n" +"raven_sender = RavenSender(\n" +" sentry_dsn=(\n" +" " +"\"https://583ca3b555054f80873e751e8139e22a@o429974.ingest.sentry.io/\"\n" +" \"5530251\"\n" +" ),\n" +" client_options=dict(\n" +" # По умолчанию возьмет значение переменной окружения SENTRY_NAME\n" +" name=\"\",\n" +" # По умолчанию возьмет значение переменной окружения SENTRY_ENVIRONMENT\n" +" environment=\"full_example\",\n" +" # По умолчанию возьмет значение переменной окружения SENTRY_RELEASE\n" +" release=__version__,\n" +"\n" +" # Умолчания для остальных аргументов\n" +" include_paths=set(),\n" +" exclude_paths=set(),\n" +" auto_log_stacks=True,\n" +" capture_locals=True,\n" +" string_max_length=400,\n" +" list_max_length=50,\n" +" site=None,\n" +" include_versions=True,\n" +" processors=(\n" +" 'raven.processors.SanitizePasswordsProcessor',\n" +" ),\n" +" sanitize_keys=None,\n" +" context={'sys.argv': getattr(sys, 'argv', [])[:]},\n" +" tags={},\n" +" sample_rate=1,\n" +" ignore_exceptions=(),\n" +" )\n" +")\n" +"\n" +"\n" +"with entrypoint(raven_sender) as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/services.rst:875 msgid "" "You will find the full specification of options in the `Raven " @@ -388,10 +1243,86 @@ msgstr "" msgid "Example of python file:" msgstr "Пример python файла:" +#: ../../source/services.rst:891 +msgid "" +"import logging\n" +"from time import sleep\n" +"\n" +"from aiomisc import entrypoint\n" +"from aiomisc.service.sdwatchdog import SDWatchdogService\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with entrypoint(SDWatchdogService()) as loop:\n" +" pass" +msgstr "" + #: ../../source/services.rst:906 msgid "Example of systemd service file:" msgstr "Пример systemd сервис-файла:" +#: ../../source/services.rst:908 +msgid "" +"[Service]\n" +"# Activating the notification mechanism\n" +"Type=notify\n" +"\n" +"# Command which should be started\n" +"ExecStart=/home/mosquito/.venv/aiomisc/bin/python " +"/home/mosquito/scratch.py\n" +"\n" +"# The time for which the program must send a watchdog notification\n" +"WatchdogSec=5\n" +"\n" +"# Kill the process if it has stopped responding to the watchdog timer\n" +"WatchdogSignal=SIGKILL\n" +"\n" +"# The service should be restarted on failure\n" +"Restart=on-failure\n" +"\n" +"# Try to kill the process instead of cgroup\n" +"KillMode=process\n" +"\n" +"# Trying to stop service properly\n" +"KillSignal=SIGINT\n" +"\n" +"# Trying to restart service properly\n" +"RestartKillSignal=SIGINT\n" +"\n" +"# Send SIGKILL when timeouts are exceeded\n" +"FinalKillSignal=SIGKILL\n" +"SendSIGKILL=yes" +msgstr "" +"[Service]\n" +"# Активизируем механизм уведомлений\n" +"Type=notify\n" +"\n" +"# Команда которую следует запускать\n" +"ExecStart=/home/mosquito/.venv/aiomisc/bin/python " +"/home/mosquito/scratch.py\n" +"\n" +"# Время через которое программа должны посылать нотификации сторожевого таймера\n" +"WatchdogSec=5\n" +"\n" +"# Процесс будет убит если он перестал отвечать сторожевому таймеру\n" +"WatchdogSignal=SIGKILL\n" +"\n" +"# Сервис будет перезапущен в случае ошибки\n" +"Restart=on-failure\n" +"\n" +"# Пробуем убить сам процесс вместо всей cgroup\n" +"KillMode=process\n" +"\n" +"# Пробуем остановить сервис \"помягче\"\n" +"KillSignal=SIGINT\n" +"\n" +"# Пробуем остановить сервис \"помягче\" при перезапуске\n" +"RestartKillSignal=SIGINT\n" +"\n" +"# Слать SIGKILL если произошел таймаут остановки\n" +"FinalKillSignal=SIGKILL\n" +"SendSIGKILL=yes" + #: ../../source/services.rst:943 msgid "``ProcessService``" msgstr "Класс ``ProcessService``" @@ -404,6 +1335,82 @@ msgstr "" "Базовый класс для запуска функции отдельным системным процессом и " "завершения при остановке родительского процесса." +#: ../../source/services.rst:948 +msgid "" +"from typing import Dict, Any\n" +"\n" +"import aiomisc.service\n" +"\n" +"# Fictional miner implementation\n" +"from .my_miner import Miner\n" +"\n" +"\n" +"class MiningService(aiomisc.service.ProcessService):\n" +" bitcoin: bool = False\n" +" monero: bool = False\n" +" dogiecoin: bool = False\n" +"\n" +" def in_process(self) -> Any:\n" +" if self.bitcoin:\n" +" miner = Miner(kind=\"bitcoin\")\n" +" elif self.monero:\n" +" miner = Miner(kind=\"monero\")\n" +" elif self.dogiecoin:\n" +" miner = Miner(kind=\"dogiecoin\")\n" +" else:\n" +" # Nothing to do\n" +" return\n" +"\n" +" miner.do_mining()\n" +"\n" +"\n" +"services = [\n" +" MiningService(bitcoin=True),\n" +" MiningService(monero=True),\n" +" MiningService(dogiecoin=True),\n" +"]\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint(*services) as loop:\n" +" loop.run_forever()" +msgstr "" +"from typing import Dict, Any\n" +"\n" +"import aiomisc.service\n" +"\n" +"# Реализация вымышленного майнера\n" +"from .my_miner import Miner\n" +"\n" +"\n" +"class MiningService(aiomisc.service.ProcessService):\n" +" bitcoin: bool = False\n" +" monero: bool = False\n" +" dogiecoin: bool = False\n" +"\n" +" def in_process(self) -> Any:\n" +" if self.bitcoin:\n" +" miner = Miner(kind=\"bitcoin\")\n" +" elif self.monero:\n" +" miner = Miner(kind=\"monero\")\n" +" elif self.dogiecoin:\n" +" miner = Miner(kind=\"dogiecoin\")\n" +" else:\n" +" # Ничего делать не нужно\n" +" return\n" +"\n" +" miner.do_mining()\n" +"\n" +"\n" +"services = [\n" +" MiningService(bitcoin=True),\n" +" MiningService(monero=True),\n" +" MiningService(dogiecoin=True),\n" +"]\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint(*services) as loop:\n" +" loop.run_forever()" + #: ../../source/services.rst:989 msgid "``RespawningProcessService``" msgstr "Класс ``RespawningProcessService``" @@ -419,3 +1426,25 @@ msgstr "" "завершения при остановке родительского процесса. Это очень похоже на " "`ProcessService` с одним отличием - если дочерний процесс неожиданно " "завершится, то он будет перезапущен." + +#: ../../source/services.rst:996 +msgid "" +"import logging\n" +"from typing import Any\n" +"\n" +"import aiomisc\n" +"\n" +"from time import sleep\n" +"\n" +"\n" +"class SuicideService(aiomisc.service.RespawningProcessService):\n" +" def in_process(self) -> Any:\n" +" sleep(10)\n" +" logging.warning(\"Goodbye mad world\")\n" +" exit(42)\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint(SuicideService()) as loop:\n" +" loop.run_forever()" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/signal.po b/docs/source/locale/ru/LC_MESSAGES/signal.po index f14516e0..2f4ac426 100644 --- a/docs/source/locale/ru/LC_MESSAGES/signal.po +++ b/docs/source/locale/ru/LC_MESSAGES/signal.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-03 16:55+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/signal.rst:2 msgid "``Signal``" @@ -37,9 +37,21 @@ msgid "" "``pre_start`` signal occurs on entrypoint starting up before any service " "has started." msgstr "" -"``pre_start`` сигнал происходящий когда entrypoint запусается но до " +"``pre_start`` сигнал происходящий когда entrypoint запускается но до " "запуска всех сервисов." +#: ../../source/signal.rst:11 +msgid "" +"from aiomisc import entrypoint, receiver\n" +"\n" +"@receiver(entrypoint.PRE_START)\n" +"async def prepare_database(entrypoint, services):\n" +" ...\n" +"\n" +"with entrypoint() as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/signal.rst:24 msgid "``post_start``" msgstr "" @@ -52,6 +64,18 @@ msgstr "" "``post_start`` сигнал происходящий после того как entrypoint запустит все" " сервисы." +#: ../../source/signal.rst:29 +msgid "" +"from aiomisc import entrypoint, receiver\n" +"\n" +"@receiver(entrypoint.POST_START)\n" +"async def startup_notifier(entrypoint, services):\n" +" ...\n" +"\n" +"with entrypoint() as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/signal.rst:42 #, fuzzy msgid "``pre_stop``" @@ -65,6 +89,18 @@ msgstr "" "``pre_stop`` сигнал происходящий когда entrypoint завершается до " "остановки всех сервисов." +#: ../../source/signal.rst:47 +msgid "" +"from aiomisc import entrypoint, receiver\n" +"\n" +"@receiver(entrypoint.PRE_STOP)\n" +"async def shutdown_notifier(entrypoint):\n" +" ...\n" +"\n" +"with entrypoint() as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/signal.rst:60 msgid "``post_stop``" msgstr "" @@ -74,6 +110,17 @@ msgid "" "``post_stop`` signal occurs on entrypoint shutdown after all services " "have been stopped." msgstr "" -"``post_stop`` сигнал происходящий когда entrypoint завершается запусается" +"``post_stop`` сигнал происходящий когда entrypoint завершается запускается" " после остановки всех сервисов." +#: ../../source/signal.rst:65 +msgid "" +"from aiomisc import entrypoint, receiver\n" +"\n" +"@receiver(entrypoint.POST_STOP)\n" +"async def cleanup(entrypoint):\n" +" ...\n" +"\n" +"with entrypoint() as loop:\n" +" loop.run_forever()" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/statistic.po b/docs/source/locale/ru/LC_MESSAGES/statistic.po index d28fbb56..ffd12ef9 100644 --- a/docs/source/locale/ru/LC_MESSAGES/statistic.po +++ b/docs/source/locale/ru/LC_MESSAGES/statistic.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2021-10-15 17:18+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/statistic.rst:2 msgid "Statistic counters" @@ -35,9 +35,44 @@ msgid "" msgstr "" "Экземпляры классов статистики создаются динамически. Вы можете " "использовать определяемые пользователем имена для них добавляя аргумент " -"``statistic_name: Optional[str] = None`` в сущьности поддерживающе это." +"``statistic_name: Optional[str] = None`` в сущности поддерживающие это." + +#: ../../source/statistic.rst:11 +msgid "" +"import aiomisc\n" +"\n" +"async def main():\n" +" for metric in aiomisc.get_statistics():\n" +" print(\n" +" str(metric.kind.__name__),\n" +" metric.name,\n" +" metric.metric,\n" +" metric.value\n" +" )\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" #: ../../source/statistic.rst:29 msgid "This code will print something like this:" msgstr "Этот код выведет что-то вроде:" +#: ../../source/statistic.rst:31 +msgid "" +"ContextStatistic None get 0\n" +"ContextStatistic None set 0\n" +"ThreadPoolStatistic logger submitted 1\n" +"ThreadPoolStatistic logger sum_time 0\n" +"ThreadPoolStatistic logger threads 1\n" +"ThreadPoolStatistic logger done 0\n" +"ThreadPoolStatistic logger success 0\n" +"ThreadPoolStatistic logger error 0\n" +"ThreadPoolStatistic default submitted 0\n" +"ThreadPoolStatistic default sum_time 0\n" +"ThreadPoolStatistic default threads 12\n" +"ThreadPoolStatistic default done 0\n" +"ThreadPoolStatistic default success 0\n" +"ThreadPoolStatistic default error 0" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/threads.po b/docs/source/locale/ru/LC_MESSAGES/threads.po index 97b863ea..a25a7a48 100644 --- a/docs/source/locale/ru/LC_MESSAGES/threads.po +++ b/docs/source/locale/ru/LC_MESSAGES/threads.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-03 15:25+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/threads.rst:2 msgid "Working with threads" @@ -39,10 +39,63 @@ msgstr "" "``contextvars``, из PyPI для python моложе 3.7 так и встроенный в " "стандартную библиотеку модуль для python 3.7." +#: ../../source/threads.rst:13 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"import contextvars\n" +"import random\n" +"import struct\n" +"\n" +"\n" +"user_id = contextvars.ContextVar(\"user_id\")\n" +"\n" +"record_struct = struct.Struct(\">I\")\n" +"\n" +"\n" +"@aiomisc.threaded\n" +"def write_user():\n" +" with open(\"/tmp/audit.bin\", 'ab') as fp:\n" +" fp.write(record_struct.pack(user_id.get()))\n" +"\n" +"\n" +"@aiomisc.threaded\n" +"def read_log():\n" +" with open(\"/tmp/audit.bin\", \"rb\") as fp:\n" +" for chunk in iter(lambda: fp.read(record_struct.size), b''):\n" +" yield record_struct.unpack(chunk)[0]\n" +"\n" +"\n" +"async def main():\n" +" futures = []\n" +" for _ in range(5):\n" +" user_id.set(random.randint(1, 65535))\n" +" futures.append(write_user())\n" +"\n" +" await asyncio.gather(*futures)\n" +"\n" +" async for data in read_log():\n" +" print(data)\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + #: ../../source/threads.rst:57 msgid "Example output:" msgstr "Пример вывода" +#: ../../source/threads.rst:59 +msgid "" +"6621\n" +"33012\n" +"1590\n" +"45008\n" +"56844" +msgstr "" + #: ../../source/threads.rst:70 msgid "" "``contextvars`` has different use cases then ``Context`` class. " @@ -66,6 +119,52 @@ msgstr "" msgid "Wraps blocking function and run it in the current thread pool." msgstr "Оборачивает блокирующую функцию и запускает ее в пуле потоков." +#: ../../source/threads.rst:83 +msgid "" +"import asyncio\n" +"import time\n" +"from aiomisc import new_event_loop, threaded\n" +"\n" +"\n" +"@threaded\n" +"def blocking_function():\n" +" time.sleep(1)\n" +"\n" +"\n" +"async def main():\n" +" # Running in parallel\n" +" await asyncio.gather(\n" +" blocking_function(),\n" +" blocking_function(),\n" +" )\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +" loop.run_until_complete(main())" +msgstr "" +"import asyncio\n" +"import time\n" +"from aiomisc import new_event_loop, threaded\n" +"\n" +"\n" +"@threaded\n" +"def blocking_function():\n" +" time.sleep(1)\n" +"\n" +"\n" +"async def main():\n" +" # Параллельный запуск\n" +" await asyncio.gather(\n" +" blocking_function(),\n" +" blocking_function(),\n" +" )\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +" loop.run_until_complete(main())" + #: ../../source/threads.rst:107 msgid "" "In case the function is a generator function ``@threaded`` decorator will" @@ -86,6 +185,80 @@ msgstr "" "Оборачивает блокирующую функцию и запускает ее в отдельном новом " "потоке.Крайне рекомендовано для длительных фоновых задач:" +#: ../../source/threads.rst:117 +msgid "" +"import asyncio\n" +"import time\n" +"import threading\n" +"import aiomisc\n" +"\n" +"\n" +"@aiomisc.threaded\n" +"def blocking_function():\n" +" time.sleep(1)\n" +"\n" +"\n" +"@aiomisc.threaded_separate\n" +"def long_blocking_function(event: threading.Event):\n" +" while not event.is_set():\n" +" print(\"Running\")\n" +" time.sleep(1)\n" +" print(\"Exitting\")\n" +"\n" +"\n" +"async def main():\n" +" stop_event = threading.Event()\n" +"\n" +" loop = asyncio.get_event_loop()\n" +" loop.call_later(10, stop_event.set)\n" +"\n" +" # Running in parallel\n" +" await asyncio.gather(\n" +" blocking_function(),\n" +" # New thread will be spawned\n" +" long_blocking_function(stop_event),\n" +" )\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"import asyncio\n" +"import time\n" +"import threading\n" +"import aiomisc\n" +"\n" +"\n" +"@aiomisc.threaded\n" +"def blocking_function():\n" +" time.sleep(1)\n" +"\n" +"\n" +"@aiomisc.threaded_separate\n" +"def long_blocking_function(event: threading.Event):\n" +" while not event.is_set():\n" +" print(\"Running\")\n" +" time.sleep(1)\n" +" print(\"Выходим\")\n" +"\n" +"\n" +"async def main():\n" +" stop_event = threading.Event()\n" +"\n" +" loop = asyncio.get_event_loop()\n" +" loop.call_later(10, stop_event.set)\n" +"\n" +" # Параллельный запуск\n" +" await asyncio.gather(\n" +" blocking_function(),\n" +" # Будет запущен отдельный новый поток\n" +" long_blocking_function(stop_event),\n" +" )\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/threads.rst:157 msgid "Threaded iterator decorator" msgstr "Threaded iterator decorator" @@ -106,12 +279,154 @@ msgstr "" "Следующий пример читает свой собственный код, и обновляет хеш для каждой " "следующей строки от предидущих строк, и отправляет все это по TCP:" +#: ../../source/threads.rst:165 +msgid "" +"import asyncio\n" +"import hashlib\n" +"\n" +"import aiomisc\n" +"\n" +"# My first blockchain\n" +"\n" +"@aiomisc.threaded_iterable\n" +"def blocking_reader(fname):\n" +" with open(fname, \"r+\") as fp:\n" +" md5_hash = hashlib.md5()\n" +" for line in fp:\n" +" bytes_line = line.encode()\n" +" md5_hash.update(bytes_line)\n" +" yield bytes_line, md5_hash.hexdigest().encode()\n" +"\n" +"\n" +"async def main():\n" +" reader, writer = await asyncio.open_connection(\"127.0.0.1\", 2233)\n" +" async with blocking_reader(__file__) as gen:\n" +" async for line, digest in gen:\n" +" writer.write(digest)\n" +" writer.write(b'\\t')\n" +" writer.write(line)\n" +" await writer.drain()\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop\n" +" loop.run_until_complete(main())" +msgstr "" +"import asyncio\n" +"import hashlib\n" +"\n" +"import aiomisc\n" +"\n" +"# Мой первый блокчейн\n" +"\n" +"@aiomisc.threaded_iterable\n" +"def blocking_reader(fname):\n" +" with open(fname, \"r+\") as fp:\n" +" md5_hash = hashlib.md5()\n" +" for line in fp:\n" +" bytes_line = line.encode()\n" +" md5_hash.update(bytes_line)\n" +" yield bytes_line, md5_hash.hexdigest().encode()\n" +"\n" +"\n" +"async def main():\n" +" reader, writer = await asyncio.open_connection(\"127.0.0.1\", 2233)\n" +" async with blocking_reader(__file__) as gen:\n" +" async for line, digest in gen:\n" +" writer.write(digest)\n" +" writer.write(b'\\t')\n" +" writer.write(line)\n" +" await writer.drain()\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop\n" +" loop.run_until_complete(main())" + #: ../../source/threads.rst:199 msgid "Run ``netcat`` listener in the terminal and run this example" msgstr "" "Запустим TCP сервер с помощью ``netcat`` в терминале, и после запустим " "этот пример." +#: ../../source/threads.rst:201 +msgid "" +"$ netcat -v -l -p 2233\n" +"Connection from 127.0.0.1:54734\n" +"dc80feba2326979f8976e387fbbc8121 import asyncio\n" +"78ec3bcb1c441614ede4af5e5b28f638 import hashlib\n" +"b7df4a0a4eac401b2f835447e5fc4139\n" +"f0a94eb3d7ad23d96846c8cb5e327454 import aiomisc\n" +"0c05dde8ac593bad97235e6ae410cb58\n" +"e4d639552b78adea6b7c928c5ebe2b67 # My first blockchain\n" +"5f04aef64f4cacce39170142fe45e53e\n" +"c0019130ba5210b15db378caf7e9f1c9 @aiomisc.threaded_iterable\n" +"a720db7e706d10f55431a921cdc1cd4c def blocking_reader(fname):\n" +"0895d7ca2984ea23228b7d653d0b38f2 with open(fname, \"r+\") as fp:\n" +"0feca8542916af0b130b2d68ade679cf md5_hash = hashlib.md5()\n" +"4a9ddfea3a0344cadd7a80a8b99ff85c for line in fp:\n" +"f66fa1df3d60b7ac8991244455dff4ee bytes_line = line.encode()" +"\n" +"aaac23a5aa34e0f5c448a8d7e973f036 " +"md5_hash.update(bytes_line)\n" +"2040bcaab6137b60e51ae6bd1e279546 yield bytes_line, " +"md5_hash.hexdigest().encode()\n" +"7346740fdcde6f07d42ecd2d6841d483\n" +"14dfb2bae89fa0d7f9b6cba2b39122c4\n" +"d69cc5fe0779f0fa800c6ec0e2a7cbbd async def main():\n" +"ead8ef1571e6b4727dcd9096a3ade4da reader, writer = await " +"asyncio.open_connection(\"127.0.0.1\", 2233)\n" +"275eb71a6b6fb219feaa5dc2391f47b7 async with " +"blocking_reader(__file__) as gen:\n" +"110375ba7e8ab3716fd38a6ae8ec8b83 async for line, digest in gen:" +"\n" +"c26894b38440dbdc31f77765f014f445 writer.write(digest)\n" +"27659596bd880c55e2bc72b331dea948 writer.write(b'\\t')\n" +"8bb9e27b43a9983c9621c6c5139a822e writer.write(line)\n" +"2659fbe434899fc66153decf126fdb1c await writer.drain()\n" +"6815f69821da8e1fad1d60ac44ef501e\n" +"5acc73f7a490dcc3b805e75fb2534254\n" +"0f29ad9505d1f5e205b0cbfef572ab0e if __name__ == '__main__':\n" +"8b04db9d80d8cda79c3b9c4640c08928 loop = aiomisc.new_event_loop()\n" +"9cc5f29f81e15cb262a46cf96b8788ba loop.run_until_complete(main())" +msgstr "" +"$ netcat -v -l -p 2233\n" +"Connection from 127.0.0.1:54734\n" +"dc80feba2326979f8976e387fbbc8121 import asyncio\n" +"78ec3bcb1c441614ede4af5e5b28f638 import hashlib\n" +"b7df4a0a4eac401b2f835447e5fc4139\n" +"f0a94eb3d7ad23d96846c8cb5e327454 import aiomisc\n" +"0c05dde8ac593bad97235e6ae410cb58\n" +"e4d639552b78adea6b7c928c5ebe2b67 # Мой первый блокчейн\n" +"5f04aef64f4cacce39170142fe45e53e\n" +"c0019130ba5210b15db378caf7e9f1c9 @aiomisc.threaded_iterable\n" +"a720db7e706d10f55431a921cdc1cd4c def blocking_reader(fname):\n" +"0895d7ca2984ea23228b7d653d0b38f2 with open(fname, \"r+\") as fp:\n" +"0feca8542916af0b130b2d68ade679cf md5_hash = hashlib.md5()\n" +"4a9ddfea3a0344cadd7a80a8b99ff85c for line in fp:\n" +"f66fa1df3d60b7ac8991244455dff4ee bytes_line = line.encode()" +"\n" +"aaac23a5aa34e0f5c448a8d7e973f036 " +"md5_hash.update(bytes_line)\n" +"2040bcaab6137b60e51ae6bd1e279546 yield bytes_line, " +"md5_hash.hexdigest().encode()\n" +"7346740fdcde6f07d42ecd2d6841d483\n" +"14dfb2bae89fa0d7f9b6cba2b39122c4\n" +"d69cc5fe0779f0fa800c6ec0e2a7cbbd async def main():\n" +"ead8ef1571e6b4727dcd9096a3ade4da reader, writer = await " +"asyncio.open_connection(\"127.0.0.1\", 2233)\n" +"275eb71a6b6fb219feaa5dc2391f47b7 async with " +"blocking_reader(__file__) as gen:\n" +"110375ba7e8ab3716fd38a6ae8ec8b83 async for line, digest in gen:" +"\n" +"c26894b38440dbdc31f77765f014f445 writer.write(digest)\n" +"27659596bd880c55e2bc72b331dea948 writer.write(b'\\t')\n" +"8bb9e27b43a9983c9621c6c5139a822e writer.write(line)\n" +"2659fbe434899fc66153decf126fdb1c await writer.drain()\n" +"6815f69821da8e1fad1d60ac44ef501e\n" +"5acc73f7a490dcc3b805e75fb2534254\n" +"0f29ad9505d1f5e205b0cbfef572ab0e if __name__ == '__main__':\n" +"8b04db9d80d8cda79c3b9c4640c08928 loop = aiomisc.new_event_loop()\n" +"9cc5f29f81e15cb262a46cf96b8788ba loop.run_until_complete(main())" + #: ../../source/threads.rst:237 msgid "" "You should use async context managers in the case when your generator " @@ -123,6 +438,122 @@ msgstr "" "``.close()`` если вы избегаете использование асинхронных " "контекст-менеджеров." +#: ../../source/threads.rst:240 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"# Set 2 chunk buffer\n" +"@aiomisc.threaded_iterable(max_size=2)\n" +"def urandom_reader():\n" +" with open('/dev/urandom', \"rb\") as fp:\n" +" while True:\n" +" yield fp.read(8)\n" +"\n" +"\n" +"# Infinity buffer on a separate thread\n" +"@aiomisc.threaded_iterable_separate\n" +"def blocking_reader(fname):\n" +" with open(fname, \"r\") as fp:\n" +" yield from fp\n" +"\n" +"\n" +"async def main():\n" +" reader, writer = await asyncio.open_connection(\"127.0.0.1\", 2233)\n" +" async for line in blocking_reader(__file__):\n" +" writer.write(line.encode())\n" +"\n" +" await writer.drain()\n" +"\n" +" # Feed white noise\n" +" gen = urandom_reader()\n" +" counter = 0\n" +" async for line in gen:\n" +" writer.write(line)\n" +" counter += 1\n" +"\n" +" if counter == 10:\n" +" break\n" +"\n" +" await writer.drain()\n" +"\n" +" # Stop running generator\n" +" await gen.close()\n" +"\n" +" # Using context manager\n" +" async with urandom_reader() as gen:\n" +" counter = 0\n" +" async for line in gen:\n" +" writer.write(line)\n" +" counter += 1\n" +"\n" +" if counter == 10:\n" +" break\n" +"\n" +" await writer.drain()\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"# Настраиваем буфер на 2 элемента вперед\n" +"@aiomisc.threaded_iterable(max_size=2)\n" +"def urandom_reader():\n" +" with open('/dev/urandom', \"rb\") as fp:\n" +" while True:\n" +" yield fp.read(8)\n" +"\n" +"\n" +"# Бесконечный буфер в отдельном потоке\n" +"@aiomisc.threaded_iterable_separate\n" +"def blocking_reader(fname):\n" +" with open(fname, \"r\") as fp:\n" +" yield from fp\n" +"\n" +"\n" +"async def main():\n" +" reader, writer = await asyncio.open_connection(\"127.0.0.1\", 2233)\n" +" async for line in blocking_reader(__file__):\n" +" writer.write(line.encode())\n" +"\n" +" await writer.drain()\n" +"\n" +" # Будем \"кушать\" белый шум\n" +" gen = urandom_reader()\n" +" counter = 0\n" +" async for line in gen:\n" +" writer.write(line)\n" +" counter += 1\n" +"\n" +" if counter == 10:\n" +" break\n" +"\n" +" await writer.drain()\n" +"\n" +" # Останавливаем запущенный генератор\n" +" await gen.close()\n" +"\n" +" # Тоже самое, только через контекст менеджер\n" +" async with urandom_reader() as gen:\n" +" counter = 0\n" +" async for line in gen:\n" +" writer.write(line)\n" +" counter += 1\n" +"\n" +" if counter == 10:\n" +" break\n" +"\n" +" await writer.drain()\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/threads.rst:300 msgid "``aiomisc.IteratorWrapper``" msgstr "" @@ -131,6 +562,84 @@ msgstr "" msgid "Run iterables on dedicated thread pool:" msgstr "Запускает блокирующий итератор в пуле потоков:" +#: ../../source/threads.rst:304 +msgid "" +"import concurrent.futures\n" +"import hashlib\n" +"import aiomisc\n" +"\n" +"\n" +"def urandom_reader():\n" +" with open('/dev/urandom', \"rb\") as fp:\n" +" while True:\n" +" yield fp.read(1024)\n" +"\n" +"\n" +"async def main():\n" +" # create a new thread pool\n" +" pool = concurrent.futures.ThreadPoolExecutor(1)\n" +" wrapper = aiomisc.IteratorWrapper(\n" +" urandom_reader,\n" +" executor=pool,\n" +" max_size=2\n" +" )\n" +"\n" +" async with wrapper as gen:\n" +" md5_hash = hashlib.md5(b'')\n" +" counter = 0\n" +" async for item in gen:\n" +" md5_hash.update(item)\n" +" counter += 1\n" +"\n" +" if counter >= 100:\n" +" break\n" +"\n" +" pool.shutdown()\n" +" print(md5_hash.hexdigest())\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"import concurrent.futures\n" +"import hashlib\n" +"import aiomisc\n" +"\n" +"\n" +"def urandom_reader():\n" +" with open('/dev/urandom', \"rb\") as fp:\n" +" while True:\n" +" yield fp.read(1024)\n" +"\n" +"\n" +"async def main():\n" +" # Создаем новый пул потоков\n" +" pool = concurrent.futures.ThreadPoolExecutor(1)\n" +" wrapper = aiomisc.IteratorWrapper(\n" +" urandom_reader,\n" +" executor=pool,\n" +" max_size=2\n" +" )\n" +"\n" +" async with wrapper as gen:\n" +" md5_hash = hashlib.md5(b'')\n" +" counter = 0\n" +" async for item in gen:\n" +" md5_hash.update(item)\n" +" counter += 1\n" +"\n" +" if counter >= 100:\n" +" break\n" +"\n" +" pool.shutdown()\n" +" print(md5_hash.hexdigest())\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/threads.rst:345 msgid "``aiomisc.IteratorWrapperSeparate``" msgstr "" @@ -139,6 +648,76 @@ msgstr "" msgid "Run iterables on a separate thread:" msgstr "Запускает блокирующий итераторы в отдельном новом потоке:" +#: ../../source/threads.rst:349 +msgid "" +"import concurrent.futures\n" +"import hashlib\n" +"import aiomisc\n" +"\n" +"\n" +"def urandom_reader():\n" +" with open('/dev/urandom', \"rb\") as fp:\n" +" while True:\n" +" yield fp.read(1024)\n" +"\n" +"\n" +"async def main():\n" +" # create a new thread pool\n" +" wrapper = aiomisc.IteratorWrapperSeparate(\n" +" urandom_reader, max_size=2\n" +" )\n" +"\n" +" async with wrapper as gen:\n" +" md5_hash = hashlib.md5(b'')\n" +" counter = 0\n" +" async for item in gen:\n" +" md5_hash.update(item)\n" +" counter += 1\n" +"\n" +" if counter >= 100:\n" +" break\n" +"\n" +" print(md5_hash.hexdigest())\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" +"import concurrent.futures\n" +"import hashlib\n" +"import aiomisc\n" +"\n" +"\n" +"def urandom_reader():\n" +" with open('/dev/urandom', \"rb\") as fp:\n" +" while True:\n" +" yield fp.read(1024)\n" +"\n" +"\n" +"async def main():\n" +" # Создаем новый пул потоков\n" +" wrapper = aiomisc.IteratorWrapperSeparate(\n" +" urandom_reader, max_size=2\n" +" )\n" +"\n" +" async with wrapper as gen:\n" +" md5_hash = hashlib.md5(b'')\n" +" counter = 0\n" +" async for item in gen:\n" +" md5_hash.update(item)\n" +" counter += 1\n" +"\n" +" if counter >= 100:\n" +" break\n" +"\n" +" print(md5_hash.hexdigest())\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" + #: ../../source/threads.rst:388 msgid "``aiomisc.ThreadPoolExecutor``" msgstr "" @@ -151,6 +730,16 @@ msgstr "Реализация быстрого и простого пула по msgid "Setting as a default thread pool:" msgstr "Устанавливаем как пул потоков по умолчанию:" +#: ../../source/threads.rst:394 +msgid "" +"import asyncio\n" +"from aiomisc import ThreadPoolExecutor\n" +"\n" +"loop = asyncio.get_event_loop()\n" +"thread_pool = ThreadPoolExecutor(4)\n" +"loop.set_default_executor(thread_pool)" +msgstr "" + #: ../../source/threads.rst:406 msgid "``entrypoint`` context manager will set it by default." msgstr "``entrypoint`` установит это по умолчанию." @@ -174,3 +763,26 @@ msgstr "" "Функции запущенные в потоке не могут вызывать и дожидаться сопрограмм по " "умолчанию. Эта функция это хелпер позволяет отправить сопрограмму в event" " loop и дождаться ее результата из текущего потока." + +#: ../../source/threads.rst:418 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"async def coro():\n" +" print(\"Coroutine started\")\n" +" await asyncio.sleep(1)\n" +" print(\"Coroutine done\")\n" +"\n" +"\n" +"@aiomisc.threaded\n" +"def in_thread(loop):\n" +" print(\"Thread started\")\n" +" aiomisc.sync_wait_coroutine(loop, coro)\n" +" print(\"Thread finished\")\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(in_thread(loop))" +msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/timeout.po b/docs/source/locale/ru/LC_MESSAGES/timeout.po index a48547b8..fdf72d40 100644 --- a/docs/source/locale/ru/LC_MESSAGES/timeout.po +++ b/docs/source/locale/ru/LC_MESSAGES/timeout.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-03 16:53+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/timeout.rst:2 msgid "``@aiomisc.timeout``" @@ -25,6 +25,14 @@ msgid "" "function is met." msgstr "Декоратор который ограничивает время выполнения оборачиваемой сопрограммы." +#: ../../source/timeout.rst:7 +msgid "" +"from aiomisc import timeout\n" +"\n" +"@timeout(1)\n" +"async def bad_func():\n" +" await asyncio.sleep(2)" +msgstr "" + #~ msgid "timeout decorator" #~ msgstr "декоратор timeout" - diff --git a/docs/source/locale/ru/LC_MESSAGES/tutorial.po b/docs/source/locale/ru/LC_MESSAGES/tutorial.po index 421394b7..d86ab84c 100644 --- a/docs/source/locale/ru/LC_MESSAGES/tutorial.po +++ b/docs/source/locale/ru/LC_MESSAGES/tutorial.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 16.1.10\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-29 08:23+0300\n" +"POT-Creation-Date: 2022-12-29 12:04+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -79,6 +79,36 @@ msgstr "" "Если вы хотите запустить tcp или веб-сервер, вам придется написать что-то" " вроде этого:" +#: ../../source/tutorial.rst:29 +msgid "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" # do my async business logic\n" +" await init_db()\n" +" await init_cache()\n" +" await start_http_server()\n" +" await start_metrics_server()\n" +"\n" +"loop = asyncio.get_event_loop()\n" +"loop.run_until_complete(example_async_func())\n" +"# Continue running all background tasks\n" +"loop.run_forever()" +msgstr "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" # Делаем что-то асинхронное и очень важное\n" +" await init_db()\n" +" await init_cache()\n" +" await start_http_server()\n" +" await start_metrics_server()\n" +"\n" +"loop = asyncio.get_event_loop()\n" +"loop.run_until_complete(example_async_func())\n" +"# Продолжаем выполнение асинхронных задач\n" +"loop.run_forever()" + #: ../../source/tutorial.rst:45 msgid "" "In order to start or stop an async programs, usually using function " @@ -94,6 +124,38 @@ msgstr "" "Чтобы продолжить выполнение кода вечно, вы можете применить следующий " "трюк:" +#: ../../source/tutorial.rst:52 +msgid "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" # do my async business logic\n" +" await init_db()\n" +" await init_cache()\n" +" await start_http_server()\n" +" await start_metrics_server()\n" +"\n" +" # Make future which never be done\n" +" # using instead loop.run_forever()\n" +" await asyncio.Future()\n" +"\n" +"asyncio.run(example_async_func())" +msgstr "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" # Делаем что-то асинхронное и очень важное\n" +" await init_db()\n" +" await init_cache()\n" +" await start_http_server()\n" +" await start_metrics_server()\n" +"\n" +" # Создаем future которая никогда не будет завершена\n" +" # используется вместо loop.run_forever()\n" +" await asyncio.Future()\n" +"\n" +"asyncio.run(example_async_func())" + #: ../../source/tutorial.rst:70 msgid "" "When the user presses `Ctrl+C`, the program simply terminates, but if you" @@ -106,6 +168,52 @@ msgstr "" "соединения с базой данных или откатить незавершенные транзакции, то вам " "нужно сделать что-то вроде этого:" +#: ../../source/tutorial.rst:75 +msgid "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" try:\n" +" # do my async business logic\n" +" await init_db()\n" +" await init_cache()\n" +" await start_http_server()\n" +" await start_metrics_server()\n" +"\n" +" # Make future which never be done\n" +" # using instead loop.run_forever()\n" +" await asyncio.Future()\n" +" except asyncio.CancelledError:\n" +" # Do this block when SIGTERM has been received\n" +" pass\n" +" finally:\n" +" # Do this block on exit\n" +" ...\n" +"\n" +"asyncio.run(example_async_func())" +msgstr "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" try:\n" +" # Делаем что-то асинхронное и очень важное\n" +" await init_db()\n" +" await init_cache()\n" +" await start_http_server()\n" +" await start_metrics_server()\n" +"\n" +" # Создаем future которая никогда не будет завершена\n" +" # используется вместо loop.run_forever()\n" +" await asyncio.Future()\n" +" except asyncio.CancelledError:\n" +" # Зайдем в этот блок будет когда получим SIGTERM\n" +" pass\n" +" finally:\n" +" # Зайдем сюда перед выходом\n" +" ...\n" +"\n" +"asyncio.run(example_async_func())" + #: ../../source/tutorial.rst:100 msgid "" "It is a good solution because it is implemented without any 3rd-party " @@ -120,6 +228,56 @@ msgstr "" "инициализацию конкурентно. На первый взгляд кажется, что этот код решит " "проблему:" +#: ../../source/tutorial.rst:106 +msgid "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" try:\n" +" # do my async business logic\n" +" await asyncio.gather(\n" +" init_db(),\n" +" init_cache(),\n" +" start_http_server(),\n" +" start_metrics_server(),\n" +" )\n" +"\n" +" # Make future which never be done\n" +" # using instead loop.run_forever()\n" +" await asyncio.Future()\n" +" except asyncio.CancelledError:\n" +" # Do this block when SIGTERM has been received\n" +" pass\n" +" finally:\n" +" # Do this block on exit\n" +" ...\n" +"\n" +"asyncio.run(example_async_func())" +msgstr "" +"import asyncio\n" +"\n" +"async def example_async_func():\n" +" try:\n" +" # Делаем что-то асинхронное и очень важное\n" +" await asyncio.gather(\n" +" init_db(),\n" +" init_cache(),\n" +" start_http_server(),\n" +" start_metrics_server(),\n" +" )\n" +"\n" +" # Создаем future которая никогда не будет завершена\n" +" # используется вместо loop.run_forever()\n" +" await asyncio.Future()\n" +" except asyncio.CancelledError:\n" +" # Зайдем в этот блок будет когда получим SIGTERM\n" +" pass\n" +" finally:\n" +" # Зайдем сюда перед выходом\n" +" ...\n" +"\n" +"asyncio.run(example_async_func())" + #: ../../source/tutorial.rst:132 msgid "" "But if suddenly some part of the initialization does not go according to " @@ -142,6 +300,72 @@ msgstr "" "функцию, которая будет содержать блок ``try/except/finally`` и содержать " "обработку ошибок." +#: ../../source/tutorial.rst:141 +msgid "" +"import asyncio\n" +"\n" +"async def init_db():\n" +" try:\n" +" # initialize connection\n" +" finally:\n" +" # close connection\n" +" ...\n" +"\n" +"async def example_async_func():\n" +" try:\n" +" # do my async business logic\n" +" await asyncio.gather(\n" +" init_db(),\n" +" init_cache(),\n" +" start_http_server(),\n" +" start_metrics_server(),\n" +" )\n" +"\n" +" # Make future which never be done\n" +" # using instead loop.run_forever()\n" +" await asyncio.Future()\n" +" except asyncio.CancelledError:\n" +" # Do this block when SIGTERM has been received\n" +" # TODO: shutdown all things correctly\n" +" pass\n" +" finally:\n" +" # Do this block on exit\n" +" ...\n" +"\n" +"asyncio.run(example_async_func())" +msgstr "" +"import asyncio\n" +"\n" +"async def init_db():\n" +" try:\n" +" # инициализируем соединение\n" +" finally:\n" +" # закрываем соединение\n" +" ...\n" +"\n" +"async def example_async_func():\n" +" try:\n" +" # Делаем что-то асинхронное и очень важное\n" +" await asyncio.gather(\n" +" init_db(),\n" +" init_cache(),\n" +" start_http_server(),\n" +" start_metrics_server(),\n" +" )\n" +"\n" +" # Создаем future которая никогда не будет завершена\n" +" # используется вместо loop.run_forever()\n" +" await asyncio.Future()\n" +" except asyncio.CancelledError:\n" +" # Зайдем в этот блок будет когда получим SIGTERM\n" +" # TODO: нужно как-то корректно все завершить\n" +" pass\n" +" finally:\n" +" # Зайдем сюда перед выходом\n" +" ...\n" +"\n" +"asyncio.run(example_async_func())" + #: ../../source/tutorial.rst:176 msgid "" "And now if the user presses Ctrl+C, you need to describe the shutdown " @@ -178,6 +402,34 @@ msgstr "" "выполняется вечно, тогда не нужно реализовывать стоп, но нужно сообщить " "что инициализация успешно закончена с помощью ``self.start_event.set()``." +#: ../../source/tutorial.rst:191 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"class InfinityService(aiomisc.Service):\n" +" async def start(self):\n" +" # Service is ready\n" +" self.start_event.set()\n" +"\n" +" while True:\n" +" # do some stuff\n" +" await asyncio.sleep(1)" +msgstr "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"class InfinityService(aiomisc.Service):\n" +" async def start(self):\n" +" # Сервис готов работать\n" +" self.start_event.set()\n" +"\n" +" while True:\n" +" # Делаем что-то полезное\n" +" await asyncio.sleep(1)" + #: ../../source/tutorial.rst:206 msgid "" "In this case, stopping the service will consist in the completion of the " @@ -194,6 +446,36 @@ msgstr "" "Второй способ это явное описание способа запуска и остановки реализовав " "методы ``start()`` и ``stop()``" +#: ../../source/tutorial.rst:213 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"from typing import Any\n" +"\n" +"\n" +"class OrdinaryService(aiomisc.Service):\n" +" async def start(self):\n" +" # do some stuff\n" +" ...\n" +"\n" +" async def stop(self, exception: Exception = None) -> Any:\n" +" # do some stuff\n" +" ..." +msgstr "" +"import asyncio\n" +"import aiomisc\n" +"from typing import Any\n" +"\n" +"\n" +"class OrdinaryService(aiomisc.Service):\n" +" async def start(self):\n" +" # Делаем что-то полезное\n" +" ...\n" +"\n" +" async def stop(self, exception: Exception = None) -> Any:\n" +" # Делаем что-то полезное\n" +" ..." + #: ../../source/tutorial.rst:229 msgid "In this case, the service will be started and stopped once." msgstr "В этом случае запуск и остановка сервиса будут выполнены однократно." @@ -218,6 +500,50 @@ msgstr "" "Вот простой императивный пример как инициализация сервиса может быть " "расширена через наследование." +#: ../../source/tutorial.rst:241 +msgid "" +"from typing import Any\n" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" def __init__(self, name: str = \"world\", **kwargs: Any):\n" +" super().__init__(**kwargs)\n" +" self.name = name\n" +"\n" +" async def start(self) -> Any:\n" +" print(f\"Hello {self.name}\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(),\n" +" HelloService(name=\"Guido\")\n" +") as loop:\n" +" pass\n" +"\n" +"# python hello.py\n" +"# <<< Hello world\n" +"# <<< Hello Guido" +msgstr "" +"from typing import Any\n" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" def __init__(self, name: str = \"мир\", **kwargs: Any):\n" +" super().__init__(**kwargs)\n" +" self.name = name\n" +"\n" +" async def start(self) -> Any:\n" +" print(f\"Привет {self.name}\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(),\n" +" HelloService(name=\"Гвидо\")\n" +") as loop:\n" +" pass\n" +"\n" +"# python hello.py\n" +"# <<< Привет мир\n" +"# <<< Привет Гвидо" + #: ../../source/tutorial.rst:264 msgid "" "In fact, you can do nothing of this, since the Service metaclass sets all" @@ -226,6 +552,44 @@ msgstr "" "На самом деле, можно было ничего и не делать, так как метакласс установит" " все переданные именованные параметры в self по умолчанию." +#: ../../source/tutorial.rst:267 +msgid "" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" name: str = \"world\"\n" +"\n" +" async def start(self):\n" +" print(f\"Hello {self.name}\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(),\n" +" HelloService(name=\"Guido\")\n" +") as loop:\n" +" pass\n" +"\n" +"# python hello.py\n" +"# <<< Hello world\n" +"# <<< Hello Guido" +msgstr "" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" name: str = \"мир\"\n" +"\n" +" async def start(self):\n" +" print(f\"Привет {self.name}\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(),\n" +" HelloService(name=\"Гвидо\")\n" +") as loop:\n" +" pass\n" +"\n" +"# python hello.py\n" +"# <<< Привет мир\n" +"# <<< Привет Гвидо" + #: ../../source/tutorial.rst:287 msgid "" "If a special class property ``__required__`` is declared, then the " @@ -235,6 +599,42 @@ msgstr "" "требовать чтобы он был передан явно при инициализации как именованный " "параметр." +#: ../../source/tutorial.rst:290 +msgid "" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" __required__ = (\"name\", \"title\")\n" +"\n" +" name: str\n" +" title: str\n" +"\n" +" async def start(self):\n" +" await asyncio.sleep(0.1)\n" +" print(f\"Hello {self.title} {self.name}\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(name=\"Guido\", title=\"mr.\")\n" +") as loop:\n" +" pass" +msgstr "" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" __required__ = (\"name\", \"title\")\n" +"\n" +" name: str\n" +" title: str\n" +"\n" +" async def start(self):\n" +" await asyncio.sleep(0.1)\n" +" print(f\"Привет {self.title} {self.name}\")\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(name=\"Гвидо\", title=\"мистер\")\n" +") as loop:\n" +" pass" + #: ../../source/tutorial.rst:309 msgid "" "Also a very useful special class attribute is ``__async_required__``. It " @@ -247,6 +647,68 @@ msgstr "" "классов. Он содержит кортеж имен методов, которые должны быть явно " "объявлены асинхронными (через ``async def``)." +#: ../../source/tutorial.rst:313 +msgid "" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" __required__ = (\"name\", \"title\")\n" +" __async_required__ = (\"greeting\",)\n" +"\n" +" name: str\n" +" title: str\n" +"\n" +" async def greeting(self) -> str:\n" +" await asyncio.sleep(0.1)\n" +" return f\"Hello {self.title} {self.name}\"\n" +"\n" +" async def start(self):\n" +" print(await self.greeting())\n" +"\n" +"class HelloEmojiService(HelloService):\n" +" async def greeting(self) -> str:\n" +" await asyncio.sleep(0.1)\n" +" return f\"🙋 {self.title} {self.name}\"\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(name=\"Guido\", title=\"mr.\"),\n" +" HelloEmojiService(name=\"👨\", title=\"🎩\")\n" +") as loop:\n" +" pass\n" +"\n" +"# Hello mr. Guido\n" +"# 🙋 🎩 👨" +msgstr "" +"import aiomisc\n" +"\n" +"class HelloService(aiomisc.Service):\n" +" __required__ = (\"name\", \"title\")\n" +" __async_required__ = (\"greeting\",)\n" +"\n" +" name: str\n" +" title: str\n" +"\n" +" async def greeting(self) -> str:\n" +" await asyncio.sleep(0.1)\n" +" return f\"Привет {self.title} {self.name}\"\n" +"\n" +" async def start(self):\n" +" print(await self.greeting())\n" +"\n" +"class HelloEmojiService(HelloService):\n" +" async def greeting(self) -> str:\n" +" await asyncio.sleep(0.1)\n" +" return f\"🙋 {self.title} {self.name}\"\n" +"\n" +"with aiomisc.entrypoint(\n" +" HelloService(name=\"Гвидо\", title=\"мистер\"),\n" +" HelloEmojiService(name=\"👨\", title=\"🎩\")\n" +") as loop:\n" +" pass\n" +"\n" +"# Привет мистер Гвидо\n" +"# 🙋 🎩 👨" + #: ../../source/tutorial.rst:345 msgid "" "If the inheritor declares these methods differently, there will be an " @@ -255,6 +717,18 @@ msgstr "" "Если наследник объявит эти методы по-другому, будет ошибка на этапе " "объявления класса." +#: ../../source/tutorial.rst:348 +msgid "" +"class BadHello(HelloService):\n" +" def greeting(self) -> str:\n" +" return f\"{self.title} {self.name}\"\n" +"\n" +"#Traceback (most recent call last):\n" +"#...\n" +"#TypeError: ('Following methods must be coroutine functions', " +"('BadHello.greeting',))" +msgstr "" + #: ../../source/tutorial.rst:360 msgid "dependency injection" msgstr "" @@ -316,6 +790,20 @@ msgstr "" msgid "Lets check an example:" msgstr "Давайте посмотрим на пример:" +#: ../../source/tutorial.rst:388 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"...\n" +"\n" +"with aiomisc.entrypoint(\n" +" OrdinaryService(),\n" +" InfinityService()\n" +") as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/tutorial.rst:401 msgid "" "In this example, we will launch the two services described above and " @@ -346,6 +834,30 @@ msgstr "" "пример, только передадим явно все параметры по умолчанию в " "``entrypoint``." +#: ../../source/tutorial.rst:414 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"...\n" +"\n" +"with aiomisc.entrypoint(\n" +" OrdinaryService(),\n" +" InfinityService(),\n" +" pool_size=4,\n" +" log_level=\"info\",\n" +" log_format=\"color\",\n" +" log_buffering=True,\n" +" log_buffer_size=1024,\n" +" log_flush_interval=0.2,\n" +" log_config=True,\n" +" policy=asyncio.DefaultEventLoopPolicy(),\n" +" debug=False\n" +") as loop:\n" +" loop.run_forever()" +msgstr "" + #: ../../source/tutorial.rst:437 msgid "" "Let's not describe what each parameter does. But in general, " @@ -366,6 +878,23 @@ msgstr "" "Также вы можете запустить ``entrypoint`` без сервисов, просто " "сконфигурировать логирование и прочее:" +#: ../../source/tutorial.rst:445 +msgid "" +"import asyncio\n" +"import logging\n" +"import aiomisc\n" +"\n" +"\n" +"async def sleep_and_exit():\n" +" logging.info(\"Started\")\n" +" await asyncio.sleep(1)\n" +" logging.info(\"Exiting\")\n" +"\n" +"\n" +"with aiomisc.entrypoint(log_level=\"info\") as loop:\n" +" loop.run_until_complete(sleep_and_exit())" +msgstr "" + #: ../../source/tutorial.rst:461 msgid "" "It is also worth paying attention to the ``aiomisc.run``, which is " @@ -376,6 +905,56 @@ msgstr "" "назначению на ``asyncio.run`` при этом поддерживает запуск и остановку " "сервисов и прочее." +#: ../../source/tutorial.rst:465 +msgid "" +"import asyncio\n" +"import logging\n" +"import aiomisc\n" +"\n" +"\n" +"async def sleep_and_exit():\n" +" logging.info(\"Started\")\n" +" await asyncio.sleep(1)\n" +" logging.info(\"Exiting\")\n" +"\n" +"\n" +"aiomisc.run(\n" +" # the first argument\n" +" # is a main coroutine\n" +" sleep_and_exit(),\n" +" # Other positional arguments\n" +" # is service instances\n" +" OrdinaryService(),\n" +" InfinityService(),\n" +" # keyword arguments will\n" +" # be passed as well to the entrypoint\n" +" log_level=\"info\"\n" +")" +msgstr "" +"import asyncio\n" +"import logging\n" +"import aiomisc\n" +"\n" +"\n" +"async def sleep_and_exit():\n" +" logging.info(\"Started\")\n" +" await asyncio.sleep(1)\n" +" logging.info(\"Exiting\")\n" +"\n" +"\n" +"aiomisc.run(\n" +" # первый аргумент\n" +" # это основная короутина\n" +" sleep_and_exit(),\n" +" # Другие позиционные аргументы\n" +" # это экземпляры сервисов\n" +" OrdinaryService(),\n" +" InfinityService(),\n" +" # другие именованные аргументы\n" +" # будут просто переданы в entrypoint\n" +" log_level=\"info\"\n" +")" + #: ../../source/tutorial.rst:493 msgid "" "As I mentioned above, the library contains lots of already realized " @@ -448,10 +1027,54 @@ msgstr "" "В разделе `working with threads`_ официальной документации по python " "даются следующие рекомендации по вызову блокирующих функций в потоках:" +#: ../../source/tutorial.rst:525 +msgid "" +"import asyncio\n" +"\n" +"def blocking_io():\n" +" # File operations (such as logging) can block the event loop.\n" +" with open('/dev/urandom', 'rb') as f:\n" +" return f.read(100)\n" +"\n" +"async def main():\n" +" loop = asyncio.get_running_loop()\n" +" result = await loop.run_in_executor(None, blocking_io)\n" +"\n" +"asyncio.run(main())" +msgstr "" +"import asyncio\n" +"\n" +"def blocking_io():\n" +" # Файловые операции (такие как логирование) могут заблокировать event" +" loop.\n" +" with open('/dev/urandom', 'rb') as f:\n" +" return f.read(100)\n" +"\n" +"async def main():\n" +" loop = asyncio.get_running_loop()\n" +" result = await loop.run_in_executor(None, blocking_io)\n" +"\n" +"asyncio.run(main())" + #: ../../source/tutorial.rst:540 msgid "This library provides a very simple way to do the same:" msgstr "Эта библиотека содержит очень простой способ сделать тоже самое:" +#: ../../source/tutorial.rst:542 +msgid "" +"import aiomisc\n" +"\n" +"@aiomisc.threaded\n" +"def blocking_io():\n" +" with open('/dev/urandom', 'rb') as f:\n" +" return f.read(100)\n" +"\n" +"async def main():\n" +" result = await blocking_io()\n" +"\n" +"aiomisc.run(main())" +msgstr "" + #: ../../source/tutorial.rst:556 msgid "" "As you can see in this example, it is enough to wrap the function with a " @@ -487,6 +1110,48 @@ msgstr "" "Декоратор запускает новый поток, не связанный с каким-либо пулом потоков." " Поток завершится после выхода из функции." +#: ../../source/tutorial.rst:571 +msgid "" +"import hashlib\n" +"import aiomisc\n" +"\n" +"@aiomisc.threaded_separate\n" +"def another_one_useless_coin_miner():\n" +" with open('/dev/urandom', 'rb') as f:\n" +" hasher = hashlib.sha256()\n" +" while True:\n" +" hasher.update(f.read(1024))\n" +" if hasher.hexdigest().startswith(\"0000\"):\n" +" return hasher.hexdigest()\n" +"\n" +"async def main():\n" +" print(\n" +" \"the hash is\",\n" +" await another_one_useless_coin_miner()\n" +" )\n" +"\n" +"aiomisc.run(main())" +msgstr "" +"import hashlib\n" +"import aiomisc\n" +"\n" +"@aiomisc.threaded_separate\n" +"def another_one_useless_coin_miner():\n" +" with open('/dev/urandom', 'rb') as f:\n" +" hasher = hashlib.sha256()\n" +" while True:\n" +" hasher.update(f.read(1024))\n" +" if hasher.hexdigest().startswith(\"0000\"):\n" +" return hasher.hexdigest()\n" +"\n" +"async def main():\n" +" print(\n" +" \"Хэш получился вот такой:\",\n" +" await another_one_useless_coin_miner()\n" +" )\n" +"\n" +"aiomisc.run(main())" + #: ../../source/tutorial.rst:595 msgid "" "This approach allows you not to occupy threads in the pool for a long " @@ -525,6 +1190,27 @@ msgstr "" "Это очень полезно, если, например, драйвер очереди или базы данных " "синхронный, но вы хотите эффективно использовать его в асинхронном коде." +#: ../../source/tutorial.rst:612 +msgid "" +"import aiomisc\n" +"\n" +"@aiomisc.threaded_iterable(max_size=8)\n" +"def urandom_reader():\n" +" with open('/dev/urandom', \"rb\") as fp:\n" +" while True:\n" +" yield fp.read(8)\n" +"\n" +"async def main():\n" +" counter = 0\n" +" async for chunk in urandom_reader():\n" +" print(chunk)\n" +" counter += 1\n" +" if counter > 16:\n" +" break\n" +"\n" +"aiomisc.run(main())" +msgstr "" + #: ../../source/tutorial.rst:632 msgid "" "Under the hood, this decorator returns a special object that has a queue," @@ -545,3 +1231,21 @@ msgstr "" "потоке, слишком большого количества элементов в асинхронный код, в случае" " асинхронной итерации в случае, если асинхронный итератор забирает " "элементы из этой очереди реже чем они поступают." + +#: ../../source/tutorial.rst:641 +msgid "Conclusion" +msgstr "Заключение" + +#: ../../source/tutorial.rst:643 +msgid "" +"On this we need to finish this tutorial, I hope everything was clear " +"here, and you learned a lot of useful things for yourself. A full " +"description of the remaining services is presented in the :doc:`/modules`" +" section, or in the source code. The authors have tried to make the " +"source code as clear and simple as possible, so feel free to explore it." +msgstr "" +"На этом нам нужно закончить этот учебник, надеюсь тут все было понятно, и " +"вы почерпнули для себя много полезного. Полное описание остальных " +"сервисов представлено в разделе :doc:`/modules`, или в исходном коде. Авторы " +"постарались сделать исходный код максимально понятным и простым, поэтому " +"не стесняйтесь исследовать его." diff --git a/docs/source/locale/ru/LC_MESSAGES/utils.po b/docs/source/locale/ru/LC_MESSAGES/utils.po index 71045ca0..c1c9b73a 100644 --- a/docs/source/locale/ru/LC_MESSAGES/utils.po +++ b/docs/source/locale/ru/LC_MESSAGES/utils.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-03 16:47+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" #: ../../source/utils.rst:2 msgid "Utilities" @@ -33,6 +33,39 @@ msgstr "" "объектов с реализованным методом `__await__`) И возвращает список " "результатов." +#: ../../source/utils.rst:10 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"async def main():\n" +" loop = asyncio.get_event_loop()\n" +" event = asyncio.Event()\n" +" future = asyncio.Future()\n" +"\n" +" loop.call_soon(event.set)\n" +"\n" +" await aiomisc.select(event.wait(), future)\n" +" print(event.is_set()) # True\n" +"\n" +" event = asyncio.Event()\n" +" future = asyncio.Future()\n" +"\n" +" loop.call_soon(future.set_result, True)\n" +"\n" +" results = await aiomisc.select(future, event.wait())\n" +" future_result, event_result = results\n" +"\n" +" print(results.result()) # True\n" +" print(results.result_idx) # 0\n" +" print(event_result, future_result) # None, True\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(main())" +msgstr "" + #: ../../source/utils.rst:45 msgid "" "When you don't want to cancel pending tasks pass ``cancel=False`` " @@ -54,6 +87,25 @@ msgstr "" "Все переданные задачи будут отменены, при это функция возвращает " "`asyncio.Task`:" +#: ../../source/utils.rst:54 +msgid "" +"import asyncio\n" +"from aiomisc import cancel_tasks\n" +"\n" +"\n" +"async def main():\n" +" done, pending = await asyncio.wait([\n" +" asyncio.sleep(i) for i in range(10)\n" +" ], timeout=5)\n" +"\n" +" print(\"Done\", len(done), \"tasks\")\n" +" print(\"Pending\", len(pending), \"tasks\")\n" +" await cancel_tasks(pending)\n" +"\n" +"\n" +"asyncio.run(main())" +msgstr "" + #: ../../source/utils.rst:74 msgid "``awaitable``" msgstr "" @@ -77,6 +129,22 @@ msgstr "" "проверять возврат из функции перед тем как использовать ее в `await` " "выражении." +#: ../../source/utils.rst:84 +msgid "" +"import asyncio\n" +"import aiomisc\n" +"\n" +"\n" +"async def do_callback(func, *args):\n" +" awaitable_func = aiomisc.awaitable(func)\n" +"\n" +" return await awaitable_func(*args)\n" +"\n" +"\n" +"print(asyncio.run(do_callback(asyncio.sleep, 2)))\n" +"print(asyncio.run(do_callback(lambda: 45)))" +msgstr "" + #: ../../source/utils.rst:100 msgid "``bind_socket``" msgstr "" @@ -90,6 +158,17 @@ msgstr "" "флаги (вроде ``setblocking(False)``). Так-же определяет семейство адресов" " (IPv6/IPv4) из формата аргумента ``address`` автоматически." +#: ../../source/utils.rst:105 +msgid "" +"from aiomisc import bind_socket\n" +"\n" +"# IPv4 socket\n" +"sock = bind_socket(address=\"127.0.0.1\", port=1234)\n" +"\n" +"# IPv6 socket (on Linux IPv4 socket will be bind too)\n" +"sock = bind_socket(address=\"::1\", port=1234)" +msgstr "" + #: ../../source/utils.rst:117 msgid "``RecurringCallback``" msgstr "" @@ -100,6 +179,68 @@ msgstr "" "Запускает сопрограммы переодически с определяемой пользователем " "стратегией." +#: ../../source/utils.rst:121 +msgid "" +"from typing import Union\n" +"from aiomisc import new_event_loop, RecurringCallback\n" +"\n" +"\n" +"async def callback():\n" +" print(\"Hello\")\n" +"\n" +"\n" +"FIRST_CALL = False\n" +"\n" +"\n" +"async def strategy(_: RecurringCallback) -> Union[int, float]:\n" +" global FIRST_CALL\n" +" if not FIRST_CALL:\n" +" FIRST_CALL = True\n" +" # Delay 5 second if just started\n" +" return 5\n" +"\n" +" # Delay 10 seconds if it is not a first call\n" +" return 10\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" periodic = RecurringCallback(callback)\n" +"\n" +" task = periodic.start(strategy)\n" +" loop.run_forever()" +msgstr "" +"from typing import Union\n" +"from aiomisc import new_event_loop, RecurringCallback\n" +"\n" +"\n" +"async def callback():\n" +" print(\"Hello\")\n" +"\n" +"\n" +"FIRST_CALL = False\n" +"\n" +"\n" +"async def strategy(_: RecurringCallback) -> Union[int, float]:\n" +" global FIRST_CALL\n" +" if not FIRST_CALL:\n" +" FIRST_CALL = True\n" +" # Ждем 5 секунд если только-что запустились\n" +" return 5\n" +"\n" +" # Ждем 10 секунд если это не первый запуск\n" +" return 10\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" periodic = RecurringCallback(callback)\n" +"\n" +" task = periodic.start(strategy)\n" +" loop.run_forever()" + #: ../../source/utils.rst:154 msgid "" "The main purpose is this class is to provide ability to specify the " @@ -116,6 +257,40 @@ msgstr "" "Кроме того, с помощью специальных исключений вы можете управлять " "поведением запущенного ``RecurringCallback``." +#: ../../source/utils.rst:160 +msgid "" +"from aiomisc import (\n" +" new_event_loop, RecurringCallback, StrategySkip, StrategyStop\n" +")\n" +"\n" +"\n" +"async def strategy(_: RecurringCallback) -> Union[int, float]:\n" +" ...\n" +"\n" +" # Skip this attempt and wait 10 seconds\n" +" raise StrategySkip(10)\n" +"\n" +" ...\n" +"\n" +" # Stop execution\n" +" raise StrategyStop()" +msgstr "" +"from aiomisc import (\n" +" new_event_loop, RecurringCallback, StrategySkip, StrategyStop\n" +")\n" +"\n" +"\n" +"async def strategy(_: RecurringCallback) -> Union[int, float]:\n" +" ...\n" +"\n" +" # Пропускаем эту попытку и ждем 10 секунд\n" +" raise StrategySkip(10)\n" +"\n" +" ...\n" +"\n" +" # Stop execution\n" +" raise StrategyStop()" + #: ../../source/utils.rst:178 msgid "" "if the strategy function returns an incorrect value (not a number), or " @@ -137,6 +312,46 @@ msgstr "" "необязательной задержкой при первом запуске. Использует " "``RecurringCallback`` под капотом." +#: ../../source/utils.rst:188 +msgid "" +"import asyncio\n" +"import time\n" +"from aiomisc import new_event_loop, PeriodicCallback\n" +"\n" +"\n" +"async def periodic_function():\n" +" print(\"Hello\")\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" periodic = PeriodicCallback(periodic_function)\n" +"\n" +" # Wait 10 seconds and call it each second after that\n" +" periodic.start(1, delay=10)\n" +"\n" +" loop.run_forever()" +msgstr "" +"import asyncio\n" +"import time\n" +"from aiomisc import new_event_loop, PeriodicCallback\n" +"\n" +"\n" +"async def periodic_function():\n" +" print(\"Hello\")\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" periodic = PeriodicCallback(periodic_function)\n" +"\n" +" # Ждем 10 секунд и вызываем это каждую секунду после этого\n" +" periodic.start(1, delay=10)\n" +"\n" +" loop.run_forever()" + #: ../../source/utils.rst:211 msgid "``CronCallback``" msgstr "" @@ -145,10 +360,18 @@ msgstr "" msgid "You have to install ``croniter`` package for use this feature:" msgstr "Придется установить пакет ``croniter`` чтобы пользоваться этим:" +#: ../../source/utils.rst:217 +msgid "pip install croniter" +msgstr "" + #: ../../source/utils.rst:221 msgid "Or add extras when installing aiomisc:" msgstr "Или указать это как extras при установке aiomisc:" +#: ../../source/utils.rst:223 +msgid "pip install aiomisc[cron]" +msgstr "" + #: ../../source/utils.rst:229 msgid "" "Runs coroutine function with cron scheduling execution. Uses " @@ -157,3 +380,42 @@ msgstr "" "Запускает сопрограммы переодически, как-будто с помощью cron.Использует " "``RecurringCallback`` под капотом." +#: ../../source/utils.rst:232 +msgid "" +"import asyncio\n" +"import time\n" +"from aiomisc import new_event_loop, CronCallback\n" +"\n" +"\n" +"async def cron_function():\n" +" print(\"Hello\")\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" periodic = CronCallback(cron_function)\n" +"\n" +" # call it each second after that\n" +" periodic.start(spec=\"* * * * * *\")\n" +"\n" +" loop.run_forever()" +msgstr "" +"import asyncio\n" +"import time\n" +"from aiomisc import new_event_loop, CronCallback\n" +"\n" +"\n" +"async def cron_function():\n" +" print(\"Hello\")\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" loop = new_event_loop()\n" +"\n" +" periodic = CronCallback(cron_function)\n" +"\n" +" # Будем запускать это каждую секунду\n" +" periodic.start(spec=\"* * * * * *\")\n" +"\n" +" loop.run_forever()" diff --git a/docs/source/locale/ru/LC_MESSAGES/worker_pool.po b/docs/source/locale/ru/LC_MESSAGES/worker_pool.po index 5c0b088b..6e38bf0b 100644 --- a/docs/source/locale/ru/LC_MESSAGES/worker_pool.po +++ b/docs/source/locale/ru/LC_MESSAGES/worker_pool.po @@ -6,14 +6,14 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-08-03 16:49+0300\n" +"POT-Creation-Date: 2022-12-29 11:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.11.0\n" # "Project-Id-Version: latest\n" #: ../../source/worker_pool.rst:2 @@ -87,6 +87,160 @@ msgstr "" msgid "Installing pillow with pip:" msgstr "Установка через pip:" +#: ../../source/worker_pool.rst:33 +msgid "pip install Pillow" +msgstr "" + +#: ../../source/worker_pool.rst:37 +msgid "" +"import asyncio\n" +"import sys\n" +"from multiprocessing import cpu_count\n" +"from typing import Tuple\n" +"from pathlib import Path\n" +"from PIL import Image\n" +"from aiomisc import entrypoint, WorkerPool\n" +"\n" +"\n" +"def thumbnail(src_path: str, dest_path: str, box: Tuple[int, int]):\n" +" img = Image.open(src_path)\n" +" img.thumbnail(box)\n" +" img.save(\n" +" dest_path, \"JPEG\", quality=65,\n" +" optimize=True,\n" +" icc_profile=img.info.get('icc_profile'),\n" +" exif=img.info.get('exif'),\n" +" )\n" +" return img.size\n" +"\n" +"\n" +"sizes = [\n" +" (1024, 1024),\n" +" (512, 512),\n" +" (256, 256),\n" +" (128, 128),\n" +" (64, 64),\n" +" (32, 32),\n" +"]\n" +"\n" +"\n" +"async def amain(path: Path):\n" +" # Create directories\n" +" for size in sizes:\n" +" size_dir = \"x\".join(map(str, size))\n" +" size_path = (path / 'thumbnails' / size_dir)\n" +" size_path.mkdir(parents=True, exist_ok=True)\n" +"\n" +" # Create and run WorkerPool\n" +" async with WorkerPool(cpu_count()) as pool:\n" +" tasks = []\n" +" for image in path.iterdir():\n" +" if not image.name.endswith(\".jpg\"):\n" +" continue\n" +"\n" +" if image.is_relative_to(path / 'thumbnails'):\n" +" continue\n" +"\n" +" for size in sizes:\n" +" rel_path = image.relative_to(path).parent\n" +" size_dir = \"x\".join(map(str, size))\n" +" dest_path = (\n" +" path / rel_path /\n" +" 'thumbnails' / size_dir /\n" +" image.name\n" +" )\n" +"\n" +" tasks.append(\n" +" pool.create_task(\n" +" thumbnail,\n" +" str(image),\n" +" str(dest_path),\n" +" size\n" +" )\n" +" )\n" +"\n" +" await asyncio.gather(*tasks)\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with entrypoint() as loop:\n" +" image_dir = Path(sys.argv[1])\n" +" loop.run_until_complete(amain(image_dir))" +msgstr "" +"import asyncio\n" +"import sys\n" +"from multiprocessing import cpu_count\n" +"from typing import Tuple\n" +"from pathlib import Path\n" +"from PIL import Image\n" +"from aiomisc import entrypoint, WorkerPool\n" +"\n" +"\n" +"def thumbnail(src_path: str, dest_path: str, box: Tuple[int, int]):\n" +" img = Image.open(src_path)\n" +" img.thumbnail(box)\n" +" img.save(\n" +" dest_path, \"JPEG\", quality=65,\n" +" optimize=True,\n" +" icc_profile=img.info.get('icc_profile'),\n" +" exif=img.info.get('exif'),\n" +" )\n" +" return img.size\n" +"\n" +"\n" +"sizes = [\n" +" (1024, 1024),\n" +" (512, 512),\n" +" (256, 256),\n" +" (128, 128),\n" +" (64, 64),\n" +" (32, 32),\n" +"]\n" +"\n" +"\n" +"async def amain(path: Path):\n" +" # Создаем директории\n" +" for size in sizes:\n" +" size_dir = \"x\".join(map(str, size))\n" +" size_path = (path / 'thumbnails' / size_dir)\n" +" size_path.mkdir(parents=True, exist_ok=True)\n" +"\n" +" # Создаем и запускаем WorkerPool\n" +" async with WorkerPool(cpu_count()) as pool:\n" +" tasks = []\n" +" for image in path.iterdir():\n" +" if not image.name.endswith(\".jpg\"):\n" +" continue\n" +"\n" +" if image.is_relative_to(path / 'thumbnails'):\n" +" continue\n" +"\n" +" for size in sizes:\n" +" rel_path = image.relative_to(path).parent\n" +" size_dir = \"x\".join(map(str, size))\n" +" dest_path = (\n" +" path / rel_path /\n" +" 'thumbnails' / size_dir /\n" +" image.name\n" +" )\n" +"\n" +" tasks.append(\n" +" pool.create_task(\n" +" thumbnail,\n" +" str(image),\n" +" str(dest_path),\n" +" size\n" +" )\n" +" )\n" +"\n" +" await asyncio.gather(*tasks)\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" with entrypoint() as loop:\n" +" image_dir = Path(sys.argv[1])\n" +" loop.run_until_complete(amain(image_dir))" + #: ../../source/worker_pool.rst:114 msgid "" "This example takes the image directory as the first command-line argument" @@ -115,4 +269,3 @@ msgid "" msgstr "" "``WorkerPool`` обрабатывает задачи конкурентно, но не более одной задачи " "на одного рабочего в один момент времени" - diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst index b42438ab..050f6a50 100644 --- a/docs/source/tutorial.rst +++ b/docs/source/tutorial.rst @@ -636,3 +636,12 @@ You should always specify the ``max_size`` parameter, which limits the size of this queue and prevents threaded code from sending too much items to asynchronous code, in case the asynchronous iteration in case the asynchronous iteration slacking. + +Conclusion +~~~~~~~~~~ + +On this we need to finish this tutorial, I hope everything was clear here, +and you learned a lot of useful things for yourself. A full description of +the remaining services is presented in the :doc:`/modules` section, or in the +source code. The authors have tried to make the source code as clear and +simple as possible, so feel free to explore it. diff --git a/poetry.toml b/poetry.toml new file mode 100644 index 00000000..b9b5afe4 --- /dev/null +++ b/poetry.toml @@ -0,0 +1,5 @@ +cache-dir = ".cache" + +[virtualenvs] +path = ".venv" +in-project = true diff --git a/pyproject.toml b/pyproject.toml index 3ab6cc2b..5cfede1a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "aiomisc" # This is a dummy version which will be rewritten with poem-plugins -version = "16.3.0" +version = "16.3.2" description = "aiomisc - miscellaneous utils for asyncio" authors = ["Dmitry Orlov "] readme = "README.rst" From f4c0173f7ef9416052f9163cda30b33b274c84b6 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 29 Dec 2022 15:14:30 +0300 Subject: [PATCH 33/45] fixes --- aiomisc/version.py | 9 +- poetry.lock | 3365 ++++++++++++++++++++++++++++---------------- pyproject.toml | 3 +- 3 files changed, 2173 insertions(+), 1204 deletions(-) diff --git a/aiomisc/version.py b/aiomisc/version.py index 01b3e0a0..3fd30480 100644 --- a/aiomisc/version.py +++ b/aiomisc/version.py @@ -1,5 +1,6 @@ -# THIS FILE WAS GENERATED BY "poem_plugins.general.version.drivers.git.GitVersionDriver" -# NEWER EDIT THIS FILE MANUALLY +# THIS FILE WAS GENERATED AUTOMATICALLY +# BY: poem-plugins "git" plugin +# NEVER EDIT THIS FILE MANUALLY -version_info = (16, 3, 2) -__version__ = "16.3.2" +version_info = (16, 3, 3) +__version__ = "16.3.3" diff --git a/poetry.lock b/poetry.lock index 79a14056..92afc84a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Poetry and should not be changed by hand. + [[package]] name = "aiocontextvars" version = "0.2.2" @@ -5,6 +7,10 @@ description = "Asyncio support for PEP-567 contextvars backport." category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "aiocontextvars-0.2.2-py2.py3-none-any.whl", hash = "sha256:885daf8261818767d8f7cbd79f9d4482d118f024b6586ef6e67980236a27bfa3"}, + {file = "aiocontextvars-0.2.2.tar.gz", hash = "sha256:f027372dc48641f683c559f247bd84962becaacdc9ba711d583c3871fb5652aa"}, +] [[package]] name = "aiohttp" @@ -13,6 +19,95 @@ description = "Async http client/server framework (asyncio)" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ba71c9b4dcbb16212f334126cc3d8beb6af377f6703d9dc2d9fb3874fd667ee9"}, + {file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d24b8bb40d5c61ef2d9b6a8f4528c2f17f1c5d2d31fed62ec860f6006142e83e"}, + {file = "aiohttp-3.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f88df3a83cf9df566f171adba39d5bd52814ac0b94778d2448652fc77f9eb491"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97decbb3372d4b69e4d4c8117f44632551c692bb1361b356a02b97b69e18a62"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:309aa21c1d54b8ef0723181d430347d7452daaff93e8e2363db8e75c72c2fb2d"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad5383a67514e8e76906a06741febd9126fc7c7ff0f599d6fcce3e82b80d026f"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20acae4f268317bb975671e375493dbdbc67cddb5f6c71eebdb85b34444ac46b"}, + {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05a3c31c6d7cd08c149e50dc7aa2568317f5844acd745621983380597f027a18"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d6f76310355e9fae637c3162936e9504b4767d5c52ca268331e2756e54fd4ca5"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:256deb4b29fe5e47893fa32e1de2d73c3afe7407738bd3c63829874661d4822d"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5c59fcd80b9049b49acd29bd3598cada4afc8d8d69bd4160cd613246912535d7"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:059a91e88f2c00fe40aed9031b3606c3f311414f86a90d696dd982e7aec48142"}, + {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2feebbb6074cdbd1ac276dbd737b40e890a1361b3cc30b74ac2f5e24aab41f7b"}, + {file = "aiohttp-3.8.3-cp310-cp310-win32.whl", hash = "sha256:5bf651afd22d5f0c4be16cf39d0482ea494f5c88f03e75e5fef3a85177fecdeb"}, + {file = "aiohttp-3.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:653acc3880459f82a65e27bd6526e47ddf19e643457d36a2250b85b41a564715"}, + {file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:86fc24e58ecb32aee09f864cb11bb91bc4c1086615001647dbfc4dc8c32f4008"}, + {file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75e14eac916f024305db517e00a9252714fce0abcb10ad327fb6dcdc0d060f1d"}, + {file = "aiohttp-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d1fde0f44029e02d02d3993ad55ce93ead9bb9b15c6b7ccd580f90bd7e3de476"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab94426ddb1ecc6a0b601d832d5d9d421820989b8caa929114811369673235c"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89d2e02167fa95172c017732ed7725bc8523c598757f08d13c5acca308e1a061"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02f9a2c72fc95d59b881cf38a4b2be9381b9527f9d328771e90f72ac76f31ad8"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7149272fb5834fc186328e2c1fa01dda3e1fa940ce18fded6d412e8f2cf76d"}, + {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:512bd5ab136b8dc0ffe3fdf2dfb0c4b4f49c8577f6cae55dca862cd37a4564e2"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7018ecc5fe97027214556afbc7c502fbd718d0740e87eb1217b17efd05b3d276"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88c70ed9da9963d5496d38320160e8eb7e5f1886f9290475a881db12f351ab5d"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:da22885266bbfb3f78218dc40205fed2671909fbd0720aedba39b4515c038091"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:e65bc19919c910127c06759a63747ebe14f386cda573d95bcc62b427ca1afc73"}, + {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:08c78317e950e0762c2983f4dd58dc5e6c9ff75c8a0efeae299d363d439c8e34"}, + {file = "aiohttp-3.8.3-cp311-cp311-win32.whl", hash = "sha256:45d88b016c849d74ebc6f2b6e8bc17cabf26e7e40c0661ddd8fae4c00f015697"}, + {file = "aiohttp-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:96372fc29471646b9b106ee918c8eeb4cca423fcbf9a34daa1b93767a88a2290"}, + {file = "aiohttp-3.8.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c971bf3786b5fad82ce5ad570dc6ee420f5b12527157929e830f51c55dc8af77"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff25f48fc8e623d95eca0670b8cc1469a83783c924a602e0fbd47363bb54aaca"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e381581b37db1db7597b62a2e6b8b57c3deec95d93b6d6407c5b61ddc98aca6d"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db19d60d846283ee275d0416e2a23493f4e6b6028825b51290ac05afc87a6f97"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25892c92bee6d9449ffac82c2fe257f3a6f297792cdb18ad784737d61e7a9a85"}, + {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:398701865e7a9565d49189f6c90868efaca21be65c725fc87fc305906be915da"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4a4fbc769ea9b6bd97f4ad0b430a6807f92f0e5eb020f1e42ece59f3ecfc4585"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:b29bfd650ed8e148f9c515474a6ef0ba1090b7a8faeee26b74a8ff3b33617502"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:1e56b9cafcd6531bab5d9b2e890bb4937f4165109fe98e2b98ef0dcfcb06ee9d"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ec40170327d4a404b0d91855d41bfe1fe4b699222b2b93e3d833a27330a87a6d"}, + {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2df5f139233060578d8c2c975128fb231a89ca0a462b35d4b5fcf7c501ebdbe1"}, + {file = "aiohttp-3.8.3-cp36-cp36m-win32.whl", hash = "sha256:f973157ffeab5459eefe7b97a804987876dd0a55570b8fa56b4e1954bf11329b"}, + {file = "aiohttp-3.8.3-cp36-cp36m-win_amd64.whl", hash = "sha256:437399385f2abcd634865705bdc180c8314124b98299d54fe1d4c8990f2f9494"}, + {file = "aiohttp-3.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:09e28f572b21642128ef31f4e8372adb6888846f32fecb288c8b0457597ba61a"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f3553510abdbec67c043ca85727396ceed1272eef029b050677046d3387be8d"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e168a7560b7c61342ae0412997b069753f27ac4862ec7867eff74f0fe4ea2ad9"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db4c979b0b3e0fa7e9e69ecd11b2b3174c6963cebadeecfb7ad24532ffcdd11a"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e164e0a98e92d06da343d17d4e9c4da4654f4a4588a20d6c73548a29f176abe2"}, + {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a78079d9a39ca9ca99a8b0ac2fdc0c4d25fc80c8a8a82e5c8211509c523363"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:21b30885a63c3f4ff5b77a5d6caf008b037cb521a5f33eab445dc566f6d092cc"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4b0f30372cef3fdc262f33d06e7b411cd59058ce9174ef159ad938c4a34a89da"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:8135fa153a20d82ffb64f70a1b5c2738684afa197839b34cc3e3c72fa88d302c"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ad61a9639792fd790523ba072c0555cd6be5a0baf03a49a5dd8cfcf20d56df48"}, + {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978b046ca728073070e9abc074b6299ebf3501e8dee5e26efacb13cec2b2dea0"}, + {file = "aiohttp-3.8.3-cp37-cp37m-win32.whl", hash = "sha256:0d2c6d8c6872df4a6ec37d2ede71eff62395b9e337b4e18efd2177de883a5033"}, + {file = "aiohttp-3.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:21d69797eb951f155026651f7e9362877334508d39c2fc37bd04ff55b2007091"}, + {file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ca9af5f8f5812d475c5259393f52d712f6d5f0d7fdad9acdb1107dd9e3cb7eb"}, + {file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d90043c1882067f1bd26196d5d2db9aa6d268def3293ed5fb317e13c9413ea4"}, + {file = "aiohttp-3.8.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d737fc67b9a970f3234754974531dc9afeea11c70791dcb7db53b0cf81b79784"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebf909ea0a3fc9596e40d55d8000702a85e27fd578ff41a5500f68f20fd32e6c"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5835f258ca9f7c455493a57ee707b76d2d9634d84d5d7f62e77be984ea80b849"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da37dcfbf4b7f45d80ee386a5f81122501ec75672f475da34784196690762f4b"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f44875f2804bc0511a69ce44a9595d5944837a62caecc8490bbdb0e18b1342"}, + {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:527b3b87b24844ea7865284aabfab08eb0faf599b385b03c2aa91fc6edd6e4b6"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5ba88df9aa5e2f806650fcbeedbe4f6e8736e92fc0e73b0400538fd25a4dd96"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e7b8813be97cab8cb52b1375f41f8e6804f6507fe4660152e8ca5c48f0436017"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2dea10edfa1a54098703cb7acaa665c07b4e7568472a47f4e64e6319d3821ccf"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:713d22cd9643ba9025d33c4af43943c7a1eb8547729228de18d3e02e278472b6"}, + {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2d252771fc85e0cf8da0b823157962d70639e63cb9b578b1dec9868dd1f4f937"}, + {file = "aiohttp-3.8.3-cp38-cp38-win32.whl", hash = "sha256:66bd5f950344fb2b3dbdd421aaa4e84f4411a1a13fca3aeb2bcbe667f80c9f76"}, + {file = "aiohttp-3.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:84b14f36e85295fe69c6b9789b51a0903b774046d5f7df538176516c3e422446"}, + {file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16c121ba0b1ec2b44b73e3a8a171c4f999b33929cd2397124a8c7fcfc8cd9e06"}, + {file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8d6aaa4e7155afaf994d7924eb290abbe81a6905b303d8cb61310a2aba1c68ba"}, + {file = "aiohttp-3.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43046a319664a04b146f81b40e1545d4c8ac7b7dd04c47e40bf09f65f2437346"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599418aaaf88a6d02a8c515e656f6faf3d10618d3dd95866eb4436520096c84b"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a2964319d359f494f16011e23434f6f8ef0434acd3cf154a6b7bec511e2fb7"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73a4131962e6d91109bca6536416aa067cf6c4efb871975df734f8d2fd821b37"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598adde339d2cf7d67beaccda3f2ce7c57b3b412702f29c946708f69cf8222aa"}, + {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75880ed07be39beff1881d81e4a907cafb802f306efd6d2d15f2b3c69935f6fb"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0239da9fbafd9ff82fd67c16704a7d1bccf0d107a300e790587ad05547681c8"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4e3a23ec214e95c9fe85a58470b660efe6534b83e6cbe38b3ed52b053d7cb6ad"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:47841407cc89a4b80b0c52276f3cc8138bbbfba4b179ee3acbd7d77ae33f7ac4"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:54d107c89a3ebcd13228278d68f1436d3f33f2dd2af5415e3feaeb1156e1a62c"}, + {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c37c5cce780349d4d51739ae682dec63573847a2a8dcb44381b174c3d9c8d403"}, + {file = "aiohttp-3.8.3-cp39-cp39-win32.whl", hash = "sha256:f178d2aadf0166be4df834c4953da2d7eef24719e8aec9a65289483eeea9d618"}, + {file = "aiohttp-3.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:88e5be56c231981428f4f506c68b6a46fa25c4123a2e86d156c58a8369d31ab7"}, + {file = "aiohttp-3.8.3.tar.gz", hash = "sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269"}, +] [package.dependencies] aiosignal = ">=1.1.2" @@ -35,6 +130,10 @@ description = "Adapter to running ASGI applications on aiohttp" category = "dev" optional = false python-versions = ">3.6.*, <4" +files = [ + {file = "aiohttp-asgi-0.4.3.tar.gz", hash = "sha256:2b211ed97ad174bdfcf2419465386e2af83ad4cf25bb06a463ad49e8e038e185"}, + {file = "aiohttp_asgi-0.4.3-py3-none-any.whl", hash = "sha256:1a77540f4758a6c8736797abd553e80e29a8cade6c864808d483e98e35a78724"}, +] [package.dependencies] aiohttp = "<4" @@ -49,6 +148,10 @@ description = "aiosignal: a list of registered asynchronous callbacks" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] [package.dependencies] frozenlist = ">=1.1.0" @@ -60,6 +163,10 @@ description = "A configurable sidebar-enabled Sphinx theme" category = "dev" optional = false python-versions = "*" +files = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] [[package]] name = "anyio" @@ -68,6 +175,10 @@ description = "High level compatibility layer for multiple asynchronous event lo category = "dev" optional = false python-versions = ">=3.6.2" +files = [ + {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, + {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, +] [package.dependencies] idna = ">=2.8" @@ -86,6 +197,10 @@ description = "Timeout context manager for asyncio programs" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, + {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, +] [package.dependencies] typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} @@ -97,14 +212,22 @@ description = "Enhance the standard unittest package with features for testing a category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, + {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, +] [[package]] name = "attrs" version = "22.1.0" description = "Classes Without Boilerplate" -category = "dev" +category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, +] [package.extras] dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] @@ -119,6 +242,9 @@ description = "Autodoc Python implementation." category = "dev" optional = false python-versions = "*" +files = [ + {file = "autodoc-0.5.0.tar.gz", hash = "sha256:c4387c5a0f1c09b055bb2e384542ee1e016542f313b2a33d904ca77f0460ded3"}, +] [package.dependencies] decorator = "*" @@ -131,6 +257,9 @@ description = "Removes unused imports and unused variables" category = "dev" optional = false python-versions = "*" +files = [ + {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, +] [package.dependencies] pyflakes = ">=1.1.0" @@ -142,10 +271,26 @@ description = "Internationalization utilities" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, + {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, +] [package.dependencies] pytz = ">=2015.7" +[[package]] +name = "backports-cached-property" +version = "1.0.2" +description = "cached_property() - computed once per instance, cached as attribute" +category = "main" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "backports.cached-property-1.0.2.tar.gz", hash = "sha256:9306f9eed6ec55fd156ace6bc1094e2c86fae5fb2bf07b6a9c00745c656e75dd"}, + {file = "backports.cached_property-1.0.2-py3-none-any.whl", hash = "sha256:baeb28e1cd619a3c9ab8941431fe34e8490861fb998c6c4590693d50171db0cc"}, +] + [[package]] name = "beautifulsoup4" version = "4.11.1" @@ -153,6 +298,10 @@ description = "Screen-scraping library" category = "dev" optional = false python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, +] [package.dependencies] soupsieve = ">1.2" @@ -161,13 +310,115 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] +[[package]] +name = "cachecontrol" +version = "0.12.11" +description = "httplib2 caching for requests" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "CacheControl-0.12.11-py2.py3-none-any.whl", hash = "sha256:2c75d6a8938cb1933c75c50184549ad42728a27e9f6b92fd677c3151aa72555b"}, + {file = "CacheControl-0.12.11.tar.gz", hash = "sha256:a5b9fcc986b184db101aa280b42ecdcdfc524892596f606858e0b7a8b4d9e144"}, +] + +[package.dependencies] +lockfile = {version = ">=0.9", optional = true, markers = "extra == \"filecache\""} +msgpack = ">=0.5.2" +requests = "*" + +[package.extras] +filecache = ["lockfile (>=0.9)"] +redis = ["redis (>=2.10.5)"] + [[package]] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." -category = "dev" +category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, +] + +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] + +[package.dependencies] +pycparser = "*" [[package]] name = "cfgv" @@ -176,18 +427,42 @@ description = "Validate configuration and produce human readable error messages. category = "dev" optional = false python-versions = ">=3.6.1" +files = [ + {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, + {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, +] [[package]] name = "charset-normalizer" version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" +category = "main" optional = false python-versions = ">=3.6.0" +files = [ + {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, + {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, +] [package.extras] unicode-backport = ["unicodedata2"] +[[package]] +name = "cleo" +version = "2.0.1" +description = "Cleo allows you to create beautiful and testable command-line interfaces." +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "cleo-2.0.1-py3-none-any.whl", hash = "sha256:6eb133670a3ed1f3b052d53789017b6e50fca66d1287e6e6696285f4cb8ea448"}, + {file = "cleo-2.0.1.tar.gz", hash = "sha256:eb4b2e1f3063c11085cebe489a6e9124163c226575a3c3be69b2e51af4a15ec5"}, +] + +[package.dependencies] +crashtest = ">=0.4.1,<0.5.0" +rapidfuzz = ">=2.2.0,<3.0.0" + [[package]] name = "click" version = "8.1.3" @@ -195,6 +470,10 @@ description = "Composable command line interface toolkit" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -207,6 +486,9 @@ description = "Distutils command to view and validate restructured text in packa category = "dev" optional = false python-versions = "*" +files = [ + {file = "collective.checkdocs-0.2.zip", hash = "sha256:3a5328257c5224bc72753820c182910d7fb336bc1dba5e09113d48566655e46e"}, +] [package.dependencies] docutils = "*" @@ -218,6 +500,10 @@ description = "Cross-platform colored terminal text." category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] [[package]] name = "colorlog" @@ -226,6 +512,10 @@ description = "Add colours to the output of Python's logging module." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, + {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, +] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} @@ -240,6 +530,10 @@ description = "Python parser for the CommonMark Markdown spec" category = "dev" optional = false python-versions = "*" +files = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] [package.extras] test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] @@ -251,6 +545,58 @@ description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, + {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, + {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, + {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, + {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, + {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, + {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, + {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, + {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, + {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, + {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, + {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, + {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, + {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, + {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, + {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, +] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} @@ -265,6 +611,10 @@ description = "Show coverage stats online via coveralls.io" category = "dev" optional = false python-versions = ">= 3.5" +files = [ + {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"}, + {file = "coveralls-3.3.1.tar.gz", hash = "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea"}, +] [package.dependencies] coverage = ">=4.1,<6.0.0 || >6.1,<6.1.1 || >6.1.1,<7.0" @@ -274,6 +624,18 @@ requests = ">=1.0.0" [package.extras] yaml = ["PyYAML (>=3.10)"] +[[package]] +name = "crashtest" +version = "0.4.1" +description = "Manage Python errors with ease" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, + {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, +] + [[package]] name = "croniter" version = "1.3.8" @@ -281,25 +643,84 @@ description = "croniter provides iteration for datetime object with cron like fo category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "croniter-1.3.8-py2.py3-none-any.whl", hash = "sha256:d6ed8386d5f4bbb29419dc1b65c4909c04a2322bd15ec0dc5b2877bfa1b75c7a"}, + {file = "croniter-1.3.8.tar.gz", hash = "sha256:32a5ec04e97ec0837bcdf013767abd2e71cceeefd3c2e14c804098ce51ad6cd9"}, +] [package.dependencies] python-dateutil = "*" [[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -category = "dev" +name = "cryptography" +version = "38.0.4" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" optional = false -python-versions = ">=3.5" - +python-versions = ">=3.6" +files = [ + {file = "cryptography-38.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:2fa36a7b2cc0998a3a4d5af26ccb6273f3df133d61da2ba13b3286261e7efb70"}, + {file = "cryptography-38.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:1f13ddda26a04c06eb57119caf27a524ccae20533729f4b1e4a69b54e07035eb"}, + {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2ec2a8714dd005949d4019195d72abed84198d877112abb5a27740e217e0ea8d"}, + {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50a1494ed0c3f5b4d07650a68cd6ca62efe8b596ce743a5c94403e6f11bf06c1"}, + {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10498349d4c8eab7357a8f9aa3463791292845b79597ad1b98a543686fb1ec8"}, + {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:10652dd7282de17990b88679cb82f832752c4e8237f0c714be518044269415db"}, + {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:bfe6472507986613dc6cc00b3d492b2f7564b02b3b3682d25ca7f40fa3fd321b"}, + {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ce127dd0a6a0811c251a6cddd014d292728484e530d80e872ad9806cfb1c5b3c"}, + {file = "cryptography-38.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:53049f3379ef05182864d13bb9686657659407148f901f3f1eee57a733fb4b00"}, + {file = "cryptography-38.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:8a4b2bdb68a447fadebfd7d24855758fe2d6fecc7fed0b78d190b1af39a8e3b0"}, + {file = "cryptography-38.0.4-cp36-abi3-win32.whl", hash = "sha256:1d7e632804a248103b60b16fb145e8df0bc60eed790ece0d12efe8cd3f3e7744"}, + {file = "cryptography-38.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:8e45653fb97eb2f20b8c96f9cd2b3a0654d742b47d638cf2897afbd97f80fa6d"}, + {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca57eb3ddaccd1112c18fc80abe41db443cc2e9dcb1917078e02dfa010a4f353"}, + {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:c9e0d79ee4c56d841bd4ac6e7697c8ff3c8d6da67379057f29e66acffcd1e9a7"}, + {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0e70da4bdff7601b0ef48e6348339e490ebfb0cbe638e083c9c41fb49f00c8bd"}, + {file = "cryptography-38.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:998cd19189d8a747b226d24c0207fdaa1e6658a1d3f2494541cb9dfbf7dcb6d2"}, + {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67461b5ebca2e4c2ab991733f8ab637a7265bb582f07c7c88914b5afb88cb95b"}, + {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:4eb85075437f0b1fd8cd66c688469a0c4119e0ba855e3fef86691971b887caf6"}, + {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3178d46f363d4549b9a76264f41c6948752183b3f587666aff0555ac50fd7876"}, + {file = "cryptography-38.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6391e59ebe7c62d9902c24a4d8bcbc79a68e7c4ab65863536127c8a9cd94043b"}, + {file = "cryptography-38.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:78e47e28ddc4ace41dd38c42e6feecfdadf9c3be2af389abbfeef1ff06822285"}, + {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fb481682873035600b5502f0015b664abc26466153fab5c6bc92c1ea69d478b"}, + {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:4367da5705922cf7070462e964f66e4ac24162e22ab0a2e9d31f1b270dd78083"}, + {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b4cad0cea995af760f82820ab4ca54e5471fc782f70a007f31531957f43e9dee"}, + {file = "cryptography-38.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:80ca53981ceeb3241998443c4964a387771588c4e4a5d92735a493af868294f9"}, + {file = "cryptography-38.0.4.tar.gz", hash = "sha256:175c1a818b87c9ac80bb7377f5520b7f31b3ef2a0004e2420319beadedb67290"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +sdist = ["setuptools-rust (>=0.11.4)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + [[package]] name = "distlib" version = "0.3.6" description = "Distribution utilities" -category = "dev" +category = "main" optional = false python-versions = "*" +files = [ + {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, + {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, +] [[package]] name = "docopt" @@ -308,6 +729,9 @@ description = "Pythonic argument parser, that will make you smile" category = "dev" optional = false python-versions = "*" +files = [ + {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, +] [[package]] name = "docutils" @@ -316,6 +740,92 @@ description = "Docutils -- Python Documentation Utilities" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, + {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, +] + +[[package]] +name = "dulwich" +version = "0.20.50" +description = "Python Git Library" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "dulwich-0.20.50-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:97f02f8d500d4af08dc022d697c56e8539171acc3f575c2fe9acf3b078e5c8c9"}, + {file = "dulwich-0.20.50-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7301773e5cc16d521bc6490e73772a86a4d1d0263de506f08b54678cc4e2f061"}, + {file = "dulwich-0.20.50-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b70106580ed11f45f4c32d2831d0c9c9f359bc2415fff4a6be443e3a36811398"}, + {file = "dulwich-0.20.50-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f9c4f2455f966cad94648278fa9972e4695b35d04f82792fa58e1ea15dd83f0"}, + {file = "dulwich-0.20.50-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9163fbb021a8ad9c35a0814a5eedf45a8eb3a0b764b865d7016d901fc5a947fc"}, + {file = "dulwich-0.20.50-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:322ff8ff6aa4d6d36294cd36de1c84767eb1903c7db3e7b4475ad091febf5363"}, + {file = "dulwich-0.20.50-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5d3290a45651c8e534f8e83ae2e30322aefdd162f0f338bae2e79a6ee5a87513"}, + {file = "dulwich-0.20.50-cp310-cp310-win32.whl", hash = "sha256:80ab07131a6e68594441f5c4767e9e44e87fceafc3e347e541c928a18c679bd8"}, + {file = "dulwich-0.20.50-cp310-cp310-win_amd64.whl", hash = "sha256:eefe786a6010f8546baac4912113eeed4e397ddb8c433a345b548a04d4176496"}, + {file = "dulwich-0.20.50-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df3562dde3079d57287c233d45b790bc967c5aae975c9a7b07ca30e60e055512"}, + {file = "dulwich-0.20.50-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e1ae18d5805f0c0c5dac65795f8d48660437166b12ee2c0ffea95bfdbf9c1051"}, + {file = "dulwich-0.20.50-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d2f7df39bd1378d3b0bfb3e7fc930fd0191924af1f0ef587bcd9946afe076c06"}, + {file = "dulwich-0.20.50-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:731e7f319b34251fadeb362ada1d52cc932369d9cdfa25c0e41150cda28773d0"}, + {file = "dulwich-0.20.50-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d11d44176e5d2fa8271fc86ad1e0a8731b9ad8f77df64c12846b30e16135eb"}, + {file = "dulwich-0.20.50-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7aaabb8e4beadd53f75f853a981caaadef3ef130e5645c902705704eaf136daa"}, + {file = "dulwich-0.20.50-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c3dc9f97ec8d3db08d9723b9fd06f3e52c15b84c800d153cfb59b0a3dc8b8d40"}, + {file = "dulwich-0.20.50-cp311-cp311-win32.whl", hash = "sha256:3b1964fa80cafd5a1fd71615b0313daf6f3295c6ab05656ea0c1d2423539904a"}, + {file = "dulwich-0.20.50-cp311-cp311-win_amd64.whl", hash = "sha256:a24a3893108f3b97beb958670d5f3f2a3bec73a1fe18637a572a85abd949a1c4"}, + {file = "dulwich-0.20.50-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6d409a282f8848fd6c8d7c7545ad2f75c16de5d5977de202642f1d50fdaac554"}, + {file = "dulwich-0.20.50-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5411d0f1092152e1c0bb916ae490fe181953ae1b8d13f4e68661253e10b78dbb"}, + {file = "dulwich-0.20.50-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6343569f998ce429e2a5d813c56768ac51b496522401db950f0aa44240bfa901"}, + {file = "dulwich-0.20.50-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a405cd236766060894411614a272cfb86fe86cde5ca73ef264fc4fa5a715fff4"}, + {file = "dulwich-0.20.50-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ee0f9b02019c0ea84cdd31c00a0c283669b771c85612997a911715cf84e33d99"}, + {file = "dulwich-0.20.50-cp36-cp36m-win32.whl", hash = "sha256:2644466270267270f2157ea6f1c0aa224f6f3bf06a307fc39954e6b4b3d82bae"}, + {file = "dulwich-0.20.50-cp36-cp36m-win_amd64.whl", hash = "sha256:d4629635a97e3af1b5da48071e00c8e70fad85f3266fadabe1f5a8f49172c507"}, + {file = "dulwich-0.20.50-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0e4862f318d99cc8a500e3622a89613a88c07d957a0f628cdc2ed86addff790f"}, + {file = "dulwich-0.20.50-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96e3fb9d48c0454dc242c7accc7819780c9a7f29e441a9eff12361ed0fa35f9"}, + {file = "dulwich-0.20.50-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc6092a4f0bbbff2e553e87a9c6325955b64ea43fca21297c8182e19ae8a43c"}, + {file = "dulwich-0.20.50-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:519b627d49d273e2fd01c79d09e578675ca6cd05193c1787e9ef165c9a1d66ea"}, + {file = "dulwich-0.20.50-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a75cab01b909c4c683c2083e060e378bc01701b7366b5a7d9846ef6d3b9e3d5"}, + {file = "dulwich-0.20.50-cp37-cp37m-win32.whl", hash = "sha256:ea8ffe26d91dbcd5580dbd5a07270a12ea57b091604d77184da0a0d9fad50ed3"}, + {file = "dulwich-0.20.50-cp37-cp37m-win_amd64.whl", hash = "sha256:8f3af857f94021cae1322d86925bfc0dd31e501e885ab5db275473bfac0bb39d"}, + {file = "dulwich-0.20.50-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3fb35cedb1243bc420d885ef5b4afd642c6ac8f07ddfc7fdbca1becf9948bf7e"}, + {file = "dulwich-0.20.50-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4bb23a9cec63e16c0e432335f068169b73dd44fa9318dd7cd7a4ca83607ff367"}, + {file = "dulwich-0.20.50-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5267619b34ddaf8d9a6b841492cd17a971fd25bf9a5657f2de928385c3a08b94"}, + {file = "dulwich-0.20.50-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9091f1d53a3c0747cbf0bd127c64e7f09b770264d8fb53e284383fcdf69154e7"}, + {file = "dulwich-0.20.50-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6ec7c8fea2b44187a3b545e6c11ab9947ffb122647b07abcdb7cc3aaa770c0e"}, + {file = "dulwich-0.20.50-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:11b180b80363b4fc70664197028181a17ae4c52df9965a29b62a6c52e40c2dbe"}, + {file = "dulwich-0.20.50-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c83e7840d9d0a94d7033bc109efe0c22dfcdcd816bcd4469085e42809e3bf5ba"}, + {file = "dulwich-0.20.50-cp38-cp38-win32.whl", hash = "sha256:c075f69c2de19d9fd97e3b70832d2b42c6a4a5d909b3ffd1963b67d86029f95f"}, + {file = "dulwich-0.20.50-cp38-cp38-win_amd64.whl", hash = "sha256:06775c5713cfeda778c7c67d4422b5e7554d3a7f644f1dde646cdf486a30285a"}, + {file = "dulwich-0.20.50-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:49f66f1c057c18d7d60363f461f4ab8329320fbe1f02a7a33c255864a7d3c942"}, + {file = "dulwich-0.20.50-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e541cd690a5e3d55082ed51732d755917e933cddeb4b0204f2a5ec5d5d7b60b"}, + {file = "dulwich-0.20.50-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:80e8750ee2fa0ab2784a095956077758e5f6107de27f637c4b9d18406652c22c"}, + {file = "dulwich-0.20.50-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fbb6368f18451dc44c95c55e1a609d1a01d3821f7ed480b22b2aea1baca0f4a7"}, + {file = "dulwich-0.20.50-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3ee45001411b638641819b7b3b33f31f13467c84066e432256580fcab7d8815"}, + {file = "dulwich-0.20.50-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4842e22ed863a776b36ef8ffe9ed7b772eb452b42c8d02975c29d27e3bc50ab4"}, + {file = "dulwich-0.20.50-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:790e4a641284a7fb4d56ebdaf8b324a5826fbbb9c54307c06f586f9f6a5e56db"}, + {file = "dulwich-0.20.50-cp39-cp39-win32.whl", hash = "sha256:f08406b6b789dea5c95ba1130a0801d8748a67f18be940fe7486a8b481fde875"}, + {file = "dulwich-0.20.50-cp39-cp39-win_amd64.whl", hash = "sha256:78c388ad421199000fb7b5ed5f0c7b509b3e31bd7cad303786a4d0bf89b82f60"}, + {file = "dulwich-0.20.50-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cb194c53109131bcbcd1ca430fcd437cdaf2d33e204e45fbe121c47eaa43e9af"}, + {file = "dulwich-0.20.50-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7542a72c5640dd0620862d6df8688f02a6c336359b5af9b3fcfe11b7fa6652f"}, + {file = "dulwich-0.20.50-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa1d0861517ebbbe0e0084cc9ab4f7ab720624a3eda2bd10e45f774ab858db8"}, + {file = "dulwich-0.20.50-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:583c6bbc27f13fe2e41a19f6987a42681c6e4f6959beae0a6e5bb033b8b081a8"}, + {file = "dulwich-0.20.50-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0c61c193d02c0e1e0d758cdd57ae76685c368d09a01f00d704ba88bd96767cfe"}, + {file = "dulwich-0.20.50-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2edbff3053251985f10702adfafbee118298d383ef5b5b432a5f22d1f1915df"}, + {file = "dulwich-0.20.50-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a344230cadfc5d315752add6ce9d4cfcfc6c85e36bbf57fce9444bcc7c6ea8fb"}, + {file = "dulwich-0.20.50-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bff9bde0b6b05b00c6acbb1a94357caddb2908ed7026a48c715ff50d220335"}, + {file = "dulwich-0.20.50-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e29a3c2037761fa816aa556e78364dfc8e3f44b873db2d17aed96f9b06ac83a3"}, + {file = "dulwich-0.20.50-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2aa2a4a84029625bf9c63771f8a628db1f3be2d2ea3cb8b17942cd4317797152"}, + {file = "dulwich-0.20.50-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd9fa00971ecf059bb358085a942ecac5be4ff71acdf299f44c8cbc45c18659f"}, + {file = "dulwich-0.20.50-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4adac92fb95671ea3a24f2f8e5e5e8f638711ce9c33a3ca6cd68bf1ff7d99f"}, + {file = "dulwich-0.20.50.tar.gz", hash = "sha256:50a941796b2c675be39be728d540c16b5b7ce77eb9e1b3f855650ece6832d2be"}, +] + +[package.dependencies] +urllib3 = ">=1.25" + +[package.extras] +fastimport = ["fastimport"] +https = ["urllib3 (>=1.24.1)"] +paramiko = ["paramiko"] +pgp = ["gpg"] [[package]] name = "exceptiongroup" @@ -324,6 +834,10 @@ description = "Backport of PEP 654 (exception groups)" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"}, + {file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"}, +] [package.extras] test = ["pytest (>=6)"] @@ -335,6 +849,10 @@ description = "FastAPI framework, high performance, easy to learn, fast to code, category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "fastapi-0.88.0-py3-none-any.whl", hash = "sha256:263b718bb384422fe3d042ffc9a0c8dece5e034ab6586ff034f6b4b1667c3eee"}, + {file = "fastapi-0.88.0.tar.gz", hash = "sha256:915bf304180a0e7c5605ec81097b7d4cd8826ff87a02bb198e336fb9f3b5ff02"}, +] [package.dependencies] pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" @@ -350,9 +868,13 @@ test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==22.10.0)", "coverage[toml] (>= name = "filelock" version = "3.8.2" description = "A platform independent file lock." -category = "dev" +category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "filelock-3.8.2-py3-none-any.whl", hash = "sha256:8df285554452285f79c035efb0c861eb33a4bcfa5b7a137016e32e6a90f9792c"}, + {file = "filelock-3.8.2.tar.gz", hash = "sha256:7565f628ea56bfcd8e54e42bdc55da899c85c1abfe1b5bcfd147e9188cebb3b2"}, +] [package.extras] docs = ["furo (>=2022.9.29)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] @@ -365,6 +887,10 @@ description = "Let your Python tests travel through time" category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "freezegun-1.0.0-py2.py3-none-any.whl", hash = "sha256:02b35de52f4699a78f6ac4518e4cd3390dddc43b0aeb978335a8f270a2d9668b"}, + {file = "freezegun-1.0.0.tar.gz", hash = "sha256:1cf08e441f913ff5e59b19cc065a8faa9dd1ddc442eaf0375294f344581a0643"}, +] [package.dependencies] python-dateutil = ">=2.7" @@ -376,6 +902,82 @@ description = "A list-like structure which implements collections.abc.MutableSeq category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, + {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, + {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, + {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, + {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, + {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, + {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, + {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, + {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, + {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, + {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, +] [[package]] name = "furo" @@ -384,6 +986,10 @@ description = "A clean customisable Sphinx documentation theme." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "furo-2022.12.7-py3-none-any.whl", hash = "sha256:7cb76c12a25ef65db85ab0743df907573d03027a33631f17d267e598ebb191f7"}, + {file = "furo-2022.12.7.tar.gz", hash = "sha256:d8008f8efbe7587a97ba533c8b2df1f9c21ee9b3e5cad0d27f61193d38b1a986"}, +] [package.dependencies] beautifulsoup4 = "*" @@ -391,6 +997,28 @@ pygments = ">=2.7" sphinx = ">=5.0,<7.0" sphinx-basic-ng = "*" +[[package]] +name = "html5lib" +version = "1.1" +description = "HTML parser based on the WHATWG HTML specification" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, + {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, +] + +[package.dependencies] +six = ">=1.9" +webencodings = "*" + +[package.extras] +all = ["chardet (>=2.2)", "genshi", "lxml"] +chardet = ["chardet (>=2.2)"] +genshi = ["genshi"] +lxml = ["lxml"] + [[package]] name = "identify" version = "2.5.11" @@ -398,6 +1026,10 @@ description = "File identification library for Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "identify-2.5.11-py2.py3-none-any.whl", hash = "sha256:e7db36b772b188099616aaf2accbee122949d1c6a1bac4f38196720d6f9f06db"}, + {file = "identify-2.5.11.tar.gz", hash = "sha256:14b7076b29c99b1b0b8b08e96d448c7b877a9b07683cd8cfda2ea06af85ffa1c"}, +] [package.extras] license = ["ukkonen"] @@ -406,9 +1038,13 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "dev" +category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] [[package]] name = "imagesize" @@ -417,24 +1053,51 @@ description = "Getting image size from png/jpeg/jpeg2000/gif file" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] [[package]] name = "importlib-metadata" -version = "5.2.0" +version = "4.13.0" description = "Read metadata from Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"}, + {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"}, +] [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] perf = ["ipython"] testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +[[package]] +name = "importlib-resources" +version = "5.10.2" +description = "Read resources from Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "importlib_resources-5.10.2-py3-none-any.whl", hash = "sha256:7d543798b0beca10b6a01ac7cafda9f822c54db9e8376a6bf57e0cbd74d486b6"}, + {file = "importlib_resources-5.10.2.tar.gz", hash = "sha256:e4a96c8cc0339647ff9a5e0550d9f276fc5a01ffa276012b58ec108cfd7b8484"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + [[package]] name = "iniconfig" version = "1.1.1" @@ -442,6 +1105,45 @@ description = "iniconfig: brain-dead simple config-ini parsing" category = "dev" optional = false python-versions = "*" +files = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] + +[[package]] +name = "jaraco-classes" +version = "3.2.3" +description = "Utility functions for Python class constructs" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jaraco.classes-3.2.3-py3-none-any.whl", hash = "sha256:2353de3288bc6b82120752201c6b1c1a14b058267fa424ed5ce5984e3b922158"}, + {file = "jaraco.classes-3.2.3.tar.gz", hash = "sha256:89559fa5c1d3c34eff6f631ad80bb21f378dbcbb35dd161fd2c6b93f5be2f98a"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[[package]] +name = "jeepney" +version = "0.8.0" +description = "Low-level, pure Python DBus protocol wrapper." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, + {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, +] + +[package.extras] +test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] +trio = ["async_generator", "trio"] [[package]] name = "jinja2" @@ -450,6 +1152,10 @@ description = "A very fast and expressive template engine." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] [package.dependencies] MarkupSafe = ">=2.0" @@ -457,6 +1163,55 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jsonschema" +version = "4.17.3" +description = "An implementation of JSON Schema validation for Python" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, +] + +[package.dependencies] +attrs = ">=17.4.0" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "keyring" +version = "23.13.1" +description = "Store and access your passwords safely." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "keyring-23.13.1-py3-none-any.whl", hash = "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd"}, + {file = "keyring-23.13.1.tar.gz", hash = "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} +importlib-resources = {version = "*", markers = "python_version < \"3.9\""} +"jaraco.classes" = "*" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +completion = ["shtab"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + [[package]] name = "livereload" version = "2.6.3" @@ -464,11 +1219,27 @@ description = "Python LiveReload is an awesome tool for web developers" category = "dev" optional = false python-versions = "*" +files = [ + {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"}, + {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, +] [package.dependencies] six = "*" tornado = {version = "*", markers = "python_version > \"2.7\""} +[[package]] +name = "lockfile" +version = "0.12.2" +description = "Platform-independent file locking module" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, + {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, +] + [[package]] name = "logging-journald" version = "0.6.4" @@ -476,6 +1247,10 @@ description = "Pure python logging handler for writing logs to the journald usin category = "main" optional = false python-versions = ">=3.7,<4.0" +files = [ + {file = "logging_journald-0.6.4-py3-none-any.whl", hash = "sha256:4d4e169cf2814ddbc30687daef2ce38a58a0ec9cd7d739f21f0fb745c4a70ee9"}, + {file = "logging_journald-0.6.4.tar.gz", hash = "sha256:a03aa0a1b85ab5f3cdc534511d98ff55f58479e44fbf4e9eb5b965923cbb0c27"}, +] [[package]] name = "markupsafe" @@ -484,1128 +1259,7 @@ description = "Safely add untrusted strings to HTML/XML markup." category = "dev" optional = false python-versions = ">=3.7" - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "multidict" -version = "6.0.3" -description = "multidict implementation" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "mypy" -version = "0.991" -description = "Optional static typing for Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -mypy-extensions = ">=0.4.3" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} -typing-extensions = ">=3.10" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -install-types = ["pip"] -python2 = ["typed-ast (>=1.4.0,<2)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "nodeenv" -version = "1.7.0" -description = "Node.js virtual environment builder" -category = "dev" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" - -[package.dependencies] -setuptools = "*" - -[[package]] -name = "packaging" -version = "22.0" -description = "Core utilities for Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "platformdirs" -version = "2.6.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] -test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] - -[[package]] -name = "pluggy" -version = "1.0.0" -description = "plugin and hook calling mechanisms for python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "2.20.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -toml = "*" -virtualenv = ">=20.0.8" - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "pycodestyle" -version = "2.10.0" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pydantic" -version = "1.10.2" -description = "Data validation and settings management using python type hints" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -typing-extensions = ">=4.1.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pydocstyle" -version = "6.1.1" -description = "Python docstring style checker" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -snowballstemmer = "*" - -[package.extras] -toml = ["toml"] - -[[package]] -name = "pyflakes" -version = "3.0.1" -description = "passive checker of Python programs" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pygments" -version = "2.13.0" -description = "Pygments is a syntax highlighting package written in Python." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -plugins = ["importlib-metadata"] - -[[package]] -name = "pylama" -version = "8.4.1" -description = "Code audit tool for python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -mccabe = ">=0.7.0" -pycodestyle = ">=2.9.1" -pydocstyle = ">=6.1.1" -pyflakes = ">=2.5.0" - -[package.extras] -all = ["eradicate", "mypy", "pylint", "radon", "vulture"] -eradicate = ["eradicate"] -mypy = ["mypy"] -pylint = ["pylint"] -radon = ["radon"] -tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "pytest (>=7.1.2)", "pytest-mypy", "radon (>=5.1.0)", "toml", "types-setuptools", "types-toml", "vulture"] -toml = ["toml (>=0.10.2)"] -vulture = ["vulture"] - -[[package]] -name = "pytest" -version = "7.2.0" -description = "pytest: simple powerful testing with Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "4.0.0" -description = "Pytest plugin for measuring coverage." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - -[[package]] -name = "pytest-freezegun" -version = "0.4.2" -description = "Wrap tests with fixtures in freeze_time" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -freezegun = ">0.3" -pytest = ">=3.0.0" - -[[package]] -name = "pytest-rst" -version = "0.0.7" -description = "Test code from RST documents with pytest" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -docutils = "*" -py = "*" -pygments = "*" -pytest = "*" - -[[package]] -name = "pytest-subtests" -version = "0.9.0" -description = "unittest subTest() support and subtests fixture" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -pytest = ">=7.0" - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2022.7" -description = "World timezone definitions, modern and historical" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pyyaml" -version = "6.0" -description = "YAML parser and emitter for Python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "raven" -version = "6.10.0" -description = "Raven is a client for Sentry (https://getsentry.com)" -category = "dev" -optional = false -python-versions = "*" - -[package.extras] -flask = ["Flask (>=0.8)", "blinker (>=1.1)"] -tests = ["Flask (>=0.8)", "Flask-Login (>=0.2.0)", "ZConfig", "aiohttp", "anyjson", "blinker (>=1.1)", "blinker (>=1.1)", "bottle", "celery (>=2.5)", "coverage (<4)", "exam (>=0.5.2)", "flake8 (==3.5.0)", "logbook", "mock", "nose", "pytest (>=3.2.0,<3.3.0)", "pytest-cov (==2.5.1)", "pytest-flake8 (==1.0.0)", "pytest-pythonpath (==0.7.2)", "pytest-timeout (==1.2.1)", "pytest-xdist (==1.18.2)", "pytz", "requests", "sanic (>=0.7.0)", "tornado (>=4.1,<5.0)", "tox", "webob", "webtest", "wheel"] - -[[package]] -name = "requests" -version = "2.28.1" -description = "Python HTTP for Humans." -category = "dev" -optional = false -python-versions = ">=3.7, <4" - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<3" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "rich" -version = "12.6.0" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "dev" -optional = false -python-versions = ">=3.6.3,<4.0.0" - -[package.dependencies] -commonmark = ">=0.9.0,<0.10.0" -pygments = ">=2.6.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] - -[[package]] -name = "setproctitle" -version = "1.3.2" -description = "A Python module to customize the process title" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "setuptools" -version = "65.6.3" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "sniffio" -version = "1.3.0" -description = "Sniff out which async library your code is running under" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "soupsieve" -version = "2.3.2.post1" -description = "A modern CSS selector implementation for Beautiful Soup." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "sphinx" -version = "5.3.0" -description = "Python documentation generator" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=2.9" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.20" -imagesize = ">=1.3" -importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.0" -packaging = ">=21.0" -Pygments = ">=2.12" -requests = ">=2.5.0" -snowballstemmer = ">=2.0" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] - -[[package]] -name = "sphinx-autobuild" -version = "2021.3.14" -description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -colorama = "*" -livereload = "*" -sphinx = "*" - -[package.extras] -test = ["pytest", "pytest-cov"] - -[[package]] -name = "sphinx-basic-ng" -version = "1.0.0b1" -description = "A modern skeleton for Sphinx themes." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -sphinx = ">=4.0" - -[package.extras] -docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"] - -[[package]] -name = "sphinx-intl" -version = "2.0.1" -description = "Sphinx utility that make it easy to translate and to apply translation." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.dependencies] -babel = "*" -click = "*" -setuptools = "*" -sphinx = "*" - -[package.extras] -test = ["mock", "pytest"] -transifex = ["transifex_client (>=0.11)"] - -[[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.2" -description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["html5lib", "pytest"] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -test = ["flake8", "mypy", "pytest"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "starlette" -version = "0.22.0" -description = "The little ASGI library that shines." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -anyio = ">=3.4.0,<5" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] - -[[package]] -name = "timeout-decorator" -version = "0.5.0" -description = "Timeout decorator" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "tornado" -version = "6.2" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "dev" -optional = false -python-versions = ">= 3.7" - -[[package]] -name = "typed-ast" -version = "1.5.4" -description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "types-croniter" -version = "1.3.2.1" -description = "Typing stubs for croniter" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "types-setuptools" -version = "65.6.0.2" -description = "Typing stubs for setuptools" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "typing-extensions" -version = "4.4.0" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "urllib3" -version = "1.26.13" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "uvloop" -version = "0.17.0" -description = "Fast implementation of asyncio event loop on top of libuv" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)", "pytest (>=3.6.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] - -[[package]] -name = "virtualenv" -version = "20.17.1" -description = "Virtual Python Environment builder" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.4.1,<4" -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.8\""} -platformdirs = ">=2.4,<3" - -[package.extras] -docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] -testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] - -[[package]] -name = "waitress" -version = "2.1.2" -description = "Waitress WSGI server" -category = "dev" -optional = false -python-versions = ">=3.7.0" - -[package.extras] -docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] -testing = ["coverage (>=5.0)", "pytest", "pytest-cover"] - -[[package]] -name = "webob" -version = "1.8.7" -description = "WSGI request and response object" -category = "dev" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" - -[package.extras] -docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] -testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "webtest" -version = "3.0.0" -description = "Helper to test WSGI applications" -category = "dev" -optional = false -python-versions = ">=3.6, <4" - -[package.dependencies] -beautifulsoup4 = "*" -waitress = ">=0.8.5" -WebOb = ">=1.2" - -[package.extras] -docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.8)"] -tests = ["PasteDeploy", "WSGIProxy2", "coverage", "pyquery", "pytest", "pytest-cov"] - -[[package]] -name = "yarl" -version = "1.8.2" -description = "Yet another URL library" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -idna = ">=2.0" -multidict = ">=4.0" -typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} - -[[package]] -name = "zipp" -version = "3.11.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - -[extras] -aiohttp = [] -asgi = [] -carbon = [] -cron = [] -raven = [] -rich = [] -uvloop = [] - -[metadata] -lock-version = "1.1" -python-versions = "^3.7" -content-hash = "66f7693da6c5fadd973d50b2d381906ff979d1781e560713d7d27819dce04333" - -[metadata.files] -aiocontextvars = [ - {file = "aiocontextvars-0.2.2-py2.py3-none-any.whl", hash = "sha256:885daf8261818767d8f7cbd79f9d4482d118f024b6586ef6e67980236a27bfa3"}, - {file = "aiocontextvars-0.2.2.tar.gz", hash = "sha256:f027372dc48641f683c559f247bd84962becaacdc9ba711d583c3871fb5652aa"}, -] -aiohttp = [ - {file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ba71c9b4dcbb16212f334126cc3d8beb6af377f6703d9dc2d9fb3874fd667ee9"}, - {file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d24b8bb40d5c61ef2d9b6a8f4528c2f17f1c5d2d31fed62ec860f6006142e83e"}, - {file = "aiohttp-3.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f88df3a83cf9df566f171adba39d5bd52814ac0b94778d2448652fc77f9eb491"}, - {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97decbb3372d4b69e4d4c8117f44632551c692bb1361b356a02b97b69e18a62"}, - {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:309aa21c1d54b8ef0723181d430347d7452daaff93e8e2363db8e75c72c2fb2d"}, - {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad5383a67514e8e76906a06741febd9126fc7c7ff0f599d6fcce3e82b80d026f"}, - {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20acae4f268317bb975671e375493dbdbc67cddb5f6c71eebdb85b34444ac46b"}, - {file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05a3c31c6d7cd08c149e50dc7aa2568317f5844acd745621983380597f027a18"}, - {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d6f76310355e9fae637c3162936e9504b4767d5c52ca268331e2756e54fd4ca5"}, - {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:256deb4b29fe5e47893fa32e1de2d73c3afe7407738bd3c63829874661d4822d"}, - {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5c59fcd80b9049b49acd29bd3598cada4afc8d8d69bd4160cd613246912535d7"}, - {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:059a91e88f2c00fe40aed9031b3606c3f311414f86a90d696dd982e7aec48142"}, - {file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2feebbb6074cdbd1ac276dbd737b40e890a1361b3cc30b74ac2f5e24aab41f7b"}, - {file = "aiohttp-3.8.3-cp310-cp310-win32.whl", hash = "sha256:5bf651afd22d5f0c4be16cf39d0482ea494f5c88f03e75e5fef3a85177fecdeb"}, - {file = "aiohttp-3.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:653acc3880459f82a65e27bd6526e47ddf19e643457d36a2250b85b41a564715"}, - {file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:86fc24e58ecb32aee09f864cb11bb91bc4c1086615001647dbfc4dc8c32f4008"}, - {file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75e14eac916f024305db517e00a9252714fce0abcb10ad327fb6dcdc0d060f1d"}, - {file = "aiohttp-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d1fde0f44029e02d02d3993ad55ce93ead9bb9b15c6b7ccd580f90bd7e3de476"}, - {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab94426ddb1ecc6a0b601d832d5d9d421820989b8caa929114811369673235c"}, - {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89d2e02167fa95172c017732ed7725bc8523c598757f08d13c5acca308e1a061"}, - {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02f9a2c72fc95d59b881cf38a4b2be9381b9527f9d328771e90f72ac76f31ad8"}, - {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7149272fb5834fc186328e2c1fa01dda3e1fa940ce18fded6d412e8f2cf76d"}, - {file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:512bd5ab136b8dc0ffe3fdf2dfb0c4b4f49c8577f6cae55dca862cd37a4564e2"}, - {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7018ecc5fe97027214556afbc7c502fbd718d0740e87eb1217b17efd05b3d276"}, - {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88c70ed9da9963d5496d38320160e8eb7e5f1886f9290475a881db12f351ab5d"}, - {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:da22885266bbfb3f78218dc40205fed2671909fbd0720aedba39b4515c038091"}, - {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:e65bc19919c910127c06759a63747ebe14f386cda573d95bcc62b427ca1afc73"}, - {file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:08c78317e950e0762c2983f4dd58dc5e6c9ff75c8a0efeae299d363d439c8e34"}, - {file = "aiohttp-3.8.3-cp311-cp311-win32.whl", hash = "sha256:45d88b016c849d74ebc6f2b6e8bc17cabf26e7e40c0661ddd8fae4c00f015697"}, - {file = "aiohttp-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:96372fc29471646b9b106ee918c8eeb4cca423fcbf9a34daa1b93767a88a2290"}, - {file = "aiohttp-3.8.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c971bf3786b5fad82ce5ad570dc6ee420f5b12527157929e830f51c55dc8af77"}, - {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff25f48fc8e623d95eca0670b8cc1469a83783c924a602e0fbd47363bb54aaca"}, - {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e381581b37db1db7597b62a2e6b8b57c3deec95d93b6d6407c5b61ddc98aca6d"}, - {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db19d60d846283ee275d0416e2a23493f4e6b6028825b51290ac05afc87a6f97"}, - {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25892c92bee6d9449ffac82c2fe257f3a6f297792cdb18ad784737d61e7a9a85"}, - {file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:398701865e7a9565d49189f6c90868efaca21be65c725fc87fc305906be915da"}, - {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4a4fbc769ea9b6bd97f4ad0b430a6807f92f0e5eb020f1e42ece59f3ecfc4585"}, - {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:b29bfd650ed8e148f9c515474a6ef0ba1090b7a8faeee26b74a8ff3b33617502"}, - {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:1e56b9cafcd6531bab5d9b2e890bb4937f4165109fe98e2b98ef0dcfcb06ee9d"}, - {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ec40170327d4a404b0d91855d41bfe1fe4b699222b2b93e3d833a27330a87a6d"}, - {file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2df5f139233060578d8c2c975128fb231a89ca0a462b35d4b5fcf7c501ebdbe1"}, - {file = "aiohttp-3.8.3-cp36-cp36m-win32.whl", hash = "sha256:f973157ffeab5459eefe7b97a804987876dd0a55570b8fa56b4e1954bf11329b"}, - {file = "aiohttp-3.8.3-cp36-cp36m-win_amd64.whl", hash = "sha256:437399385f2abcd634865705bdc180c8314124b98299d54fe1d4c8990f2f9494"}, - {file = "aiohttp-3.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:09e28f572b21642128ef31f4e8372adb6888846f32fecb288c8b0457597ba61a"}, - {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f3553510abdbec67c043ca85727396ceed1272eef029b050677046d3387be8d"}, - {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e168a7560b7c61342ae0412997b069753f27ac4862ec7867eff74f0fe4ea2ad9"}, - {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db4c979b0b3e0fa7e9e69ecd11b2b3174c6963cebadeecfb7ad24532ffcdd11a"}, - {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e164e0a98e92d06da343d17d4e9c4da4654f4a4588a20d6c73548a29f176abe2"}, - {file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a78079d9a39ca9ca99a8b0ac2fdc0c4d25fc80c8a8a82e5c8211509c523363"}, - {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:21b30885a63c3f4ff5b77a5d6caf008b037cb521a5f33eab445dc566f6d092cc"}, - {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4b0f30372cef3fdc262f33d06e7b411cd59058ce9174ef159ad938c4a34a89da"}, - {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:8135fa153a20d82ffb64f70a1b5c2738684afa197839b34cc3e3c72fa88d302c"}, - {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ad61a9639792fd790523ba072c0555cd6be5a0baf03a49a5dd8cfcf20d56df48"}, - {file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978b046ca728073070e9abc074b6299ebf3501e8dee5e26efacb13cec2b2dea0"}, - {file = "aiohttp-3.8.3-cp37-cp37m-win32.whl", hash = "sha256:0d2c6d8c6872df4a6ec37d2ede71eff62395b9e337b4e18efd2177de883a5033"}, - {file = "aiohttp-3.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:21d69797eb951f155026651f7e9362877334508d39c2fc37bd04ff55b2007091"}, - {file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ca9af5f8f5812d475c5259393f52d712f6d5f0d7fdad9acdb1107dd9e3cb7eb"}, - {file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d90043c1882067f1bd26196d5d2db9aa6d268def3293ed5fb317e13c9413ea4"}, - {file = "aiohttp-3.8.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d737fc67b9a970f3234754974531dc9afeea11c70791dcb7db53b0cf81b79784"}, - {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebf909ea0a3fc9596e40d55d8000702a85e27fd578ff41a5500f68f20fd32e6c"}, - {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5835f258ca9f7c455493a57ee707b76d2d9634d84d5d7f62e77be984ea80b849"}, - {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da37dcfbf4b7f45d80ee386a5f81122501ec75672f475da34784196690762f4b"}, - {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f44875f2804bc0511a69ce44a9595d5944837a62caecc8490bbdb0e18b1342"}, - {file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:527b3b87b24844ea7865284aabfab08eb0faf599b385b03c2aa91fc6edd6e4b6"}, - {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5ba88df9aa5e2f806650fcbeedbe4f6e8736e92fc0e73b0400538fd25a4dd96"}, - {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e7b8813be97cab8cb52b1375f41f8e6804f6507fe4660152e8ca5c48f0436017"}, - {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2dea10edfa1a54098703cb7acaa665c07b4e7568472a47f4e64e6319d3821ccf"}, - {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:713d22cd9643ba9025d33c4af43943c7a1eb8547729228de18d3e02e278472b6"}, - {file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2d252771fc85e0cf8da0b823157962d70639e63cb9b578b1dec9868dd1f4f937"}, - {file = "aiohttp-3.8.3-cp38-cp38-win32.whl", hash = "sha256:66bd5f950344fb2b3dbdd421aaa4e84f4411a1a13fca3aeb2bcbe667f80c9f76"}, - {file = "aiohttp-3.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:84b14f36e85295fe69c6b9789b51a0903b774046d5f7df538176516c3e422446"}, - {file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16c121ba0b1ec2b44b73e3a8a171c4f999b33929cd2397124a8c7fcfc8cd9e06"}, - {file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8d6aaa4e7155afaf994d7924eb290abbe81a6905b303d8cb61310a2aba1c68ba"}, - {file = "aiohttp-3.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43046a319664a04b146f81b40e1545d4c8ac7b7dd04c47e40bf09f65f2437346"}, - {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599418aaaf88a6d02a8c515e656f6faf3d10618d3dd95866eb4436520096c84b"}, - {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a2964319d359f494f16011e23434f6f8ef0434acd3cf154a6b7bec511e2fb7"}, - {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73a4131962e6d91109bca6536416aa067cf6c4efb871975df734f8d2fd821b37"}, - {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598adde339d2cf7d67beaccda3f2ce7c57b3b412702f29c946708f69cf8222aa"}, - {file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75880ed07be39beff1881d81e4a907cafb802f306efd6d2d15f2b3c69935f6fb"}, - {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0239da9fbafd9ff82fd67c16704a7d1bccf0d107a300e790587ad05547681c8"}, - {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4e3a23ec214e95c9fe85a58470b660efe6534b83e6cbe38b3ed52b053d7cb6ad"}, - {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:47841407cc89a4b80b0c52276f3cc8138bbbfba4b179ee3acbd7d77ae33f7ac4"}, - {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:54d107c89a3ebcd13228278d68f1436d3f33f2dd2af5415e3feaeb1156e1a62c"}, - {file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c37c5cce780349d4d51739ae682dec63573847a2a8dcb44381b174c3d9c8d403"}, - {file = "aiohttp-3.8.3-cp39-cp39-win32.whl", hash = "sha256:f178d2aadf0166be4df834c4953da2d7eef24719e8aec9a65289483eeea9d618"}, - {file = "aiohttp-3.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:88e5be56c231981428f4f506c68b6a46fa25c4123a2e86d156c58a8369d31ab7"}, - {file = "aiohttp-3.8.3.tar.gz", hash = "sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269"}, -] -aiohttp-asgi = [ - {file = "aiohttp-asgi-0.4.3.tar.gz", hash = "sha256:2b211ed97ad174bdfcf2419465386e2af83ad4cf25bb06a463ad49e8e038e185"}, - {file = "aiohttp_asgi-0.4.3-py3-none-any.whl", hash = "sha256:1a77540f4758a6c8736797abd553e80e29a8cade6c864808d483e98e35a78724"}, -] -aiosignal = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, -] -alabaster = [ - {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, - {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, -] -anyio = [ - {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, - {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, -] -async-timeout = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, -] -asynctest = [ - {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, - {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, -] -attrs = [ - {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, - {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, -] -autodoc = [ - {file = "autodoc-0.5.0.tar.gz", hash = "sha256:c4387c5a0f1c09b055bb2e384542ee1e016542f313b2a33d904ca77f0460ded3"}, -] -autoflake = [ - {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, -] -babel = [ - {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, - {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, -] -beautifulsoup4 = [ - {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, - {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, -] -certifi = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, -] -cfgv = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, - {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, -] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] -collective-checkdocs = [ - {file = "collective.checkdocs-0.2.zip", hash = "sha256:3a5328257c5224bc72753820c182910d7fb336bc1dba5e09113d48566655e46e"}, -] -colorama = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -colorlog = [ - {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, - {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, -] -commonmark = [ - {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, - {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, -] -coverage = [ - {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, - {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, - {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, - {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, - {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, - {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, - {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, - {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, - {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, - {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, - {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, - {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, - {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, - {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, - {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, - {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, - {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, - {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, - {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, - {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, -] -coveralls = [ - {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"}, - {file = "coveralls-3.3.1.tar.gz", hash = "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea"}, -] -croniter = [ - {file = "croniter-1.3.8-py2.py3-none-any.whl", hash = "sha256:d6ed8386d5f4bbb29419dc1b65c4909c04a2322bd15ec0dc5b2877bfa1b75c7a"}, - {file = "croniter-1.3.8.tar.gz", hash = "sha256:32a5ec04e97ec0837bcdf013767abd2e71cceeefd3c2e14c804098ce51ad6cd9"}, -] -decorator = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] -distlib = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, -] -docopt = [ - {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, -] -docutils = [ - {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, - {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, -] -exceptiongroup = [ - {file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"}, - {file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"}, -] -fastapi = [ - {file = "fastapi-0.88.0-py3-none-any.whl", hash = "sha256:263b718bb384422fe3d042ffc9a0c8dece5e034ab6586ff034f6b4b1667c3eee"}, - {file = "fastapi-0.88.0.tar.gz", hash = "sha256:915bf304180a0e7c5605ec81097b7d4cd8826ff87a02bb198e336fb9f3b5ff02"}, -] -filelock = [ - {file = "filelock-3.8.2-py3-none-any.whl", hash = "sha256:8df285554452285f79c035efb0c861eb33a4bcfa5b7a137016e32e6a90f9792c"}, - {file = "filelock-3.8.2.tar.gz", hash = "sha256:7565f628ea56bfcd8e54e42bdc55da899c85c1abfe1b5bcfd147e9188cebb3b2"}, -] -freezegun = [ - {file = "freezegun-1.0.0-py2.py3-none-any.whl", hash = "sha256:02b35de52f4699a78f6ac4518e4cd3390dddc43b0aeb978335a8f270a2d9668b"}, - {file = "freezegun-1.0.0.tar.gz", hash = "sha256:1cf08e441f913ff5e59b19cc065a8faa9dd1ddc442eaf0375294f344581a0643"}, -] -frozenlist = [ - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, - {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, - {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, - {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, - {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, - {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, - {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, - {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, - {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, - {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, - {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, -] -furo = [ - {file = "furo-2022.12.7-py3-none-any.whl", hash = "sha256:7cb76c12a25ef65db85ab0743df907573d03027a33631f17d267e598ebb191f7"}, - {file = "furo-2022.12.7.tar.gz", hash = "sha256:d8008f8efbe7587a97ba533c8b2df1f9c21ee9b3e5cad0d27f61193d38b1a986"}, -] -identify = [ - {file = "identify-2.5.11-py2.py3-none-any.whl", hash = "sha256:e7db36b772b188099616aaf2accbee122949d1c6a1bac4f38196720d6f9f06db"}, - {file = "identify-2.5.11.tar.gz", hash = "sha256:14b7076b29c99b1b0b8b08e96d448c7b877a9b07683cd8cfda2ea06af85ffa1c"}, -] -idna = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] -imagesize = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] -importlib-metadata = [ - {file = "importlib_metadata-5.2.0-py3-none-any.whl", hash = "sha256:0eafa39ba42bf225fc00e67f701d71f85aead9f878569caf13c3724f704b970f"}, - {file = "importlib_metadata-5.2.0.tar.gz", hash = "sha256:404d48d62bba0b7a77ff9d405efd91501bef2e67ff4ace0bed40a0cf28c3c7cd"}, -] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -jinja2 = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, -] -livereload = [ - {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, -] -logging-journald = [ - {file = "logging_journald-0.6.4-py3-none-any.whl", hash = "sha256:4d4e169cf2814ddbc30687daef2ce38a58a0ec9cd7d739f21f0fb745c4a70ee9"}, - {file = "logging_journald-0.6.4.tar.gz", hash = "sha256:a03aa0a1b85ab5f3cdc534511d98ff55f58479e44fbf4e9eb5b965923cbb0c27"}, -] -markupsafe = [ +files = [ {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, @@ -1647,11 +1301,101 @@ markupsafe = [ {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] -mccabe = [ + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] -multidict = [ + +[[package]] +name = "more-itertools" +version = "9.0.0" +description = "More routines for operating on iterables, beyond itertools" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "more-itertools-9.0.0.tar.gz", hash = "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab"}, + {file = "more_itertools-9.0.0-py3-none-any.whl", hash = "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41"}, +] + +[[package]] +name = "msgpack" +version = "1.0.4" +description = "MessagePack serializer" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250"}, + {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88"}, + {file = "msgpack-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467"}, + {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6"}, + {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa"}, + {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6"}, + {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba"}, + {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e"}, + {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db"}, + {file = "msgpack-1.0.4-cp310-cp310-win32.whl", hash = "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef"}, + {file = "msgpack-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075"}, + {file = "msgpack-1.0.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52"}, + {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9"}, + {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9"}, + {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08"}, + {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8"}, + {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6"}, + {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae"}, + {file = "msgpack-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6"}, + {file = "msgpack-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661"}, + {file = "msgpack-1.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c"}, + {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0"}, + {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227"}, + {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff"}, + {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd"}, + {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e"}, + {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236"}, + {file = "msgpack-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44"}, + {file = "msgpack-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1"}, + {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d"}, + {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab"}, + {file = "msgpack-1.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb"}, + {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9"}, + {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e"}, + {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1"}, + {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e"}, + {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43"}, + {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243"}, + {file = "msgpack-1.0.4-cp38-cp38-win32.whl", hash = "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2"}, + {file = "msgpack-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6"}, + {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae"}, + {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55"}, + {file = "msgpack-1.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da"}, + {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f"}, + {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92"}, + {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f"}, + {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624"}, + {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8"}, + {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae"}, + {file = "msgpack-1.0.4-cp39-cp39-win32.whl", hash = "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c"}, + {file = "msgpack-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce"}, + {file = "msgpack-1.0.4.tar.gz", hash = "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f"}, +] + +[[package]] +name = "multidict" +version = "6.0.3" +description = "multidict implementation" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "multidict-6.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:73009ea04205966d47e16d98686ac5c438af23a1bb30b48a2c5da3423ec9ce37"}, {file = "multidict-6.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b92a9f3ab904397a33b193000dc4de7318ea175c4c460a1e154c415f9008e3d"}, {file = "multidict-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:578bfcb16f4b8675ef71b960c00f174b0426e0eeb796bab6737389d8288eb827"}, @@ -1727,7 +1471,15 @@ multidict = [ {file = "multidict-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:5e58ec0375803526d395f6f7e730ecc45d06e15f68f7b9cdbf644a2918324e51"}, {file = "multidict-6.0.3.tar.gz", hash = "sha256:2523a29006c034687eccd3ee70093a697129a3ffe8732535d3b2df6a4ecc279d"}, ] -mypy = [ + +[[package]] +name = "mypy" +version = "0.991" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "mypy-0.991-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7d17e0a9707d0772f4a7b878f04b4fd11f6f5bcb9b3813975a9b13c9332153ab"}, {file = "mypy-0.991-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0714258640194d75677e86c786e80ccf294972cc76885d3ebbb560f11db0003d"}, {file = "mypy-0.991-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c8f3be99e8a8bd403caa8c03be619544bc2c77a7093685dcf308c6b109426c6"}, @@ -1759,39 +1511,286 @@ mypy = [ {file = "mypy-0.991-py3-none-any.whl", hash = "sha256:de32edc9b0a7e67c2775e574cb061a537660e51210fbf6006b0b36ea695ae9bb"}, {file = "mypy-0.991.tar.gz", hash = "sha256:3c0165ba8f354a6d9881809ef29f1a9318a236a6d81c690094c5df32107bde06"}, ] -mypy-extensions = [ + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] -nodeenv = [ + +[[package]] +name = "nodeenv" +version = "1.7.0" +description = "Node.js virtual environment builder" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, ] -packaging = [ + +[package.dependencies] +setuptools = "*" + +[[package]] +name = "packaging" +version = "22.0" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ {file = "packaging-22.0-py3-none-any.whl", hash = "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3"}, {file = "packaging-22.0.tar.gz", hash = "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3"}, ] -platformdirs = [ + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pkginfo" +version = "1.9.2" +description = "Query metadatdata from sdists / bdists / installed packages." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkginfo-1.9.2-py3-none-any.whl", hash = "sha256:d580059503f2f4549ad6e4c106d7437356dbd430e2c7df99ee1efe03d75f691e"}, + {file = "pkginfo-1.9.2.tar.gz", hash = "sha256:ac03e37e4d601aaee40f8087f63fc4a2a6c9814dda2c8fa6aab1b1829653bdfa"}, +] + +[package.extras] +testing = ["pytest", "pytest-cov"] + +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] + +[[package]] +name = "platformdirs" +version = "2.6.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ {file = "platformdirs-2.6.0-py3-none-any.whl", hash = "sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca"}, {file = "platformdirs-2.6.0.tar.gz", hash = "sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e"}, ] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + +[package.extras] +docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] +test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] + +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "poetry" +version = "1.3.1" +description = "Python dependency management and packaging made easy." +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "poetry-1.3.1-py3-none-any.whl", hash = "sha256:e8c24984af3e124ef31a5891c1c11871c948687368ee451e95f7f101ffbf8204"}, + {file = "poetry-1.3.1.tar.gz", hash = "sha256:fde98462ad5dc9879393157da93092206a3411117e25a4761a41c6d08f31aea8"}, +] + +[package.dependencies] +"backports.cached-property" = {version = ">=1.0.2,<2.0.0", markers = "python_version < \"3.8\""} +cachecontrol = {version = ">=0.12.9,<0.13.0", extras = ["filecache"]} +cleo = ">=2.0.0,<3.0.0" +crashtest = ">=0.4.1,<0.5.0" +dulwich = ">=0.20.46,<0.21.0" +filelock = ">=3.8.0,<4.0.0" +html5lib = ">=1.0,<2.0" +importlib-metadata = {version = ">=4.4,<5.0", markers = "python_version < \"3.10\""} +jsonschema = ">=4.10.0,<5.0.0" +keyring = ">=23.9.0,<24.0.0" +lockfile = ">=0.12.2,<0.13.0" +packaging = ">=20.4" +pexpect = ">=4.7.0,<5.0.0" +pkginfo = ">=1.5,<2.0" +platformdirs = ">=2.5.2,<3.0.0" +poetry-core = "1.4.0" +poetry-plugin-export = ">=1.2.0,<2.0.0" +requests = ">=2.18,<3.0" +requests-toolbelt = ">=0.9.1,<0.11.0" +shellingham = ">=1.5,<2.0" +tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.11.1,<0.11.2 || >0.11.2,<0.11.3 || >0.11.3,<1.0.0" +trove-classifiers = ">=2022.5.19" +urllib3 = ">=1.26.0,<2.0.0" +virtualenv = [ + {version = ">=20.4.3,<20.4.5 || >20.4.5,<20.4.6 || >20.4.6,<21.0.0", markers = "sys_platform != \"win32\" or python_version != \"3.9\""}, + {version = ">=20.4.3,<20.4.5 || >20.4.5,<20.4.6 || >20.4.6,<20.16.6", markers = "sys_platform == \"win32\" and python_version == \"3.9\""}, +] +xattr = {version = ">=0.10.0,<0.11.0", markers = "sys_platform == \"darwin\""} + +[[package]] +name = "poetry-core" +version = "1.4.0" +description = "Poetry PEP 517 Build Backend" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "poetry_core-1.4.0-py3-none-any.whl", hash = "sha256:5559ab80384ac021db329ef317086417e140ee1176bcfcb3a3838b544e213c8e"}, + {file = "poetry_core-1.4.0.tar.gz", hash = "sha256:514bd33c30e0bf56b0ed44ee15e120d7e47b61ad908b2b1011da68c48a84ada9"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} + +[[package]] +name = "poetry-plugin-export" +version = "1.2.0" +description = "Poetry plugin to export the dependencies to various formats" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "poetry_plugin_export-1.2.0-py3-none-any.whl", hash = "sha256:109fb43ebfd0e79d8be2e7f9d43ba2ae357c4975a18dfc0cfdd9597dd086790e"}, + {file = "poetry_plugin_export-1.2.0.tar.gz", hash = "sha256:9a1dd42765408931d7831738749022651d43a2968b67c988db1b7a567dfe41ef"}, ] -pre-commit = [ + +[package.dependencies] +poetry = ">=1.2.2,<2.0.0" +poetry-core = ">=1.3.0,<2.0.0" + +[[package]] +name = "pre-commit" +version = "2.20.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "pre_commit-2.20.0-py2.py3-none-any.whl", hash = "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7"}, {file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"}, ] -py = [ + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +toml = "*" +virtualenv = ">=20.0.8" + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] -pycodestyle = [ + +[[package]] +name = "pycodestyle" +version = "2.10.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, ] -pydantic = [ + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + +[[package]] +name = "pydantic" +version = "1.10.2" +description = "Data validation and settings management using python type hints" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"}, {file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"}, {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"}, @@ -1829,50 +1828,263 @@ pydantic = [ {file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"}, {file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"}, ] -pydocstyle = [ + +[package.dependencies] +typing-extensions = ">=4.1.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pydocstyle" +version = "6.1.1" +description = "Python docstring style checker" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, ] -pyflakes = [ + +[package.dependencies] +snowballstemmer = "*" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "pyflakes" +version = "3.0.1" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, ] -pygments = [ + +[[package]] +name = "pygments" +version = "2.13.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, ] -pylama = [ + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pylama" +version = "8.4.1" +description = "Code audit tool for python" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "pylama-8.4.1-py3-none-any.whl", hash = "sha256:5bbdbf5b620aba7206d688ed9fc917ecd3d73e15ec1a89647037a09fa3a86e60"}, {file = "pylama-8.4.1.tar.gz", hash = "sha256:2d4f7aecfb5b7466216d48610c7d6bad1c3990c29cdd392ad08259b161e486f6"}, ] -pytest = [ + +[package.dependencies] +mccabe = ">=0.7.0" +pycodestyle = ">=2.9.1" +pydocstyle = ">=6.1.1" +pyflakes = ">=2.5.0" + +[package.extras] +all = ["eradicate", "mypy", "pylint", "radon", "vulture"] +eradicate = ["eradicate"] +mypy = ["mypy"] +pylint = ["pylint"] +radon = ["radon"] +tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "pytest (>=7.1.2)", "pytest-mypy", "radon (>=5.1.0)", "toml", "types-setuptools", "types-toml", "vulture"] +toml = ["toml (>=0.10.2)"] +vulture = ["vulture"] + +[[package]] +name = "pyrsistent" +version = "0.19.3" +description = "Persistent/Functional/Immutable data structures" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, + {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, + {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, + {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, + {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, + {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, +] + +[[package]] +name = "pytest" +version = "7.2.0" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, ] -pytest-cov = [ + +[package.dependencies] +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.0.0" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, ] -pytest-freezegun = [ + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pytest-freezegun" +version = "0.4.2" +description = "Wrap tests with fixtures in freeze_time" +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "pytest-freezegun-0.4.2.zip", hash = "sha256:19c82d5633751bf3ec92caa481fb5cffaac1787bd485f0df6436fd6242176949"}, {file = "pytest_freezegun-0.4.2-py2.py3-none-any.whl", hash = "sha256:5318a6bfb8ba4b709c8471c94d0033113877b3ee02da5bfcd917c1889cde99a7"}, ] -pytest-rst = [ + +[package.dependencies] +freezegun = ">0.3" +pytest = ">=3.0.0" + +[[package]] +name = "pytest-rst" +version = "0.0.7" +description = "Test code from RST documents with pytest" +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "pytest-rst-0.0.7.tar.gz", hash = "sha256:2b34aa9d41ce8dce3e685e6f40dff432804962ffec49d3d37565f2dbad4014d5"}, ] -pytest-subtests = [ + +[package.dependencies] +docutils = "*" +py = "*" +pygments = "*" +pytest = "*" + +[[package]] +name = "pytest-subtests" +version = "0.9.0" +description = "unittest subTest() support and subtests fixture" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "pytest-subtests-0.9.0.tar.gz", hash = "sha256:c0317cd5f6a5eb3e957e89dbe4fc3322a9afddba2db8414355ed2a2cb91a844e"}, {file = "pytest_subtests-0.9.0-py3-none-any.whl", hash = "sha256:f5f616b92c13405909d210569d6d3914db6fe156333ff5426534f97d5b447861"}, ] -python-dateutil = [ + +[package.dependencies] +pytest = ">=7.0" + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] -pytz = [ + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2022.7" +description = "World timezone definitions, modern and historical" +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "pytz-2022.7-py2.py3-none-any.whl", hash = "sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd"}, {file = "pytz-2022.7.tar.gz", hash = "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a"}, ] -pyyaml = [ + +[[package]] +name = "pywin32-ctypes" +version = "0.2.0" +description = "" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, + {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, +] + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, @@ -1914,19 +2126,206 @@ pyyaml = [ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] -raven = [ + +[[package]] +name = "rapidfuzz" +version = "2.13.7" +description = "rapid fuzzy string matching" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b75dd0928ce8e216f88660ab3d5c5ffe990f4dd682fd1709dba29d5dafdde6de"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24d3fea10680d085fd0a4d76e581bfb2b1074e66e78fd5964d4559e1fcd2a2d4"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8109e0324d21993d5b2d111742bf5958f3516bf8c59f297c5d1cc25a2342eb66"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f705652360d520c2de52bee11100c92f59b3e3daca308ebb150cbc58aecdad"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7496e8779905b02abc0ab4ba2a848e802ab99a6e20756ffc967a0de4900bd3da"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24eb6b843492bdc63c79ee4b2f104059b7a2201fef17f25177f585d3be03405a"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:467c1505362823a5af12b10234cb1c4771ccf124c00e3fc9a43696512bd52293"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53dcae85956853b787c27c1cb06f18bb450e22cf57a4ad3444cf03b8ff31724a"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46b9b8aa09998bc48dd800854e8d9b74bc534d7922c1d6e1bbf783e7fa6ac29c"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1fbad8fb28d98980f5bff33c7842efef0315d42f0cd59082108482a7e6b61410"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:43fb8cb030f888c3f076d40d428ed5eb4331f5dd6cf1796cfa39c67bf0f0fc1e"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b6bad92de071cbffa2acd4239c1779f66851b60ffbbda0e4f4e8a2e9b17e7eef"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d00df2e4a81ffa56a6b1ec4d2bc29afdcb7f565e0b8cd3092fece2290c4c7a79"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-win32.whl", hash = "sha256:2c836f0f2d33d4614c3fbaf9a1eb5407c0fe23f8876f47fd15b90f78daa64c34"}, + {file = "rapidfuzz-2.13.7-cp310-cp310-win_amd64.whl", hash = "sha256:c36fd260084bb636b9400bb92016c6bd81fd80e59ed47f2466f85eda1fc9f782"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b34e8c0e492949ecdd5da46a1cfc856a342e2f0389b379b1a45a3cdcd3176a6e"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:875d51b3497439a72e2d76183e1cb5468f3f979ab2ddfc1d1f7dde3b1ecfb42f"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae33a72336059213996fe4baca4e0e4860913905c2efb7c991eab33b95a98a0a"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5585189b3d90d81ccd62d4f18530d5ac8972021f0aaaa1ffc6af387ff1dce75"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42085d4b154a8232767de8296ac39c8af5bccee6b823b0507de35f51c9cbc2d7"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:585206112c294e335d84de5d5f179c0f932837752d7420e3de21db7fdc476278"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f891b98f8bc6c9d521785816085e9657212621e93f223917fb8e32f318b2957e"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08590905a95ccfa43f4df353dcc5d28c15d70664299c64abcad8721d89adce4f"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b5dd713a1734574c2850c566ac4286594bacbc2d60b9170b795bee4b68656625"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:988f8f6abfba7ee79449f8b50687c174733b079521c3cc121d65ad2d38831846"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b3210869161a864f3831635bb13d24f4708c0aa7208ef5baac1ac4d46e9b4208"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f6fe570e20e293eb50491ae14ddeef71a6a7e5f59d7e791393ffa99b13f1f8c2"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6120f2995f5154057454c5de99d86b4ef3b38397899b5da1265467e8980b2f60"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-win32.whl", hash = "sha256:b20141fa6cee041917801de0bab503447196d372d4c7ee9a03721b0a8edf5337"}, + {file = "rapidfuzz-2.13.7-cp311-cp311-win_amd64.whl", hash = "sha256:ec55a81ac2b0f41b8d6fb29aad16e55417036c7563bad5568686931aa4ff08f7"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d005e058d86f2a968a8d28ca6f2052fab1f124a39035aa0523261d6baf21e1f"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe59a0c21a032024edb0c8e43f5dee5623fef0b65a1e3c1281836d9ce199af3b"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfc04f7647c29fb48da7a04082c34cdb16f878d3c6d098d62d5715c0ad3000c"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68a89bb06d5a331511961f4d3fa7606f8e21237467ba9997cae6f67a1c2c2b9e"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:effe182767d102cb65dfbbf74192237dbd22d4191928d59415aa7d7c861d8c88"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25b4cedf2aa19fb7212894ce5f5219010cce611b60350e9a0a4d492122e7b351"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3a9bd02e1679c0fd2ecf69b72d0652dbe2a9844eaf04a36ddf4adfbd70010e95"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5e2b3d020219baa75f82a4e24b7c8adcb598c62f0e54e763c39361a9e5bad510"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:cf62dacb3f9234f3fddd74e178e6d25c68f2067fde765f1d95f87b1381248f58"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:fa263135b892686e11d5b84f6a1892523123a00b7e5882eff4fbdabb38667347"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa4c598ed77f74ec973247ca776341200b0f93ec3883e34c222907ce72cb92a4"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-win32.whl", hash = "sha256:c2523f8180ebd9796c18d809e9a19075a1060b1a170fde3799e83db940c1b6d5"}, + {file = "rapidfuzz-2.13.7-cp37-cp37m-win_amd64.whl", hash = "sha256:5ada0a14c67452358c1ee52ad14b80517a87b944897aaec3e875279371a9cb96"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ca8a23097c1f50e0fdb4de9e427537ca122a18df2eead06ed39c3a0bef6d9d3a"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9be02162af0376d64b840f2fc8ee3366794fc149f1e06d095a6a1d42447d97c5"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af4f7c3c904ca709493eb66ca9080b44190c38e9ecb3b48b96d38825d5672559"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f50d1227e6e2a0e3ae1fb1c9a2e1c59577d3051af72c7cab2bcc430cb5e18da"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c71d9d512b76f05fa00282227c2ae884abb60e09f08b5ca3132b7e7431ac7f0d"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b52ac2626945cd21a2487aeefed794c14ee31514c8ae69b7599170418211e6f6"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca00fafd2756bc9649bf80f1cf72c647dce38635f0695d7ce804bc0f759aa756"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d248a109699ce9992304e79c1f8735c82cc4c1386cd8e27027329c0549f248a2"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c88adbcb933f6b8612f6c593384bf824e562bb35fc8a0f55fac690ab5b3486e5"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8601a66fbfc0052bb7860d2eacd303fcde3c14e87fdde409eceff516d659e77"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:27be9c63215d302ede7d654142a2e21f0d34ea6acba512a4ae4cfd52bbaa5b59"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3dcffe1f3cbda0dc32133a2ae2255526561ca594f15f9644384549037b355245"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8450d15f7765482e86ef9be2ad1a05683cd826f59ad236ef7b9fb606464a56aa"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-win32.whl", hash = "sha256:460853983ab88f873173e27cc601c5276d469388e6ad6e08c4fd57b2a86f1064"}, + {file = "rapidfuzz-2.13.7-cp38-cp38-win_amd64.whl", hash = "sha256:424f82c35dbe4f83bdc3b490d7d696a1dc6423b3d911460f5493b7ffae999fd2"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c3fbe449d869ea4d0909fc9d862007fb39a584fb0b73349a6aab336f0d90eaed"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16080c05a63d6042643ae9b6cfec1aefd3e61cef53d0abe0df3069b9d4b72077"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dbcf5371ea704759fcce772c66a07647751d1f5dbdec7818331c9b31ae996c77"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:114810491efb25464016fd554fdf1e20d390309cecef62587494fc474d4b926f"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99a84ab9ac9a823e7e93b4414f86344052a5f3e23b23aa365cda01393ad895bd"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81642a24798851b118f82884205fc1bd9ff70b655c04018c467824b6ecc1fabc"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3741cb0bf9794783028e8b0cf23dab917fa5e37a6093b94c4c2f805f8e36b9f"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:759a3361711586a29bc753d3d1bdb862983bd9b9f37fbd7f6216c24f7c972554"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1333fb3d603d6b1040e365dca4892ba72c7e896df77a54eae27dc07db90906e3"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:916bc2e6cf492c77ad6deb7bcd088f0ce9c607aaeabc543edeb703e1fbc43e31"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:23524635840500ce6f4d25005c9529a97621689c85d2f727c52eed1782839a6a"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:ebe303cd9839af69dd1f7942acaa80b1ba90bacef2e7ded9347fbed4f1654672"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fe56659ccadbee97908132135de4b875543353351e0c92e736b7c57aee298b5a"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-win32.whl", hash = "sha256:3f11a7eff7bc6301cd6a5d43f309e22a815af07e1f08eeb2182892fca04c86cb"}, + {file = "rapidfuzz-2.13.7-cp39-cp39-win_amd64.whl", hash = "sha256:e8914dad106dacb0775718e54bf15e528055c4e92fb2677842996f2d52da5069"}, + {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f7930adf84301797c3f09c94b9c5a9ed90a9e8b8ed19b41d2384937e0f9f5bd"}, + {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c31022d9970177f6affc6d5dd757ed22e44a10890212032fabab903fdee3bfe7"}, + {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f42b82f268689f429def9ecfb86fa65ceea0eaf3fed408b570fe113311bf5ce7"}, + {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b477b43ced896301665183a5e0faec0f5aea2373005648da8bdcb3c4b73f280"}, + {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d63def9bbc6b35aef4d76dc740301a4185867e8870cbb8719ec9de672212fca8"}, + {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c66546e30addb04a16cd864f10f5821272a1bfe6462ee5605613b4f1cb6f7b48"}, + {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f799d1d6c33d81e983d3682571cc7d993ae7ff772c19b3aabb767039c33f6d1e"}, + {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d82f20c0060ffdaadaf642b88ab0aa52365b56dffae812e188e5bdb998043588"}, + {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:042644133244bfa7b20de635d500eb9f46af7097f3d90b1724f94866f17cb55e"}, + {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75c45dcd595f8178412367e302fd022860ea025dc4a78b197b35428081ed33d5"}, + {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3d8b081988d0a49c486e4e845a547565fee7c6e7ad8be57ff29c3d7c14c6894c"}, + {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16ffad751f43ab61001187b3fb4a9447ec2d1aedeff7c5bac86d3b95f9980cc3"}, + {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:020858dd89b60ce38811cd6e37875c4c3c8d7fcd8bc20a0ad2ed1f464b34dc4e"}, + {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cda1e2f66bb4ba7261a0f4c2d052d5d909798fca557cbff68f8a79a87d66a18f"}, + {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b6389c50d8d214c9cd11a77f6d501529cb23279a9c9cafe519a3a4b503b5f72a"}, + {file = "rapidfuzz-2.13.7.tar.gz", hash = "sha256:8d3e252d4127c79b4d7c2ae47271636cbaca905c8bb46d80c7930ab906cf4b5c"}, +] + +[package.extras] +full = ["numpy"] + +[[package]] +name = "raven" +version = "6.10.0" +description = "Raven is a client for Sentry (https://getsentry.com)" +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "raven-6.10.0-py2.py3-none-any.whl", hash = "sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4"}, {file = "raven-6.10.0.tar.gz", hash = "sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54"}, ] -requests = [ + +[package.extras] +flask = ["Flask (>=0.8)", "blinker (>=1.1)"] +tests = ["Flask (>=0.8)", "Flask-Login (>=0.2.0)", "ZConfig", "aiohttp", "anyjson", "blinker (>=1.1)", "blinker (>=1.1)", "bottle", "celery (>=2.5)", "coverage (<4)", "exam (>=0.5.2)", "flake8 (==3.5.0)", "logbook", "mock", "nose", "pytest (>=3.2.0,<3.3.0)", "pytest-cov (==2.5.1)", "pytest-flake8 (==1.0.0)", "pytest-pythonpath (==0.7.2)", "pytest-timeout (==1.2.1)", "pytest-xdist (==1.18.2)", "pytz", "requests", "sanic (>=0.7.0)", "tornado (>=4.1,<5.0)", "tox", "webob", "webtest", "wheel"] + +[[package]] +name = "requests" +version = "2.28.1" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=3.7, <4" +files = [ {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] -rich = [ + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-toolbelt" +version = "0.10.1" +description = "A utility belt for advanced users of python-requests" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-0.10.1.tar.gz", hash = "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d"}, + {file = "requests_toolbelt-0.10.1-py2.py3-none-any.whl", hash = "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "rich" +version = "12.6.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "dev" +optional = false +python-versions = ">=3.6.3,<4.0.0" +files = [ {file = "rich-12.6.0-py3-none-any.whl", hash = "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e"}, {file = "rich-12.6.0.tar.gz", hash = "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0"}, ] -setproctitle = [ + +[package.dependencies] +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] + +[[package]] +name = "secretstorage" +version = "3.3.3" +description = "Python bindings to FreeDesktop.org Secret Service API" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, + {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, +] + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + +[[package]] +name = "setproctitle" +version = "1.3.2" +description = "A Python module to customize the process title" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "setproctitle-1.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:288943dec88e178bb2fd868adf491197cc0fc8b6810416b1c6775e686bab87fe"}, {file = "setproctitle-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:630f6fe5e24a619ccf970c78e084319ee8be5be253ecc9b5b216b0f474f5ef18"}, {file = "setproctitle-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c877691b90026670e5a70adfbcc735460a9f4c274d35ec5e8a43ce3f8443005"}, @@ -1939,6 +2338,18 @@ setproctitle = [ {file = "setproctitle-1.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f2719a398e1a2c01c2a63bf30377a34d0b6ef61946ab9cf4d550733af8f1ef1"}, {file = "setproctitle-1.3.2-cp310-cp310-win32.whl", hash = "sha256:e425be62524dc0c593985da794ee73eb8a17abb10fe692ee43bb39e201d7a099"}, {file = "setproctitle-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:e85e50b9c67854f89635a86247412f3ad66b132a4d8534ac017547197c88f27d"}, + {file = "setproctitle-1.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a97d51c17d438cf5be284775a322d57b7ca9505bb7e118c28b1824ecaf8aeaa"}, + {file = "setproctitle-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587c7d6780109fbd8a627758063d08ab0421377c0853780e5c356873cdf0f077"}, + {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d17c8bd073cbf8d141993db45145a70b307385b69171d6b54bcf23e5d644de"}, + {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e932089c35a396dc31a5a1fc49889dd559548d14cb2237adae260382a090382e"}, + {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e4f8f12258a8739c565292a551c3db62cca4ed4f6b6126664e2381acb4931bf"}, + {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:570d255fd99c7f14d8f91363c3ea96bd54f8742275796bca67e1414aeca7d8c3"}, + {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a8e0881568c5e6beff91ef73c0ec8ac2a9d3ecc9edd6bd83c31ca34f770910c4"}, + {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4bba3be4c1fabf170595b71f3af46c6d482fbe7d9e0563999b49999a31876f77"}, + {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:37ece938110cab2bb3957e3910af8152ca15f2b6efdf4f2612e3f6b7e5459b80"}, + {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db684d6bbb735a80bcbc3737856385b55d53f8a44ce9b46e9a5682c5133a9bf7"}, + {file = "setproctitle-1.3.2-cp311-cp311-win32.whl", hash = "sha256:ca58cd260ea02759238d994cfae844fc8b1e206c684beb8f38877dcab8451dfc"}, + {file = "setproctitle-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:88486e6cce2a18a033013d17b30a594f1c5cb42520c49c19e6ade40b864bb7ff"}, {file = "setproctitle-1.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:92c626edc66169a1b09e9541b9c0c9f10488447d8a2b1d87c8f0672e771bc927"}, {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:710e16fa3bade3b026907e4a5e841124983620046166f355bbb84be364bf2a02"}, {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f29b75e86260b0ab59adb12661ef9f113d2f93a59951373eb6d68a852b13e83"}, @@ -1988,81 +2399,351 @@ setproctitle = [ {file = "setproctitle-1.3.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7aa0aac1711fadffc1d51e9d00a3bea61f68443d6ac0241a224e4d622489d665"}, {file = "setproctitle-1.3.2.tar.gz", hash = "sha256:b9fb97907c830d260fa0658ed58afd48a86b2b88aac521135c352ff7fd3477fd"}, ] -setuptools = [ + +[package.extras] +test = ["pytest"] + +[[package]] +name = "setuptools" +version = "65.6.3" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"}, {file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"}, ] -six = [ + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "shellingham" +version = "1.5.0" +description = "Tool to Detect Surrounding Shell" +category = "main" +optional = false +python-versions = ">=3.4" +files = [ + {file = "shellingham-1.5.0-py2.py3-none-any.whl", hash = "sha256:a8f02ba61b69baaa13facdba62908ca8690a94b8119b69f5ec5873ea85f7391b"}, + {file = "shellingham-1.5.0.tar.gz", hash = "sha256:72fb7f5c63103ca2cb91b23dee0c71fe8ad6fbfd46418ef17dbe40db51592dad"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -sniffio = [ + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] -snowballstemmer = [ + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -soupsieve = [ + +[[package]] +name = "soupsieve" +version = "2.3.2.post1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, ] -sphinx = [ + +[[package]] +name = "sphinx" +version = "5.3.0" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"}, {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"}, ] -sphinx-autobuild = [ + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.20" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.12" +requests = ">=2.5.0" +snowballstemmer = ">=2.0" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] + +[[package]] +name = "sphinx-autobuild" +version = "2021.3.14" +description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, ] -sphinx-basic-ng = [ + +[package.dependencies] +colorama = "*" +livereload = "*" +sphinx = "*" + +[package.extras] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b1" +description = "A modern skeleton for Sphinx themes." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "sphinx_basic_ng-1.0.0b1-py3-none-any.whl", hash = "sha256:ade597a3029c7865b24ad0eda88318766bcc2f9f4cef60df7e28126fde94db2a"}, {file = "sphinx_basic_ng-1.0.0b1.tar.gz", hash = "sha256:89374bd3ccd9452a301786781e28c8718e99960f2d4f411845ea75fc7bb5a9b0"}, ] -sphinx-intl = [ + +[package.dependencies] +sphinx = ">=4.0" + +[package.extras] +docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"] + +[[package]] +name = "sphinx-intl" +version = "2.0.1" +description = "Sphinx utility that make it easy to translate and to apply translation." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ {file = "sphinx-intl-2.0.1.tar.gz", hash = "sha256:b25a6ec169347909e8d983eefe2d8adecb3edc2f27760db79b965c69950638b4"}, ] -sphinxcontrib-applehelp = [ + +[package.dependencies] +babel = "*" +click = "*" +setuptools = "*" +sphinx = "*" + +[package.extras] +test = ["mock", "pytest"] +transifex = ["transifex_client (>=0.11)"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, ] -sphinxcontrib-devhelp = [ + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, ] -sphinxcontrib-htmlhelp = [ + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, ] -sphinxcontrib-jsmath = [ + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, ] -sphinxcontrib-qthelp = [ + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, ] -sphinxcontrib-serializinghtml = [ + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] -starlette = [ + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "starlette" +version = "0.22.0" +description = "The little ASGI library that shines." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "starlette-0.22.0-py3-none-any.whl", hash = "sha256:b5eda991ad5f0ee5d8ce4c4540202a573bb6691ecd0c712262d0bc85cf8f2c50"}, {file = "starlette-0.22.0.tar.gz", hash = "sha256:b092cbc365bea34dd6840b42861bdabb2f507f8671e642e8272d2442e08ea4ff"}, ] -timeout-decorator = [ + +[package.dependencies] +anyio = ">=3.4.0,<5" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] + +[[package]] +name = "timeout-decorator" +version = "0.5.0" +description = "Timeout decorator" +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "timeout-decorator-0.5.0.tar.gz", hash = "sha256:6a2f2f58db1c5b24a2cc79de6345760377ad8bdc13813f5265f6c3e63d16b3d7"}, ] -toml = [ + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -tomli = [ + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -tornado = [ + +[[package]] +name = "tomlkit" +version = "0.11.6" +description = "Style preserving TOML library" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, + {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, +] + +[[package]] +name = "tornado" +version = "6.2" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "dev" +optional = false +python-versions = ">= 3.7" +files = [ {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"}, {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"}, {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"}, @@ -2075,7 +2756,27 @@ tornado = [ {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, ] -typed-ast = [ + +[[package]] +name = "trove-classifiers" +version = "2022.12.22" +description = "Canonical source for classifiers on PyPI (pypi.org)." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "trove-classifiers-2022.12.22.tar.gz", hash = "sha256:fe0fe3f085987161aee2a5a853c7cc7cdf64515c5965d57ad968fdd8cc3b0362"}, + {file = "trove_classifiers-2022.12.22-py3-none-any.whl", hash = "sha256:f0013fd4ce06cfae879a2580ab6acc3d51ec93ecb364d6c061b6c77b44dd72de"}, +] + +[[package]] +name = "typed-ast" +version = "1.5.4" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, @@ -2101,23 +2802,68 @@ typed-ast = [ {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] -types-croniter = [ + +[[package]] +name = "types-croniter" +version = "1.3.2.1" +description = "Typing stubs for croniter" +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "types-croniter-1.3.2.1.tar.gz", hash = "sha256:1f0a14b9465471f460640de935e8e4a9b3fe90537ff1f287594e6e53f3ff6b86"}, {file = "types_croniter-1.3.2.1-py3-none-any.whl", hash = "sha256:469e795a71f45fd2895af3accfccfbf337c9df364fcc23a8768417cbf1447339"}, ] -types-setuptools = [ + +[[package]] +name = "types-setuptools" +version = "65.6.0.2" +description = "Typing stubs for setuptools" +category = "dev" +optional = false +python-versions = "*" +files = [ {file = "types-setuptools-65.6.0.2.tar.gz", hash = "sha256:ad60ccf01d626de9762224448f36c13e0660e863afd6dc11d979b3739a6c7d24"}, {file = "types_setuptools-65.6.0.2-py3-none-any.whl", hash = "sha256:2c2b4f756f79778074ce2d21f745aa737b12160d9f8dfa274f47a7287c7a2fee"}, ] -typing-extensions = [ + +[[package]] +name = "typing-extensions" +version = "4.4.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] -urllib3 = [ + +[[package]] +name = "urllib3" +version = "1.26.13" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, ] -uvloop = [ + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "uvloop" +version = "0.17.0" +description = "Fast implementation of asyncio event loop on top of libuv" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718"}, {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c"}, {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d"}, @@ -2149,23 +2895,213 @@ uvloop = [ {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded"}, {file = "uvloop-0.17.0.tar.gz", hash = "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1"}, ] -virtualenv = [ + +[package.extras] +dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)", "pytest (>=3.6.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] + +[[package]] +name = "virtualenv" +version = "20.16.5" +description = "Virtual Python Environment builder" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "virtualenv-20.16.5-py3-none-any.whl", hash = "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27"}, + {file = "virtualenv-20.16.5.tar.gz", hash = "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da"}, +] + +[package.dependencies] +distlib = ">=0.3.5,<1" +filelock = ">=3.4.1,<4" +platformdirs = ">=2.4,<3" + +[package.extras] +docs = ["proselint (>=0.13)", "sphinx (>=5.1.1)", "sphinx-argparse (>=0.3.1)", "sphinx-rtd-theme (>=1)", "towncrier (>=21.9)"] +testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] + +[[package]] +name = "virtualenv" +version = "20.17.1" +description = "Virtual Python Environment builder" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ {file = "virtualenv-20.17.1-py3-none-any.whl", hash = "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4"}, {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, ] -waitress = [ + +[package.dependencies] +distlib = ">=0.3.6,<1" +filelock = ">=3.4.1,<4" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.8\""} +platformdirs = ">=2.4,<3" + +[package.extras] +docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] +testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] + +[[package]] +name = "waitress" +version = "2.1.2" +description = "Waitress WSGI server" +category = "dev" +optional = false +python-versions = ">=3.7.0" +files = [ {file = "waitress-2.1.2-py3-none-any.whl", hash = "sha256:7500c9625927c8ec60f54377d590f67b30c8e70ef4b8894214ac6e4cad233d2a"}, {file = "waitress-2.1.2.tar.gz", hash = "sha256:780a4082c5fbc0fde6a2fcfe5e26e6efc1e8f425730863c04085769781f51eba"}, ] -webob = [ + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] +testing = ["coverage (>=5.0)", "pytest", "pytest-cover"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[[package]] +name = "webob" +version = "1.8.7" +description = "WSGI request and response object" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" +files = [ {file = "WebOb-1.8.7-py2.py3-none-any.whl", hash = "sha256:73aae30359291c14fa3b956f8b5ca31960e420c28c1bec002547fb04928cf89b"}, {file = "WebOb-1.8.7.tar.gz", hash = "sha256:b64ef5141be559cfade448f044fa45c2260351edcb6a8ef6b7e00c7dcef0c323"}, ] -webtest = [ + +[package.extras] +docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] +testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "webtest" +version = "3.0.0" +description = "Helper to test WSGI applications" +category = "dev" +optional = false +python-versions = ">=3.6, <4" +files = [ {file = "WebTest-3.0.0-py3-none-any.whl", hash = "sha256:2a001a9efa40d2a7e5d9cd8d1527c75f41814eb6afce2c3d207402547b1e5ead"}, {file = "WebTest-3.0.0.tar.gz", hash = "sha256:54bd969725838d9861a9fa27f8d971f79d275d94ae255f5c501f53bb6d9929eb"}, ] -yarl = [ + +[package.dependencies] +beautifulsoup4 = "*" +waitress = ">=0.8.5" +WebOb = ">=1.2" + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.8)"] +tests = ["PasteDeploy", "WSGIProxy2", "coverage", "pyquery", "pytest", "pytest-cov"] + +[[package]] +name = "xattr" +version = "0.10.1" +description = "Python wrapper for extended filesystem attributes" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "xattr-0.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:16a660a883e703b311d1bbbcafc74fa877585ec081cd96e8dd9302c028408ab1"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1e2973e72faa87ca29d61c23b58c3c89fe102d1b68e091848b0e21a104123503"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:13279fe8f7982e3cdb0e088d5cb340ce9cbe5ef92504b1fd80a0d3591d662f68"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1dc9b9f580ef4b8ac5e2c04c16b4d5086a611889ac14ecb2e7e87170623a0b75"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:485539262c2b1f5acd6b6ea56e0da2bc281a51f74335c351ea609c23d82c9a79"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:295b3ab335fcd06ca0a9114439b34120968732e3f5e9d16f456d5ec4fa47a0a2"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a126eb38e14a2f273d584a692fe36cff760395bf7fc061ef059224efdb4eb62c"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:b0e919c24f5b74428afa91507b15e7d2ef63aba98e704ad13d33bed1288dca81"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:e31d062cfe1aaeab6ba3db6bd255f012d105271018e647645941d6609376af18"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:209fb84c09b41c2e4cf16dd2f481bb4a6e2e81f659a47a60091b9bcb2e388840"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c4120090dac33eddffc27e487f9c8f16b29ff3f3f8bcb2251b2c6c3f974ca1e1"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e739d624491267ec5bb740f4eada93491de429d38d2fcdfb97b25efe1288eca"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2677d40b95636f3482bdaf64ed9138fb4d8376fb7933f434614744780e46e42d"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40039f1532c4456fd0f4c54e9d4e01eb8201248c321c6c6856262d87e9a99593"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:148466e5bb168aba98f80850cf976e931469a3c6eb11e9880d9f6f8b1e66bd06"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0aedf55b116beb6427e6f7958ccd80a8cbc80e82f87a4cd975ccb61a8d27b2ee"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c3024a9ff157247c8190dd0eb54db4a64277f21361b2f756319d9d3cf20e475f"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f1be6e733e9698f645dbb98565bb8df9b75e80e15a21eb52787d7d96800e823b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7880c8a54c18bc091a4ce0adc5c6d81da1c748aec2fe7ac586d204d6ec7eca5b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:89c93b42c3ba8aedbc29da759f152731196c2492a2154371c0aae3ef8ba8301b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b905e808df61b677eb972f915f8a751960284358b520d0601c8cbc476ba2df6"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ef954d0655f93a34d07d0cc7e02765ec779ff0b59dc898ee08c6326ad614d5"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:199b20301b6acc9022661412346714ce764d322068ef387c4de38062474db76c"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0956a8ab0f0d3f9011ba480f1e1271b703d11542375ef73eb8695a6bd4b78b"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffcb57ca1be338d69edad93cf59aac7c6bb4dbb92fd7bf8d456c69ea42f7e6d2"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f0563196ee54756fe2047627d316977dc77d11acd7a07970336e1a711e934db"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc354f086f926a1c7f04886f97880fed1a26d20e3bc338d0d965fd161dbdb8ab"}, + {file = "xattr-0.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c0cd2d02ef2fb45ecf2b0da066a58472d54682c6d4f0452dfe7ae2f3a76a42ea"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49626096ddd72dcc1654aadd84b103577d8424f26524a48d199847b5d55612d0"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceaa26bef8fcb17eb59d92a7481c2d15d20211e217772fb43c08c859b01afc6a"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c014c371391f28f8cd27d73ea59f42b30772cd640b5a2538ad4f440fd9190b"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:46c32cd605673606b9388a313b0050ee7877a0640d7561eea243ace4fa2cc5a6"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:772b22c4ff791fe5816a7c2a1c9fcba83f9ab9bea138eb44d4d70f34676232b4"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:183ad611a2d70b5a3f5f7aadef0fcef604ea33dcf508228765fd4ddac2c7321d"}, + {file = "xattr-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8068df3ebdfa9411e58d5ae4a05d807ec5994645bb01af66ec9f6da718b65c5b"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bc40570155beb85e963ae45300a530223d9822edfdf09991b880e69625ba38a"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:436e1aaf23c07e15bed63115f1712d2097e207214fc6bcde147c1efede37e2c5"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7298455ccf3a922d403339781b10299b858bb5ec76435445f2da46fb768e31a5"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:986c2305c6c1a08f78611eb38ef9f1f47682774ce954efb5a4f3715e8da00d5f"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5dc6099e76e33fa3082a905fe59df766b196534c705cf7a2e3ad9bed2b8a180e"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:042ad818cda6013162c0bfd3816f6b74b7700e73c908cde6768da824686885f8"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d4c306828a45b41b76ca17adc26ac3dc00a80e01a5ba85d71df2a3e948828f2"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a606280b0c9071ef52572434ecd3648407b20df3d27af02c6592e84486b05894"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5b49d591cf34cda2079fd7a5cb2a7a1519f54dc2e62abe3e0720036f6ed41a85"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8705ac6791426559c1a5c2b88bb2f0e83dc5616a09b4500899bfff6a929302"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5ea974930e876bc5c146f54ac0f85bb39b7b5de2b6fc63f90364712ae368ebe"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f55a2dd73a12a1ae5113c5d9cd4b4ab6bf7950f4d76d0a1a0c0c4264d50da61d"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:475c38da0d3614cc5564467c4efece1e38bd0705a4dbecf8deeb0564a86fb010"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:925284a4a28e369459b2b7481ea22840eed3e0573a4a4c06b6b0614ecd27d0a7"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa32f1b45fed9122bed911de0fcc654da349e1f04fa4a9c8ef9b53e1cc98b91e"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c5d3d0e728bace64b74c475eb4da6148cd172b2d23021a1dcd055d92f17619ac"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8faaacf311e2b5cc67c030c999167a78a9906073e6abf08eaa8cf05b0416515c"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc6b8d5ca452674e1a96e246a3d2db5f477aecbc7c945c73f890f56323e75203"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3725746a6502f40f72ef27e0c7bfc31052a239503ff3eefa807d6b02a249be22"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789bd406d1aad6735e97b20c6d6a1701e1c0661136be9be862e6a04564da771f"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a7a807ab538210ff8532220d8fc5e2d51c212681f63dbd4e7ede32543b070f"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e5825b5fc99ecdd493b0cc09ec35391e7a451394fdf623a88b24726011c950d"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80638d1ce7189dc52f26c234cee3522f060fadab6a8bc3562fe0ddcbe11ba5a4"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3ff0dbe4a6ce2ce065c6de08f415bcb270ecfd7bf1655a633ddeac695ce8b250"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5267e5f9435c840d2674194150b511bef929fa7d3bc942a4a75b9eddef18d8d8"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b27dfc13b193cb290d5d9e62f806bb9a99b00cd73bb6370d556116ad7bb5dc12"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:636ebdde0277bce4d12d2ef2550885804834418fee0eb456b69be928e604ecc4"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d60c27922ec80310b45574351f71e0dd3a139c5295e8f8b19d19c0010196544f"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b34df5aad035d0343bd740a95ca30db99b776e2630dca9cc1ba8e682c9cc25ea"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f24a7c04ff666d0fe905dfee0a84bc899d624aeb6dccd1ea86b5c347f15c20c1"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3878e1aff8eca64badad8f6d896cb98c52984b1e9cd9668a3ab70294d1ef92d"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4abef557028c551d59cf2fb3bf63f2a0c89f00d77e54c1c15282ecdd56943496"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e14bd5965d3db173d6983abdc1241c22219385c22df8b0eb8f1846c15ce1fee"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9be588a4b6043b03777d50654c6079af3da60cc37527dbb80d36ec98842b1e"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bc4ae264aa679aacf964abf3ea88e147eb4a22aea6af8c6d03ebdebd64cfd6"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:827b5a97673b9997067fde383a7f7dc67342403093b94ea3c24ae0f4f1fec649"}, + {file = "xattr-0.10.1.tar.gz", hash = "sha256:c12e7d81ffaa0605b3ac8c22c2994a8e18a9cf1c59287a1b7722a2289c952ec5"}, +] + +[package.dependencies] +cffi = ">=1.0" + +[[package]] +name = "yarl" +version = "1.8.2" +description = "Yet another URL library" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5"}, {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:47d49ac96156f0928f002e2424299b2c91d9db73e08c4cd6742923a086f1c863"}, {file = "yarl-1.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3fc056e35fa6fba63248d93ff6e672c096f95f7836938241ebc8260e062832fe"}, @@ -2241,7 +3177,38 @@ yarl = [ {file = "yarl-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:6604711362f2dbf7160df21c416f81fac0de6dbcf0b5445a2ef25478ecc4c778"}, {file = "yarl-1.8.2.tar.gz", hash = "sha256:49d43402c6e3013ad0978602bf6bf5328535c48d192304b91b97a3c6790b1562"}, ] -zipp = [ + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} + +[[package]] +name = "zipp" +version = "3.11.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, ] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[extras] +aiohttp = [] +asgi = [] +carbon = [] +cron = [] +raven = [] +rich = [] +uvloop = [] + +[metadata] +lock-version = "2.0" +python-versions = "^3.7" +content-hash = "098f0b6b51ca17e933a156a48d09385b67139302ac3a355897d264a773be7c70" diff --git a/pyproject.toml b/pyproject.toml index 5cfede1a..85e722d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "aiomisc" # This is a dummy version which will be rewritten with poem-plugins -version = "16.3.2" +version = "16.3.3" description = "aiomisc - miscellaneous utils for asyncio" authors = ["Dmitry Orlov "] readme = "README.rst" @@ -38,6 +38,7 @@ packages = [ python = "^3.7" colorlog = "^6.0" logging-journald = [{ version = '*', platform = 'linux' }] +poetry = "^1.3.1" [tool.poetry.group.dev.dependencies] aiocontextvars = "0.2.2" From 0c3d020eb53632b1d7ac9afffaf947c51499e735 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 29 Dec 2022 15:28:12 +0300 Subject: [PATCH 34/45] add semver summary --- README.rst | 14 + docs/source/index.rst | 15 + docs/source/locale/ru/LC_MESSAGES/index.po | 56 +- poetry.lock | 1287 +++----------------- pyproject.toml | 1 - 5 files changed, 237 insertions(+), 1136 deletions(-) diff --git a/README.rst b/README.rst index 1631da70..a27bd9b0 100644 --- a/README.rst +++ b/README.rst @@ -75,6 +75,20 @@ Versioning This software follows `Semantic Versioning`_ +Summary: it's given a version number MAJOR.MINOR.PATCH, increment the: + +* MAJOR version when you make incompatible API changes +* MINOR version when you add functionality in a backwards compatible manner +* PATCH version when you make backwards compatible bug fixes +* Additional labels for pre-release and build metadata are available as + extensions to the MAJOR.MINOR.PATCH format. + +In this case, the package version is assigned automatically with poem-plugins_, +it using on the tag in the repository as a major and minor and the counter, +which takes the number of commits between tag to the head of branch. + +.. _poem-plugins: https://pypi.org/project/poem-plugins + How to develop? --------------- diff --git a/docs/source/index.rst b/docs/source/index.rst index 6c5237d1..73976a10 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -295,6 +295,21 @@ Versioning This software follows `Semantic Versioning`_ +Summary: it's given a version number MAJOR.MINOR.PATCH, increment the: + +* MAJOR version when you make incompatible API changes +* MINOR version when you add functionality in a backwards compatible manner +* PATCH version when you make backwards compatible bug fixes +* Additional labels for pre-release and build metadata are available as + extensions to the MAJOR.MINOR.PATCH format. + +In this case, the package version is assigned automatically with poem-plugins_, +it using on the tag in the repository as a major and minor and the counter, +which takes the number of commits between tag to the head of branch. + +.. _poem-plugins: https://pypi.org/project/poem-plugins + + How to develop? --------------- diff --git a/docs/source/locale/ru/LC_MESSAGES/index.po b/docs/source/locale/ru/LC_MESSAGES/index.po index 2fef2275..bffa4f5e 100644 --- a/docs/source/locale/ru/LC_MESSAGES/index.po +++ b/docs/source/locale/ru/LC_MESSAGES/index.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-12-29 12:06+0300\n" +"POT-Creation-Date: 2022-12-29 15:24+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -500,38 +500,74 @@ msgstr "" "Это программное обеспечение следует методологиии `Семантического " "Версионирования`_" -#: ../../source/index.rst:299 +#: ../../source/index.rst:298 +msgid "Summary: it's given a version number MAJOR.MINOR.PATCH, increment the:" +msgstr "Кратко: учитывая номер версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ, следует увеличивать:" + +#: ../../source/index.rst:300 +msgid "MAJOR version when you make incompatible API changes" +msgstr "МАЖОРНУЮ версию, когда сделаны обратно несовместимые изменения API." + +#: ../../source/index.rst:301 +msgid "MINOR version when you add functionality in a backwards compatible manner" +msgstr "МИНОРНУЮ версию, когда вы добавляете новую функциональность, не нарушая обратной совместимости." + +#: ../../source/index.rst:302 +msgid "PATCH version when you make backwards compatible bug fixes" +msgstr "ПАТЧ-версию, когда вы делаете обратно совместимые исправления." + +#: ../../source/index.rst:303 +msgid "" +"Additional labels for pre-release and build metadata are available as " +"extensions to the MAJOR.MINOR.PATCH format." +msgstr "" +"Дополнительные обозначения для предрелизных и билд-метаданных возможны как " +"дополнения к МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ формату." + +#: ../../source/index.rst:306 +msgid "" +"In this project, the package version is assigned automatically with poem-" +"plugins_, it using on the tag in the repository as a major and minor and " +"the counter, which takes the number of commits between tag to the head of" +" branch." +msgstr "" +"В этом проекте версия пакета назначается автоматически с помощью " +"poem-plugins_, он использует тег в репозитории как МАЖОР и МИНОР, " +"а также счетчик, который берет количество коммитов между тегом и " +"головой ветки." + +#: ../../source/index.rst:314 msgid "How to develop?" msgstr "Как начать разработку?" -#: ../../source/index.rst:301 +#: ../../source/index.rst:316 msgid "Should be installed:" msgstr "Должно быть установлено" -#: ../../source/index.rst:303 +#: ../../source/index.rst:318 msgid "``virtualenv``" msgstr "``virtualenv``" -#: ../../source/index.rst:304 +#: ../../source/index.rst:319 msgid "GNU Make as ``make``" msgstr "GNU Make как ``make``" -#: ../../source/index.rst:305 +#: ../../source/index.rst:320 msgid "Python 3.7+ as ``python3``" msgstr "Python 3.7+ как ``python3``" -#: ../../source/index.rst:306 +#: ../../source/index.rst:321 msgid "Installed Poetry_ as ``poetry``" msgstr "Установлен Poetry_ как ``poetry``" -#: ../../source/index.rst:311 +#: ../../source/index.rst:326 msgid "For setting up developer environment just type" msgstr "Для настройки окружения разработчика просто наберите" -#: ../../source/index.rst:313 +#: ../../source/index.rst:328 msgid "poetry install" msgstr "" -#: ../../source/index.rst:321 +#: ../../source/index.rst:336 msgid "Table Of Contents" msgstr "Содержание" diff --git a/poetry.lock b/poetry.lock index 92afc84a..9fa5c113 100644 --- a/poetry.lock +++ b/poetry.lock @@ -219,21 +219,22 @@ files = [ [[package]] name = "attrs" -version = "22.1.0" +version = "22.2.0" description = "Classes Without Boilerplate" -category = "main" +category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, - {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, + {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, + {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, ] [package.extras] -dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] -docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] -tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs[tests-no-zope]", "zope.interface"] +tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] [[package]] name = "autodoc" @@ -279,18 +280,6 @@ files = [ [package.dependencies] pytz = ">=2015.7" -[[package]] -name = "backports-cached-property" -version = "1.0.2" -description = "cached_property() - computed once per instance, cached as attribute" -category = "main" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "backports.cached-property-1.0.2.tar.gz", hash = "sha256:9306f9eed6ec55fd156ace6bc1094e2c86fae5fb2bf07b6a9c00745c656e75dd"}, - {file = "backports.cached_property-1.0.2-py3-none-any.whl", hash = "sha256:baeb28e1cd619a3c9ab8941431fe34e8490861fb998c6c4590693d50171db0cc"}, -] - [[package]] name = "beautifulsoup4" version = "4.11.1" @@ -310,32 +299,11 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] -[[package]] -name = "cachecontrol" -version = "0.12.11" -description = "httplib2 caching for requests" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "CacheControl-0.12.11-py2.py3-none-any.whl", hash = "sha256:2c75d6a8938cb1933c75c50184549ad42728a27e9f6b92fd677c3151aa72555b"}, - {file = "CacheControl-0.12.11.tar.gz", hash = "sha256:a5b9fcc986b184db101aa280b42ecdcdfc524892596f606858e0b7a8b4d9e144"}, -] - -[package.dependencies] -lockfile = {version = ">=0.9", optional = true, markers = "extra == \"filecache\""} -msgpack = ">=0.5.2" -requests = "*" - -[package.extras] -filecache = ["lockfile (>=0.9)"] -redis = ["redis (>=2.10.5)"] - [[package]] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -343,83 +311,6 @@ files = [ {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, ] -[[package]] -name = "cffi" -version = "1.15.1" -description = "Foreign Function Interface for Python calling C code." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, -] - -[package.dependencies] -pycparser = "*" - [[package]] name = "cfgv" version = "3.3.1" @@ -436,7 +327,7 @@ files = [ name = "charset-normalizer" version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" +category = "dev" optional = false python-versions = ">=3.6.0" files = [ @@ -447,22 +338,6 @@ files = [ [package.extras] unicode-backport = ["unicodedata2"] -[[package]] -name = "cleo" -version = "2.0.1" -description = "Cleo allows you to create beautiful and testable command-line interfaces." -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "cleo-2.0.1-py3-none-any.whl", hash = "sha256:6eb133670a3ed1f3b052d53789017b6e50fca66d1287e6e6696285f4cb8ea448"}, - {file = "cleo-2.0.1.tar.gz", hash = "sha256:eb4b2e1f3063c11085cebe489a6e9124163c226575a3c3be69b2e51af4a15ec5"}, -] - -[package.dependencies] -crashtest = ">=0.4.1,<0.5.0" -rapidfuzz = ">=2.2.0,<3.0.0" - [[package]] name = "click" version = "8.1.3" @@ -624,18 +499,6 @@ requests = ">=1.0.0" [package.extras] yaml = ["PyYAML (>=3.10)"] -[[package]] -name = "crashtest" -version = "0.4.1" -description = "Manage Python errors with ease" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, - {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, -] - [[package]] name = "croniter" version = "1.3.8" @@ -651,53 +514,6 @@ files = [ [package.dependencies] python-dateutil = "*" -[[package]] -name = "cryptography" -version = "38.0.4" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "cryptography-38.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:2fa36a7b2cc0998a3a4d5af26ccb6273f3df133d61da2ba13b3286261e7efb70"}, - {file = "cryptography-38.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:1f13ddda26a04c06eb57119caf27a524ccae20533729f4b1e4a69b54e07035eb"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2ec2a8714dd005949d4019195d72abed84198d877112abb5a27740e217e0ea8d"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50a1494ed0c3f5b4d07650a68cd6ca62efe8b596ce743a5c94403e6f11bf06c1"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10498349d4c8eab7357a8f9aa3463791292845b79597ad1b98a543686fb1ec8"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:10652dd7282de17990b88679cb82f832752c4e8237f0c714be518044269415db"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:bfe6472507986613dc6cc00b3d492b2f7564b02b3b3682d25ca7f40fa3fd321b"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ce127dd0a6a0811c251a6cddd014d292728484e530d80e872ad9806cfb1c5b3c"}, - {file = "cryptography-38.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:53049f3379ef05182864d13bb9686657659407148f901f3f1eee57a733fb4b00"}, - {file = "cryptography-38.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:8a4b2bdb68a447fadebfd7d24855758fe2d6fecc7fed0b78d190b1af39a8e3b0"}, - {file = "cryptography-38.0.4-cp36-abi3-win32.whl", hash = "sha256:1d7e632804a248103b60b16fb145e8df0bc60eed790ece0d12efe8cd3f3e7744"}, - {file = "cryptography-38.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:8e45653fb97eb2f20b8c96f9cd2b3a0654d742b47d638cf2897afbd97f80fa6d"}, - {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca57eb3ddaccd1112c18fc80abe41db443cc2e9dcb1917078e02dfa010a4f353"}, - {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:c9e0d79ee4c56d841bd4ac6e7697c8ff3c8d6da67379057f29e66acffcd1e9a7"}, - {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0e70da4bdff7601b0ef48e6348339e490ebfb0cbe638e083c9c41fb49f00c8bd"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:998cd19189d8a747b226d24c0207fdaa1e6658a1d3f2494541cb9dfbf7dcb6d2"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67461b5ebca2e4c2ab991733f8ab637a7265bb582f07c7c88914b5afb88cb95b"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:4eb85075437f0b1fd8cd66c688469a0c4119e0ba855e3fef86691971b887caf6"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3178d46f363d4549b9a76264f41c6948752183b3f587666aff0555ac50fd7876"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6391e59ebe7c62d9902c24a4d8bcbc79a68e7c4ab65863536127c8a9cd94043b"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:78e47e28ddc4ace41dd38c42e6feecfdadf9c3be2af389abbfeef1ff06822285"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fb481682873035600b5502f0015b664abc26466153fab5c6bc92c1ea69d478b"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:4367da5705922cf7070462e964f66e4ac24162e22ab0a2e9d31f1b270dd78083"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b4cad0cea995af760f82820ab4ca54e5471fc782f70a007f31531957f43e9dee"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:80ca53981ceeb3241998443c4964a387771588c4e4a5d92735a493af868294f9"}, - {file = "cryptography-38.0.4.tar.gz", hash = "sha256:175c1a818b87c9ac80bb7377f5520b7f31b3ef2a0004e2420319beadedb67290"}, -] - -[package.dependencies] -cffi = ">=1.12" - -[package.extras] -docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] -docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] -sdist = ["setuptools-rust (>=0.11.4)"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] - [[package]] name = "decorator" version = "5.1.1" @@ -714,7 +530,7 @@ files = [ name = "distlib" version = "0.3.6" description = "Distribution utilities" -category = "main" +category = "dev" optional = false python-versions = "*" files = [ @@ -745,98 +561,16 @@ files = [ {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, ] -[[package]] -name = "dulwich" -version = "0.20.50" -description = "Python Git Library" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "dulwich-0.20.50-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:97f02f8d500d4af08dc022d697c56e8539171acc3f575c2fe9acf3b078e5c8c9"}, - {file = "dulwich-0.20.50-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7301773e5cc16d521bc6490e73772a86a4d1d0263de506f08b54678cc4e2f061"}, - {file = "dulwich-0.20.50-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b70106580ed11f45f4c32d2831d0c9c9f359bc2415fff4a6be443e3a36811398"}, - {file = "dulwich-0.20.50-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f9c4f2455f966cad94648278fa9972e4695b35d04f82792fa58e1ea15dd83f0"}, - {file = "dulwich-0.20.50-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9163fbb021a8ad9c35a0814a5eedf45a8eb3a0b764b865d7016d901fc5a947fc"}, - {file = "dulwich-0.20.50-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:322ff8ff6aa4d6d36294cd36de1c84767eb1903c7db3e7b4475ad091febf5363"}, - {file = "dulwich-0.20.50-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5d3290a45651c8e534f8e83ae2e30322aefdd162f0f338bae2e79a6ee5a87513"}, - {file = "dulwich-0.20.50-cp310-cp310-win32.whl", hash = "sha256:80ab07131a6e68594441f5c4767e9e44e87fceafc3e347e541c928a18c679bd8"}, - {file = "dulwich-0.20.50-cp310-cp310-win_amd64.whl", hash = "sha256:eefe786a6010f8546baac4912113eeed4e397ddb8c433a345b548a04d4176496"}, - {file = "dulwich-0.20.50-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df3562dde3079d57287c233d45b790bc967c5aae975c9a7b07ca30e60e055512"}, - {file = "dulwich-0.20.50-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e1ae18d5805f0c0c5dac65795f8d48660437166b12ee2c0ffea95bfdbf9c1051"}, - {file = "dulwich-0.20.50-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d2f7df39bd1378d3b0bfb3e7fc930fd0191924af1f0ef587bcd9946afe076c06"}, - {file = "dulwich-0.20.50-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:731e7f319b34251fadeb362ada1d52cc932369d9cdfa25c0e41150cda28773d0"}, - {file = "dulwich-0.20.50-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d11d44176e5d2fa8271fc86ad1e0a8731b9ad8f77df64c12846b30e16135eb"}, - {file = "dulwich-0.20.50-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7aaabb8e4beadd53f75f853a981caaadef3ef130e5645c902705704eaf136daa"}, - {file = "dulwich-0.20.50-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c3dc9f97ec8d3db08d9723b9fd06f3e52c15b84c800d153cfb59b0a3dc8b8d40"}, - {file = "dulwich-0.20.50-cp311-cp311-win32.whl", hash = "sha256:3b1964fa80cafd5a1fd71615b0313daf6f3295c6ab05656ea0c1d2423539904a"}, - {file = "dulwich-0.20.50-cp311-cp311-win_amd64.whl", hash = "sha256:a24a3893108f3b97beb958670d5f3f2a3bec73a1fe18637a572a85abd949a1c4"}, - {file = "dulwich-0.20.50-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6d409a282f8848fd6c8d7c7545ad2f75c16de5d5977de202642f1d50fdaac554"}, - {file = "dulwich-0.20.50-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5411d0f1092152e1c0bb916ae490fe181953ae1b8d13f4e68661253e10b78dbb"}, - {file = "dulwich-0.20.50-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6343569f998ce429e2a5d813c56768ac51b496522401db950f0aa44240bfa901"}, - {file = "dulwich-0.20.50-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a405cd236766060894411614a272cfb86fe86cde5ca73ef264fc4fa5a715fff4"}, - {file = "dulwich-0.20.50-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ee0f9b02019c0ea84cdd31c00a0c283669b771c85612997a911715cf84e33d99"}, - {file = "dulwich-0.20.50-cp36-cp36m-win32.whl", hash = "sha256:2644466270267270f2157ea6f1c0aa224f6f3bf06a307fc39954e6b4b3d82bae"}, - {file = "dulwich-0.20.50-cp36-cp36m-win_amd64.whl", hash = "sha256:d4629635a97e3af1b5da48071e00c8e70fad85f3266fadabe1f5a8f49172c507"}, - {file = "dulwich-0.20.50-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0e4862f318d99cc8a500e3622a89613a88c07d957a0f628cdc2ed86addff790f"}, - {file = "dulwich-0.20.50-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96e3fb9d48c0454dc242c7accc7819780c9a7f29e441a9eff12361ed0fa35f9"}, - {file = "dulwich-0.20.50-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc6092a4f0bbbff2e553e87a9c6325955b64ea43fca21297c8182e19ae8a43c"}, - {file = "dulwich-0.20.50-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:519b627d49d273e2fd01c79d09e578675ca6cd05193c1787e9ef165c9a1d66ea"}, - {file = "dulwich-0.20.50-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a75cab01b909c4c683c2083e060e378bc01701b7366b5a7d9846ef6d3b9e3d5"}, - {file = "dulwich-0.20.50-cp37-cp37m-win32.whl", hash = "sha256:ea8ffe26d91dbcd5580dbd5a07270a12ea57b091604d77184da0a0d9fad50ed3"}, - {file = "dulwich-0.20.50-cp37-cp37m-win_amd64.whl", hash = "sha256:8f3af857f94021cae1322d86925bfc0dd31e501e885ab5db275473bfac0bb39d"}, - {file = "dulwich-0.20.50-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3fb35cedb1243bc420d885ef5b4afd642c6ac8f07ddfc7fdbca1becf9948bf7e"}, - {file = "dulwich-0.20.50-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4bb23a9cec63e16c0e432335f068169b73dd44fa9318dd7cd7a4ca83607ff367"}, - {file = "dulwich-0.20.50-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5267619b34ddaf8d9a6b841492cd17a971fd25bf9a5657f2de928385c3a08b94"}, - {file = "dulwich-0.20.50-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9091f1d53a3c0747cbf0bd127c64e7f09b770264d8fb53e284383fcdf69154e7"}, - {file = "dulwich-0.20.50-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6ec7c8fea2b44187a3b545e6c11ab9947ffb122647b07abcdb7cc3aaa770c0e"}, - {file = "dulwich-0.20.50-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:11b180b80363b4fc70664197028181a17ae4c52df9965a29b62a6c52e40c2dbe"}, - {file = "dulwich-0.20.50-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c83e7840d9d0a94d7033bc109efe0c22dfcdcd816bcd4469085e42809e3bf5ba"}, - {file = "dulwich-0.20.50-cp38-cp38-win32.whl", hash = "sha256:c075f69c2de19d9fd97e3b70832d2b42c6a4a5d909b3ffd1963b67d86029f95f"}, - {file = "dulwich-0.20.50-cp38-cp38-win_amd64.whl", hash = "sha256:06775c5713cfeda778c7c67d4422b5e7554d3a7f644f1dde646cdf486a30285a"}, - {file = "dulwich-0.20.50-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:49f66f1c057c18d7d60363f461f4ab8329320fbe1f02a7a33c255864a7d3c942"}, - {file = "dulwich-0.20.50-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e541cd690a5e3d55082ed51732d755917e933cddeb4b0204f2a5ec5d5d7b60b"}, - {file = "dulwich-0.20.50-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:80e8750ee2fa0ab2784a095956077758e5f6107de27f637c4b9d18406652c22c"}, - {file = "dulwich-0.20.50-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fbb6368f18451dc44c95c55e1a609d1a01d3821f7ed480b22b2aea1baca0f4a7"}, - {file = "dulwich-0.20.50-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3ee45001411b638641819b7b3b33f31f13467c84066e432256580fcab7d8815"}, - {file = "dulwich-0.20.50-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4842e22ed863a776b36ef8ffe9ed7b772eb452b42c8d02975c29d27e3bc50ab4"}, - {file = "dulwich-0.20.50-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:790e4a641284a7fb4d56ebdaf8b324a5826fbbb9c54307c06f586f9f6a5e56db"}, - {file = "dulwich-0.20.50-cp39-cp39-win32.whl", hash = "sha256:f08406b6b789dea5c95ba1130a0801d8748a67f18be940fe7486a8b481fde875"}, - {file = "dulwich-0.20.50-cp39-cp39-win_amd64.whl", hash = "sha256:78c388ad421199000fb7b5ed5f0c7b509b3e31bd7cad303786a4d0bf89b82f60"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cb194c53109131bcbcd1ca430fcd437cdaf2d33e204e45fbe121c47eaa43e9af"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7542a72c5640dd0620862d6df8688f02a6c336359b5af9b3fcfe11b7fa6652f"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa1d0861517ebbbe0e0084cc9ab4f7ab720624a3eda2bd10e45f774ab858db8"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:583c6bbc27f13fe2e41a19f6987a42681c6e4f6959beae0a6e5bb033b8b081a8"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0c61c193d02c0e1e0d758cdd57ae76685c368d09a01f00d704ba88bd96767cfe"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2edbff3053251985f10702adfafbee118298d383ef5b5b432a5f22d1f1915df"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a344230cadfc5d315752add6ce9d4cfcfc6c85e36bbf57fce9444bcc7c6ea8fb"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bff9bde0b6b05b00c6acbb1a94357caddb2908ed7026a48c715ff50d220335"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e29a3c2037761fa816aa556e78364dfc8e3f44b873db2d17aed96f9b06ac83a3"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2aa2a4a84029625bf9c63771f8a628db1f3be2d2ea3cb8b17942cd4317797152"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd9fa00971ecf059bb358085a942ecac5be4ff71acdf299f44c8cbc45c18659f"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4adac92fb95671ea3a24f2f8e5e5e8f638711ce9c33a3ca6cd68bf1ff7d99f"}, - {file = "dulwich-0.20.50.tar.gz", hash = "sha256:50a941796b2c675be39be728d540c16b5b7ce77eb9e1b3f855650ece6832d2be"}, -] - -[package.dependencies] -urllib3 = ">=1.25" - -[package.extras] -fastimport = ["fastimport"] -https = ["urllib3 (>=1.24.1)"] -paramiko = ["paramiko"] -pgp = ["gpg"] - [[package]] name = "exceptiongroup" -version = "1.0.4" +version = "1.1.0" description = "Backport of PEP 654 (exception groups)" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"}, - {file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"}, + {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"}, + {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"}, ] [package.extras] @@ -866,19 +600,19 @@ test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==22.10.0)", "coverage[toml] (>= [[package]] name = "filelock" -version = "3.8.2" +version = "3.9.0" description = "A platform independent file lock." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "filelock-3.8.2-py3-none-any.whl", hash = "sha256:8df285554452285f79c035efb0c861eb33a4bcfa5b7a137016e32e6a90f9792c"}, - {file = "filelock-3.8.2.tar.gz", hash = "sha256:7565f628ea56bfcd8e54e42bdc55da899c85c1abfe1b5bcfd147e9188cebb3b2"}, + {file = "filelock-3.9.0-py3-none-any.whl", hash = "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d"}, + {file = "filelock-3.9.0.tar.gz", hash = "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de"}, ] [package.extras] -docs = ["furo (>=2022.9.29)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -testing = ["covdefaults (>=2.2.2)", "coverage (>=6.5)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2022.12.7)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] +testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] [[package]] name = "freezegun" @@ -997,28 +731,6 @@ pygments = ">=2.7" sphinx = ">=5.0,<7.0" sphinx-basic-ng = "*" -[[package]] -name = "html5lib" -version = "1.1" -description = "HTML parser based on the WHATWG HTML specification" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, - {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, -] - -[package.dependencies] -six = ">=1.9" -webencodings = "*" - -[package.extras] -all = ["chardet (>=2.2)", "genshi", "lxml"] -chardet = ["chardet (>=2.2)"] -genshi = ["genshi"] -lxml = ["lxml"] - [[package]] name = "identify" version = "2.5.11" @@ -1038,7 +750,7 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1060,14 +772,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "4.13.0" +version = "5.2.0" description = "Read metadata from Python packages" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"}, - {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"}, + {file = "importlib_metadata-5.2.0-py3-none-any.whl", hash = "sha256:0eafa39ba42bf225fc00e67f701d71f85aead9f878569caf13c3724f704b970f"}, + {file = "importlib_metadata-5.2.0.tar.gz", hash = "sha256:404d48d62bba0b7a77ff9d405efd91501bef2e67ff4ace0bed40a0cf28c3c7cd"}, ] [package.dependencies] @@ -1075,29 +787,10 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] -[[package]] -name = "importlib-resources" -version = "5.10.2" -description = "Read resources from Python packages" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "importlib_resources-5.10.2-py3-none-any.whl", hash = "sha256:7d543798b0beca10b6a01ac7cafda9f822c54db9e8376a6bf57e0cbd74d486b6"}, - {file = "importlib_resources-5.10.2.tar.gz", hash = "sha256:e4a96c8cc0339647ff9a5e0550d9f276fc5a01ffa276012b58ec108cfd7b8484"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [[package]] name = "iniconfig" version = "1.1.1" @@ -1110,41 +803,6 @@ files = [ {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] -[[package]] -name = "jaraco-classes" -version = "3.2.3" -description = "Utility functions for Python class constructs" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jaraco.classes-3.2.3-py3-none-any.whl", hash = "sha256:2353de3288bc6b82120752201c6b1c1a14b058267fa424ed5ce5984e3b922158"}, - {file = "jaraco.classes-3.2.3.tar.gz", hash = "sha256:89559fa5c1d3c34eff6f631ad80bb21f378dbcbb35dd161fd2c6b93f5be2f98a"}, -] - -[package.dependencies] -more-itertools = "*" - -[package.extras] -docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - -[[package]] -name = "jeepney" -version = "0.8.0" -description = "Low-level, pure Python DBus protocol wrapper." -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, - {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, -] - -[package.extras] -test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] -trio = ["async_generator", "trio"] - [[package]] name = "jinja2" version = "3.1.2" @@ -1163,55 +821,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "jsonschema" -version = "4.17.3" -description = "An implementation of JSON Schema validation for Python" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] - -[[package]] -name = "keyring" -version = "23.13.1" -description = "Store and access your passwords safely." -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "keyring-23.13.1-py3-none-any.whl", hash = "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd"}, - {file = "keyring-23.13.1.tar.gz", hash = "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} -importlib-resources = {version = "*", markers = "python_version < \"3.9\""} -"jaraco.classes" = "*" -jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} -pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} -SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} - -[package.extras] -completion = ["shtab"] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [[package]] name = "livereload" version = "2.6.3" @@ -1228,18 +837,6 @@ files = [ six = "*" tornado = {version = "*", markers = "python_version > \"2.7\""} -[[package]] -name = "lockfile" -version = "0.12.2" -description = "Platform-independent file locking module" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, - {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, -] - [[package]] name = "logging-journald" version = "0.6.4" @@ -1314,162 +911,88 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] -[[package]] -name = "more-itertools" -version = "9.0.0" -description = "More routines for operating on iterables, beyond itertools" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "more-itertools-9.0.0.tar.gz", hash = "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab"}, - {file = "more_itertools-9.0.0-py3-none-any.whl", hash = "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41"}, -] - -[[package]] -name = "msgpack" -version = "1.0.4" -description = "MessagePack serializer" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250"}, - {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88"}, - {file = "msgpack-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467"}, - {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6"}, - {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa"}, - {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6"}, - {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba"}, - {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e"}, - {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db"}, - {file = "msgpack-1.0.4-cp310-cp310-win32.whl", hash = "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef"}, - {file = "msgpack-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075"}, - {file = "msgpack-1.0.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52"}, - {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9"}, - {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9"}, - {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08"}, - {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8"}, - {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6"}, - {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae"}, - {file = "msgpack-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6"}, - {file = "msgpack-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661"}, - {file = "msgpack-1.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c"}, - {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0"}, - {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227"}, - {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff"}, - {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd"}, - {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e"}, - {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236"}, - {file = "msgpack-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44"}, - {file = "msgpack-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1"}, - {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d"}, - {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab"}, - {file = "msgpack-1.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb"}, - {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9"}, - {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e"}, - {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1"}, - {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e"}, - {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43"}, - {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243"}, - {file = "msgpack-1.0.4-cp38-cp38-win32.whl", hash = "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2"}, - {file = "msgpack-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6"}, - {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae"}, - {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55"}, - {file = "msgpack-1.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da"}, - {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f"}, - {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92"}, - {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f"}, - {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624"}, - {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8"}, - {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae"}, - {file = "msgpack-1.0.4-cp39-cp39-win32.whl", hash = "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c"}, - {file = "msgpack-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce"}, - {file = "msgpack-1.0.4.tar.gz", hash = "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f"}, -] - [[package]] name = "multidict" -version = "6.0.3" +version = "6.0.4" description = "multidict implementation" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "multidict-6.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:73009ea04205966d47e16d98686ac5c438af23a1bb30b48a2c5da3423ec9ce37"}, - {file = "multidict-6.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b92a9f3ab904397a33b193000dc4de7318ea175c4c460a1e154c415f9008e3d"}, - {file = "multidict-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:578bfcb16f4b8675ef71b960c00f174b0426e0eeb796bab6737389d8288eb827"}, - {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1650ea41c408755da5eed52ac6ccbc8938ccc3e698d81e6f6a1be02ff2a0945"}, - {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d52442e7c951e4c9ee591d6047706e66923d248d83958bbf99b8b19515fffaef"}, - {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad7d66422b9cc51125509229693d27e18c08f2dea3ac9de408d821932b1b3759"}, - {file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cd14e61f0da2a2cfb9fe05bfced2a1ed7063ce46a7a8cd473be4973de9a7f91"}, - {file = "multidict-6.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:190626ced82d4cc567a09e7346340d380154a493bac6905e0095d8158cdf1e38"}, - {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:791458a1f7d1b4ab3bd9e93e0dcd1d59ef7ee9aa051dcd1ea030e62e49b923fd"}, - {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b46e79a9f4db53897d17bc64a39d1c7c2be3e3d4f8dba6d6730a2b13ddf0f986"}, - {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e4a095e18847c12ec20e55326ab8782d9c2d599400a3a2f174fab4796875d0e2"}, - {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fb6c3dc3d65014d2c782f5acf0b3ba14e639c6c33d3ed8932ead76b9080b3544"}, - {file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3541882266247c7cd3dba78d6ef28dbe704774df60c9e4231edaa4493522e614"}, - {file = "multidict-6.0.3-cp310-cp310-win32.whl", hash = "sha256:67090b17a0a5be5704fd109f231ee73cefb1b3802d41288d6378b5df46ae89ba"}, - {file = "multidict-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:36df958b15639e40472adaa4f0c2c7828fe680f894a6b48c4ce229f59a6a798b"}, - {file = "multidict-6.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5b51969503709415a35754954c2763f536a70b8bf7360322b2edb0c0a44391f6"}, - {file = "multidict-6.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:24e8d513bfcaadc1f8b0ebece3ff50961951c54b07d5a775008a882966102418"}, - {file = "multidict-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d325d61cac602976a5d47b19eaa7d04e3daf4efce2164c630219885087234102"}, - {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbbe17f8a7211b623502d2bf41022a51da3025142401417c765bf9a56fed4c"}, - {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4fb3fe591956d8841882c463f934c9f7485cfd5f763a08c0d467b513dc18ef89"}, - {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1925f78a543b94c3d46274c66a366fee8a263747060220ed0188e5f3eeea1c0"}, - {file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e1ce0b187c4e93112304dcde2aa18922fdbe8fb4f13d8aa72a5657bce0563a"}, - {file = "multidict-6.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e07c24018986fb00d6e7eafca8fcd6e05095649e17fcf0e33a592caaa62a78b9"}, - {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:114a4ab3e5cfbc56c4b6697686ecb92376c7e8c56893ef20547921552f8bdf57"}, - {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ccf55f28066b4f08666764a957c2b7c241c7547b0921d69c7ceab5f74fe1a45"}, - {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:9d359b0a962e052b713647ac1f13eabf2263167b149ed1e27d5c579f5c8c7d2c"}, - {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:df7b4cee3ff31b3335aba602f8d70dbc641e5b7164b1e9565570c9d3c536a438"}, - {file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ee9b1cae9a6c5d023e5a150f6f6b9dbb3c3bbc7887d6ee07d4c0ecb49a473734"}, - {file = "multidict-6.0.3-cp311-cp311-win32.whl", hash = "sha256:960ce1b790952916e682093788696ef7e33ac6a97482f9b983abdc293091b531"}, - {file = "multidict-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:2b66d61966b12e6bba500e5cbb2c721a35e119c30ee02495c5629bd0e91eea30"}, - {file = "multidict-6.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:526f8397fc124674b8f39748680a0ff673bd6a715fecb4866716d36e380f015f"}, - {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f5d5129a937af4e3c4a1d6c139f4051b7d17d43276cefdd8d442a7031f7eef2"}, - {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38d394814b39be1c36ac709006d39d50d72a884f9551acd9c8cc1ffae3fc8c4e"}, - {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99341ca1f1db9e7f47914cb2461305665a662383765ced6f843712564766956d"}, - {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5790cc603456b6dcf8a9a4765f666895a6afddc88b3d3ba7b53dea2b6e23116"}, - {file = "multidict-6.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce8e51774eb03844588d3c279adb94efcd0edeccd2f97516623292445bcc01f9"}, - {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:baa96a3418e27d723064854143b2f414a422c84cc87285a71558722049bebc5a"}, - {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:cb4a08f0aaaa869f189ffea0e17b86ad0237b51116d494da15ef7991ee6ad2d7"}, - {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:62db44727d0befea68e8ad2881bb87a9cfb6b87d45dd78609009627167f37b69"}, - {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:4cc5c8cd205a9810d16a5cd428cd81bac554ad1477cb87f4ad722b10992e794d"}, - {file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f76109387e1ec8d8e2137c94c437b89fe002f29e0881aae8ae45529bdff92000"}, - {file = "multidict-6.0.3-cp37-cp37m-win32.whl", hash = "sha256:f8a728511c977df6f3d8af388fcb157e49f11db4a6637dd60131b8b6e40b0253"}, - {file = "multidict-6.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c2a1168e5aa7c72499fb03c850e0f03f624fa4a5c8d2e215c518d0a73872eb64"}, - {file = "multidict-6.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eddf604a3de2ace3d9a4e4d491be7562a1ac095a0a1c95a9ec5781ef0273ef11"}, - {file = "multidict-6.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d09daf5c6ce7fc6ed444c9339bbde5ea84e2534d1ca1cd37b60f365c77f00dea"}, - {file = "multidict-6.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:12e0d396faa6dc55ff5379eee54d1df3b508243ff15bfc8295a6ec7a4483a335"}, - {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70740c2bc9ab1c99f7cdcb104f27d16c63860c56d51c5bf0ef82fc1d892a2131"}, - {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e322c94596054352f5a02771eec71563c018b15699b961aba14d6dd943367022"}, - {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4159fc1ec9ede8ab93382e0d6ba9b1b3d23c72da39a834db7a116986605c7ab4"}, - {file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47defc0218682281a52fb1f6346ebb8b68b17538163a89ea24dfe4da37a8a9a3"}, - {file = "multidict-6.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f9511e48bde6b995825e8d35e434fc96296cf07a25f4aae24ff9162be7eaa46"}, - {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e0bce9f7c30e7e3a9e683f670314c0144e8d34be6b7019e40604763bd278d84f"}, - {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:01b456046a05ff7cceefb0e1d2a9d32f05efcb1c7e0d152446304e11557639ce"}, - {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:8230a39bae6c2e8a09e4da6bace5064693b00590a4a213e38f9a9366da10e7dd"}, - {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:445c0851a1cbc1f2ec3b40bc22f9c4a235edb3c9a0906122a9df6ea8d51f886c"}, - {file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9aac6881454a750554ed4b280a839dcf9e2133a9d12ab4d417d673fb102289b7"}, - {file = "multidict-6.0.3-cp38-cp38-win32.whl", hash = "sha256:81c3d597591b0940e04949e4e4f79359b2d2e542a686ba0da5e25de33fec13e0"}, - {file = "multidict-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:dc4cfef5d899f5f1a15f3d2ac49f71107a01a5a2745b4dd53fa0cede1419385a"}, - {file = "multidict-6.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d408172519049e36fb6d29672f060dc8461fc7174eba9883c7026041ef9bfb38"}, - {file = "multidict-6.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e068dfeadbce63072b2d8096486713d04db4946aad0a0f849bd4fc300799d0d3"}, - {file = "multidict-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8b817d4ed68fd568ec5e45dd75ddf30cc72a47a6b41b74d5bb211374c296f5e"}, - {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cf5d19e12eff855aa198259c0b02fd3f5d07e1291fbd20279c37b3b0e6c9852"}, - {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5a811aab1b4aea0b4be669363c19847a8c547510f0e18fb632956369fdbdf67"}, - {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2cfda34b7cb99eacada2072e0f69c0ad3285cb6f8e480b11f2b6d6c1c6f92718"}, - {file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beeca903e4270b4afcd114f371a9602240dc143f9e944edfea00f8d4ad56c40d"}, - {file = "multidict-6.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd5771e8ea325f85cbb361ddbdeb9ae424a68e5dfb6eea786afdcd22e68a7d5d"}, - {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9dbab2a7e9c073bc9538824a01f5ed689194db7f55f2b8102766873e906a6c1a"}, - {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f2c0957b3e8c66c10d27272709a5299ab3670a0f187c9428f3b90d267119aedb"}, - {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:94cbe5535ef150546b8321aebea22862a3284da51e7b55f6f95b7d73e96d90ee"}, - {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d0e798b072cf2aab9daceb43d97c9c527a0c7593e67a7846ad4cc6051de1e303"}, - {file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a27b029caa3b555a4f3da54bc1e718eb55fcf1a11fda8bf0132147b476cf4c08"}, - {file = "multidict-6.0.3-cp39-cp39-win32.whl", hash = "sha256:018c8e3be7f161a12b3e41741b6721f9baeb2210f4ab25a6359b7d76c1017dce"}, - {file = "multidict-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:5e58ec0375803526d395f6f7e730ecc45d06e15f68f7b9cdbf644a2918324e51"}, - {file = "multidict-6.0.3.tar.gz", hash = "sha256:2523a29006c034687eccd3ee70093a697129a3ffe8732535d3b2df6a4ecc279d"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, + {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, + {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, + {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, + {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, + {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, + {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, + {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, + {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, + {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, + {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, + {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, + {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, ] [[package]] @@ -1555,7 +1078,7 @@ setuptools = "*" name = "packaging" version = "22.0" description = "Core utilities for Python packages" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1563,63 +1086,24 @@ files = [ {file = "packaging-22.0.tar.gz", hash = "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3"}, ] -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pkginfo" -version = "1.9.2" -description = "Query metadatdata from sdists / bdists / installed packages." -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkginfo-1.9.2-py3-none-any.whl", hash = "sha256:d580059503f2f4549ad6e4c106d7437356dbd430e2c7df99ee1efe03d75f691e"}, - {file = "pkginfo-1.9.2.tar.gz", hash = "sha256:ac03e37e4d601aaee40f8087f63fc4a2a6c9814dda2c8fa6aab1b1829653bdfa"}, -] - -[package.extras] -testing = ["pytest", "pytest-cov"] - -[[package]] -name = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, -] - [[package]] name = "platformdirs" -version = "2.6.0" +version = "2.6.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-2.6.0-py3-none-any.whl", hash = "sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca"}, - {file = "platformdirs-2.6.0.tar.gz", hash = "sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e"}, + {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, + {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} + [package.extras] -docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] -test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -1640,90 +1124,16 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "poetry" -version = "1.3.1" -description = "Python dependency management and packaging made easy." -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry-1.3.1-py3-none-any.whl", hash = "sha256:e8c24984af3e124ef31a5891c1c11871c948687368ee451e95f7f101ffbf8204"}, - {file = "poetry-1.3.1.tar.gz", hash = "sha256:fde98462ad5dc9879393157da93092206a3411117e25a4761a41c6d08f31aea8"}, -] - -[package.dependencies] -"backports.cached-property" = {version = ">=1.0.2,<2.0.0", markers = "python_version < \"3.8\""} -cachecontrol = {version = ">=0.12.9,<0.13.0", extras = ["filecache"]} -cleo = ">=2.0.0,<3.0.0" -crashtest = ">=0.4.1,<0.5.0" -dulwich = ">=0.20.46,<0.21.0" -filelock = ">=3.8.0,<4.0.0" -html5lib = ">=1.0,<2.0" -importlib-metadata = {version = ">=4.4,<5.0", markers = "python_version < \"3.10\""} -jsonschema = ">=4.10.0,<5.0.0" -keyring = ">=23.9.0,<24.0.0" -lockfile = ">=0.12.2,<0.13.0" -packaging = ">=20.4" -pexpect = ">=4.7.0,<5.0.0" -pkginfo = ">=1.5,<2.0" -platformdirs = ">=2.5.2,<3.0.0" -poetry-core = "1.4.0" -poetry-plugin-export = ">=1.2.0,<2.0.0" -requests = ">=2.18,<3.0" -requests-toolbelt = ">=0.9.1,<0.11.0" -shellingham = ">=1.5,<2.0" -tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""} -tomlkit = ">=0.11.1,<0.11.2 || >0.11.2,<0.11.3 || >0.11.3,<1.0.0" -trove-classifiers = ">=2022.5.19" -urllib3 = ">=1.26.0,<2.0.0" -virtualenv = [ - {version = ">=20.4.3,<20.4.5 || >20.4.5,<20.4.6 || >20.4.6,<21.0.0", markers = "sys_platform != \"win32\" or python_version != \"3.9\""}, - {version = ">=20.4.3,<20.4.5 || >20.4.5,<20.4.6 || >20.4.6,<20.16.6", markers = "sys_platform == \"win32\" and python_version == \"3.9\""}, -] -xattr = {version = ">=0.10.0,<0.11.0", markers = "sys_platform == \"darwin\""} - -[[package]] -name = "poetry-core" -version = "1.4.0" -description = "Poetry PEP 517 Build Backend" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry_core-1.4.0-py3-none-any.whl", hash = "sha256:5559ab80384ac021db329ef317086417e140ee1176bcfcb3a3838b544e213c8e"}, - {file = "poetry_core-1.4.0.tar.gz", hash = "sha256:514bd33c30e0bf56b0ed44ee15e120d7e47b61ad908b2b1011da68c48a84ada9"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} - -[[package]] -name = "poetry-plugin-export" -version = "1.2.0" -description = "Poetry plugin to export the dependencies to various formats" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry_plugin_export-1.2.0-py3-none-any.whl", hash = "sha256:109fb43ebfd0e79d8be2e7f9d43ba2ae357c4975a18dfc0cfdd9597dd086790e"}, - {file = "poetry_plugin_export-1.2.0.tar.gz", hash = "sha256:9a1dd42765408931d7831738749022651d43a2968b67c988db1b7a567dfe41ef"}, -] - -[package.dependencies] -poetry = ">=1.2.2,<2.0.0" -poetry-core = ">=1.3.0,<2.0.0" - [[package]] name = "pre-commit" -version = "2.20.0" +version = "2.21.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pre_commit-2.20.0-py2.py3-none-any.whl", hash = "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7"}, - {file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"}, + {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"}, + {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, ] [package.dependencies] @@ -1732,20 +1142,7 @@ identify = ">=1.0.0" importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} nodeenv = ">=0.11.1" pyyaml = ">=5.1" -toml = "*" -virtualenv = ">=20.0.8" - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] +virtualenv = ">=20.10.0" [[package]] name = "py" @@ -1771,62 +1168,50 @@ files = [ {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, ] -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] - [[package]] name = "pydantic" -version = "1.10.2" +version = "1.10.3" description = "Data validation and settings management using python type hints" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"}, - {file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"}, - {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"}, - {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559"}, - {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"}, - {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c"}, - {file = "pydantic-1.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644"}, - {file = "pydantic-1.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f"}, - {file = "pydantic-1.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a"}, - {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525"}, - {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283"}, - {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42"}, - {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52"}, - {file = "pydantic-1.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c"}, - {file = "pydantic-1.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5"}, - {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c"}, - {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254"}, - {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5"}, - {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d"}, - {file = "pydantic-1.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2"}, - {file = "pydantic-1.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13"}, - {file = "pydantic-1.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116"}, - {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624"}, - {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1"}, - {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9"}, - {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965"}, - {file = "pydantic-1.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e"}, - {file = "pydantic-1.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488"}, - {file = "pydantic-1.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41"}, - {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b"}, - {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe"}, - {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d"}, - {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda"}, - {file = "pydantic-1.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6"}, - {file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"}, - {file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"}, + {file = "pydantic-1.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef012251ca6bc899f0b5a9239c527dec30915462f35c3a58aab6ddff09708484"}, + {file = "pydantic-1.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:810e1510da10bc6c59300221ba55e17cfb7b62279fe87c6466f9e293975a6dd5"}, + {file = "pydantic-1.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a83e92f7311c703fb1d64dba81d1e374786465a4e260b0616f731401e1f875a8"}, + {file = "pydantic-1.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4efd2e1f63cdd0877e24ca5d5edd7dc65a24b915da04e67b1fe485a0f7f3508"}, + {file = "pydantic-1.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d15d22b5d666b7b610d9a99a73de6b27be8982ee3af4de0cb32586ee72557f25"}, + {file = "pydantic-1.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d29e5353593117937901a6329c7295955eacbf4856a0c01da5319f416ad18967"}, + {file = "pydantic-1.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:106302e18978c22c51b013d347db6ef5589776137663b16dc77ea3162bc82711"}, + {file = "pydantic-1.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85e48eb95c39a5fd4500d148e8330d878fafe9e3eca6c253bdf0bd0af2b71371"}, + {file = "pydantic-1.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9862e881689e1c067c11b307513465e6509647f9f10e3c48d100120351449087"}, + {file = "pydantic-1.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21cca3b77f9a7a69f51991e26780427396226a5a576c72635e25b8439dd0170"}, + {file = "pydantic-1.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df2fa7102d1bec588d360833777d47772ce7f6aecc0335be43de710a8d034f42"}, + {file = "pydantic-1.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f7eb71ad9fb1f6911ca2b7010039a9d61a3f14bd4f60a1c57e9250f8d87375fb"}, + {file = "pydantic-1.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:762a6560e6d31d0a5558ee95cdece616dd6d92c94e3a9a41fb46f2d733a66f49"}, + {file = "pydantic-1.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:38dc429316685a3b13ca008c907e2cc9e164068e49612b5284d7cbb01504c3a3"}, + {file = "pydantic-1.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:000a7d934e182f6e368340382338dea5423b0503a3a5cafd3f2b75e684fe67f2"}, + {file = "pydantic-1.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec151222823911a72aeb3c855947fe10b31e718484b233eb7d2d98a5df3d3c7b"}, + {file = "pydantic-1.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a63805997d1ab9082c2c89017d3368369689660a35a7d8a8fccb67f77d5cf4d8"}, + {file = "pydantic-1.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5fa3374562b3d4ea45bdff711c01854e5ce6c9ca9e2f37a6e94313412249000e"}, + {file = "pydantic-1.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bf121ec413f943803e9401fae0e58898bf9e68a97bdd9eea4d055499936a2e75"}, + {file = "pydantic-1.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:e580ec5dcb7ff6861ef2de3b7c8a9af4112691bebd392221ed70de57fe846ae9"}, + {file = "pydantic-1.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:495ad4077575e2629f775a7635c4f383d279b3de2439880b76ce27758db98902"}, + {file = "pydantic-1.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cf20586026691c7aa59f0372488a75699194ab6ff7142577d585272b45e12ba"}, + {file = "pydantic-1.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f918f2dcd740ac3b2603a1a8bf091a151385a31d02fac5903a2bbf2336d2025"}, + {file = "pydantic-1.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddcec93519cb0ea63d0d7e8462042b46191020f862b88302815586707f4e8acc"}, + {file = "pydantic-1.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3701a2971a8d0c7274b28a2d3fa9146390a51e7ffda4bc2406d10fda64d6f727"}, + {file = "pydantic-1.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e8b895bf2faf61dba6ab9990e01e99d0b96e3d6a23e810d85060a51fbc27e1dc"}, + {file = "pydantic-1.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:85bbea6c5b9bbd07532a875ab09a6d4987d89eb5566c6b8d2cc60f2dcdec5300"}, + {file = "pydantic-1.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0627a759a14dc47cdca10e3590c86df368d96b46b23db44c986286656007d253"}, + {file = "pydantic-1.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9197d3f22eefa113bcb0564cfc5812ccf889aaff08a6459c9ed04796b8f88c14"}, + {file = "pydantic-1.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aef6dc6b7c6ae2dea27eea5fde6b5c766397a6c765c19414713dbc832a245d"}, + {file = "pydantic-1.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac2a986c200c1739ce1a358d545f133d3a50b896c88c0c02a35c661120d85692"}, + {file = "pydantic-1.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9ee33436a271e46ed3be422cb23f8c75c2dce53abf7259b7dd173ed1b7cabb66"}, + {file = "pydantic-1.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e7c2d9ffca1124e751db9ae529968dbbcefd0b8db69ce958bb7cf777716e7b8"}, + {file = "pydantic-1.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:6804f70ebf7e1d37bf8e0d0baf2bee20e3b07229b600db4c46eddd5f3738308a"}, + {file = "pydantic-1.10.3-py3-none-any.whl", hash = "sha256:c50085e5ebd9da2e7d67353969185f6a6c190ed4142f93a46aa294c8213c466a"}, + {file = "pydantic-1.10.3.tar.gz", hash = "sha256:01d450f1b6a642c98f58630e807f7554df0a8ce669ffaff087ce9e1fd4ff7ec8"}, ] [package.dependencies] @@ -1909,43 +1294,6 @@ tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "p toml = ["toml (>=0.10.2)"] vulture = ["vulture"] -[[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, - {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, - {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, - {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, - {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, - {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, -] - [[package]] name = "pytest" version = "7.2.0" @@ -2065,18 +1413,6 @@ files = [ {file = "pytz-2022.7.tar.gz", hash = "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a"}, ] -[[package]] -name = "pywin32-ctypes" -version = "0.2.0" -description = "" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, - {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, -] - [[package]] name = "pyyaml" version = "6.0" @@ -2127,108 +1463,6 @@ files = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] -[[package]] -name = "rapidfuzz" -version = "2.13.7" -description = "rapid fuzzy string matching" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b75dd0928ce8e216f88660ab3d5c5ffe990f4dd682fd1709dba29d5dafdde6de"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24d3fea10680d085fd0a4d76e581bfb2b1074e66e78fd5964d4559e1fcd2a2d4"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8109e0324d21993d5b2d111742bf5958f3516bf8c59f297c5d1cc25a2342eb66"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f705652360d520c2de52bee11100c92f59b3e3daca308ebb150cbc58aecdad"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7496e8779905b02abc0ab4ba2a848e802ab99a6e20756ffc967a0de4900bd3da"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24eb6b843492bdc63c79ee4b2f104059b7a2201fef17f25177f585d3be03405a"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:467c1505362823a5af12b10234cb1c4771ccf124c00e3fc9a43696512bd52293"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53dcae85956853b787c27c1cb06f18bb450e22cf57a4ad3444cf03b8ff31724a"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46b9b8aa09998bc48dd800854e8d9b74bc534d7922c1d6e1bbf783e7fa6ac29c"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1fbad8fb28d98980f5bff33c7842efef0315d42f0cd59082108482a7e6b61410"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:43fb8cb030f888c3f076d40d428ed5eb4331f5dd6cf1796cfa39c67bf0f0fc1e"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b6bad92de071cbffa2acd4239c1779f66851b60ffbbda0e4f4e8a2e9b17e7eef"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d00df2e4a81ffa56a6b1ec4d2bc29afdcb7f565e0b8cd3092fece2290c4c7a79"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-win32.whl", hash = "sha256:2c836f0f2d33d4614c3fbaf9a1eb5407c0fe23f8876f47fd15b90f78daa64c34"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-win_amd64.whl", hash = "sha256:c36fd260084bb636b9400bb92016c6bd81fd80e59ed47f2466f85eda1fc9f782"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b34e8c0e492949ecdd5da46a1cfc856a342e2f0389b379b1a45a3cdcd3176a6e"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:875d51b3497439a72e2d76183e1cb5468f3f979ab2ddfc1d1f7dde3b1ecfb42f"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae33a72336059213996fe4baca4e0e4860913905c2efb7c991eab33b95a98a0a"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5585189b3d90d81ccd62d4f18530d5ac8972021f0aaaa1ffc6af387ff1dce75"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42085d4b154a8232767de8296ac39c8af5bccee6b823b0507de35f51c9cbc2d7"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:585206112c294e335d84de5d5f179c0f932837752d7420e3de21db7fdc476278"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f891b98f8bc6c9d521785816085e9657212621e93f223917fb8e32f318b2957e"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08590905a95ccfa43f4df353dcc5d28c15d70664299c64abcad8721d89adce4f"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b5dd713a1734574c2850c566ac4286594bacbc2d60b9170b795bee4b68656625"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:988f8f6abfba7ee79449f8b50687c174733b079521c3cc121d65ad2d38831846"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b3210869161a864f3831635bb13d24f4708c0aa7208ef5baac1ac4d46e9b4208"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f6fe570e20e293eb50491ae14ddeef71a6a7e5f59d7e791393ffa99b13f1f8c2"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6120f2995f5154057454c5de99d86b4ef3b38397899b5da1265467e8980b2f60"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-win32.whl", hash = "sha256:b20141fa6cee041917801de0bab503447196d372d4c7ee9a03721b0a8edf5337"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-win_amd64.whl", hash = "sha256:ec55a81ac2b0f41b8d6fb29aad16e55417036c7563bad5568686931aa4ff08f7"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d005e058d86f2a968a8d28ca6f2052fab1f124a39035aa0523261d6baf21e1f"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe59a0c21a032024edb0c8e43f5dee5623fef0b65a1e3c1281836d9ce199af3b"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfc04f7647c29fb48da7a04082c34cdb16f878d3c6d098d62d5715c0ad3000c"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68a89bb06d5a331511961f4d3fa7606f8e21237467ba9997cae6f67a1c2c2b9e"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:effe182767d102cb65dfbbf74192237dbd22d4191928d59415aa7d7c861d8c88"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25b4cedf2aa19fb7212894ce5f5219010cce611b60350e9a0a4d492122e7b351"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3a9bd02e1679c0fd2ecf69b72d0652dbe2a9844eaf04a36ddf4adfbd70010e95"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5e2b3d020219baa75f82a4e24b7c8adcb598c62f0e54e763c39361a9e5bad510"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:cf62dacb3f9234f3fddd74e178e6d25c68f2067fde765f1d95f87b1381248f58"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:fa263135b892686e11d5b84f6a1892523123a00b7e5882eff4fbdabb38667347"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa4c598ed77f74ec973247ca776341200b0f93ec3883e34c222907ce72cb92a4"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-win32.whl", hash = "sha256:c2523f8180ebd9796c18d809e9a19075a1060b1a170fde3799e83db940c1b6d5"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-win_amd64.whl", hash = "sha256:5ada0a14c67452358c1ee52ad14b80517a87b944897aaec3e875279371a9cb96"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ca8a23097c1f50e0fdb4de9e427537ca122a18df2eead06ed39c3a0bef6d9d3a"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9be02162af0376d64b840f2fc8ee3366794fc149f1e06d095a6a1d42447d97c5"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af4f7c3c904ca709493eb66ca9080b44190c38e9ecb3b48b96d38825d5672559"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f50d1227e6e2a0e3ae1fb1c9a2e1c59577d3051af72c7cab2bcc430cb5e18da"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c71d9d512b76f05fa00282227c2ae884abb60e09f08b5ca3132b7e7431ac7f0d"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b52ac2626945cd21a2487aeefed794c14ee31514c8ae69b7599170418211e6f6"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca00fafd2756bc9649bf80f1cf72c647dce38635f0695d7ce804bc0f759aa756"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d248a109699ce9992304e79c1f8735c82cc4c1386cd8e27027329c0549f248a2"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c88adbcb933f6b8612f6c593384bf824e562bb35fc8a0f55fac690ab5b3486e5"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8601a66fbfc0052bb7860d2eacd303fcde3c14e87fdde409eceff516d659e77"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:27be9c63215d302ede7d654142a2e21f0d34ea6acba512a4ae4cfd52bbaa5b59"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3dcffe1f3cbda0dc32133a2ae2255526561ca594f15f9644384549037b355245"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8450d15f7765482e86ef9be2ad1a05683cd826f59ad236ef7b9fb606464a56aa"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-win32.whl", hash = "sha256:460853983ab88f873173e27cc601c5276d469388e6ad6e08c4fd57b2a86f1064"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-win_amd64.whl", hash = "sha256:424f82c35dbe4f83bdc3b490d7d696a1dc6423b3d911460f5493b7ffae999fd2"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c3fbe449d869ea4d0909fc9d862007fb39a584fb0b73349a6aab336f0d90eaed"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16080c05a63d6042643ae9b6cfec1aefd3e61cef53d0abe0df3069b9d4b72077"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dbcf5371ea704759fcce772c66a07647751d1f5dbdec7818331c9b31ae996c77"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:114810491efb25464016fd554fdf1e20d390309cecef62587494fc474d4b926f"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99a84ab9ac9a823e7e93b4414f86344052a5f3e23b23aa365cda01393ad895bd"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81642a24798851b118f82884205fc1bd9ff70b655c04018c467824b6ecc1fabc"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3741cb0bf9794783028e8b0cf23dab917fa5e37a6093b94c4c2f805f8e36b9f"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:759a3361711586a29bc753d3d1bdb862983bd9b9f37fbd7f6216c24f7c972554"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1333fb3d603d6b1040e365dca4892ba72c7e896df77a54eae27dc07db90906e3"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:916bc2e6cf492c77ad6deb7bcd088f0ce9c607aaeabc543edeb703e1fbc43e31"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:23524635840500ce6f4d25005c9529a97621689c85d2f727c52eed1782839a6a"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:ebe303cd9839af69dd1f7942acaa80b1ba90bacef2e7ded9347fbed4f1654672"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fe56659ccadbee97908132135de4b875543353351e0c92e736b7c57aee298b5a"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-win32.whl", hash = "sha256:3f11a7eff7bc6301cd6a5d43f309e22a815af07e1f08eeb2182892fca04c86cb"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-win_amd64.whl", hash = "sha256:e8914dad106dacb0775718e54bf15e528055c4e92fb2677842996f2d52da5069"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f7930adf84301797c3f09c94b9c5a9ed90a9e8b8ed19b41d2384937e0f9f5bd"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c31022d9970177f6affc6d5dd757ed22e44a10890212032fabab903fdee3bfe7"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f42b82f268689f429def9ecfb86fa65ceea0eaf3fed408b570fe113311bf5ce7"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b477b43ced896301665183a5e0faec0f5aea2373005648da8bdcb3c4b73f280"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d63def9bbc6b35aef4d76dc740301a4185867e8870cbb8719ec9de672212fca8"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c66546e30addb04a16cd864f10f5821272a1bfe6462ee5605613b4f1cb6f7b48"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f799d1d6c33d81e983d3682571cc7d993ae7ff772c19b3aabb767039c33f6d1e"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d82f20c0060ffdaadaf642b88ab0aa52365b56dffae812e188e5bdb998043588"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:042644133244bfa7b20de635d500eb9f46af7097f3d90b1724f94866f17cb55e"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75c45dcd595f8178412367e302fd022860ea025dc4a78b197b35428081ed33d5"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3d8b081988d0a49c486e4e845a547565fee7c6e7ad8be57ff29c3d7c14c6894c"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16ffad751f43ab61001187b3fb4a9447ec2d1aedeff7c5bac86d3b95f9980cc3"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:020858dd89b60ce38811cd6e37875c4c3c8d7fcd8bc20a0ad2ed1f464b34dc4e"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cda1e2f66bb4ba7261a0f4c2d052d5d909798fca557cbff68f8a79a87d66a18f"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b6389c50d8d214c9cd11a77f6d501529cb23279a9c9cafe519a3a4b503b5f72a"}, - {file = "rapidfuzz-2.13.7.tar.gz", hash = "sha256:8d3e252d4127c79b4d7c2ae47271636cbaca905c8bb46d80c7930ab906cf4b5c"}, -] - -[package.extras] -full = ["numpy"] - [[package]] name = "raven" version = "6.10.0" @@ -2249,7 +1483,7 @@ tests = ["Flask (>=0.8)", "Flask-Login (>=0.2.0)", "ZConfig", "aiohttp", "anyjso name = "requests" version = "2.28.1" description = "Python HTTP for Humans." -category = "main" +category = "dev" optional = false python-versions = ">=3.7, <4" files = [ @@ -2267,21 +1501,6 @@ urllib3 = ">=1.21.1,<1.27" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "requests-toolbelt" -version = "0.10.1" -description = "A utility belt for advanced users of python-requests" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-0.10.1.tar.gz", hash = "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d"}, - {file = "requests_toolbelt-0.10.1-py2.py3-none-any.whl", hash = "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - [[package]] name = "rich" version = "12.6.0" @@ -2302,22 +1521,6 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] -[[package]] -name = "secretstorage" -version = "3.3.3" -description = "Python bindings to FreeDesktop.org Secret Service API" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, - {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, -] - -[package.dependencies] -cryptography = ">=2.0" -jeepney = ">=0.6" - [[package]] name = "setproctitle" version = "1.3.2" @@ -2420,23 +1623,11 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] -[[package]] -name = "shellingham" -version = "1.5.0" -description = "Tool to Detect Surrounding Shell" -category = "main" -optional = false -python-versions = ">=3.4" -files = [ - {file = "shellingham-1.5.0-py2.py3-none-any.whl", hash = "sha256:a8f02ba61b69baaa13facdba62908ca8690a94b8119b69f5ec5873ea85f7391b"}, - {file = "shellingham-1.5.0.tar.gz", hash = "sha256:72fb7f5c63103ca2cb91b23dee0c71fe8ad6fbfd46418ef17dbe40db51592dad"}, -] - [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2700,23 +1891,11 @@ files = [ {file = "timeout-decorator-0.5.0.tar.gz", hash = "sha256:6a2f2f58db1c5b24a2cc79de6345760377ad8bdc13813f5265f6c3e63d16b3d7"}, ] -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2724,18 +1903,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "tomlkit" -version = "0.11.6" -description = "Style preserving TOML library" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, - {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, -] - [[package]] name = "tornado" version = "6.2" @@ -2757,18 +1924,6 @@ files = [ {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, ] -[[package]] -name = "trove-classifiers" -version = "2022.12.22" -description = "Canonical source for classifiers on PyPI (pypi.org)." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "trove-classifiers-2022.12.22.tar.gz", hash = "sha256:fe0fe3f085987161aee2a5a853c7cc7cdf64515c5965d57ad968fdd8cc3b0362"}, - {file = "trove_classifiers-2022.12.22-py3-none-any.whl", hash = "sha256:f0013fd4ce06cfae879a2580ab6acc3d51ec93ecb364d6c061b6c77b44dd72de"}, -] - [[package]] name = "typed-ast" version = "1.5.4" @@ -2831,7 +1986,7 @@ files = [ name = "typing-extensions" version = "4.4.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2843,7 +1998,7 @@ files = [ name = "urllib3" version = "1.26.13" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -2901,32 +2056,11 @@ dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flak docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] -[[package]] -name = "virtualenv" -version = "20.16.5" -description = "Virtual Python Environment builder" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "virtualenv-20.16.5-py3-none-any.whl", hash = "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27"}, - {file = "virtualenv-20.16.5.tar.gz", hash = "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da"}, -] - -[package.dependencies] -distlib = ">=0.3.5,<1" -filelock = ">=3.4.1,<4" -platformdirs = ">=2.4,<3" - -[package.extras] -docs = ["proselint (>=0.13)", "sphinx (>=5.1.1)", "sphinx-argparse (>=0.3.1)", "sphinx-rtd-theme (>=1)", "towncrier (>=21.9)"] -testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] - [[package]] name = "virtualenv" version = "20.17.1" description = "Virtual Python Environment builder" -category = "main" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2960,18 +2094,6 @@ files = [ docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] testing = ["coverage (>=5.0)", "pytest", "pytest-cover"] -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - [[package]] name = "webob" version = "1.8.7" @@ -3009,91 +2131,6 @@ WebOb = ">=1.2" docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.8)"] tests = ["PasteDeploy", "WSGIProxy2", "coverage", "pyquery", "pytest", "pytest-cov"] -[[package]] -name = "xattr" -version = "0.10.1" -description = "Python wrapper for extended filesystem attributes" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "xattr-0.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:16a660a883e703b311d1bbbcafc74fa877585ec081cd96e8dd9302c028408ab1"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1e2973e72faa87ca29d61c23b58c3c89fe102d1b68e091848b0e21a104123503"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:13279fe8f7982e3cdb0e088d5cb340ce9cbe5ef92504b1fd80a0d3591d662f68"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1dc9b9f580ef4b8ac5e2c04c16b4d5086a611889ac14ecb2e7e87170623a0b75"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:485539262c2b1f5acd6b6ea56e0da2bc281a51f74335c351ea609c23d82c9a79"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:295b3ab335fcd06ca0a9114439b34120968732e3f5e9d16f456d5ec4fa47a0a2"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a126eb38e14a2f273d584a692fe36cff760395bf7fc061ef059224efdb4eb62c"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:b0e919c24f5b74428afa91507b15e7d2ef63aba98e704ad13d33bed1288dca81"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:e31d062cfe1aaeab6ba3db6bd255f012d105271018e647645941d6609376af18"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:209fb84c09b41c2e4cf16dd2f481bb4a6e2e81f659a47a60091b9bcb2e388840"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c4120090dac33eddffc27e487f9c8f16b29ff3f3f8bcb2251b2c6c3f974ca1e1"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e739d624491267ec5bb740f4eada93491de429d38d2fcdfb97b25efe1288eca"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2677d40b95636f3482bdaf64ed9138fb4d8376fb7933f434614744780e46e42d"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40039f1532c4456fd0f4c54e9d4e01eb8201248c321c6c6856262d87e9a99593"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:148466e5bb168aba98f80850cf976e931469a3c6eb11e9880d9f6f8b1e66bd06"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0aedf55b116beb6427e6f7958ccd80a8cbc80e82f87a4cd975ccb61a8d27b2ee"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c3024a9ff157247c8190dd0eb54db4a64277f21361b2f756319d9d3cf20e475f"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f1be6e733e9698f645dbb98565bb8df9b75e80e15a21eb52787d7d96800e823b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7880c8a54c18bc091a4ce0adc5c6d81da1c748aec2fe7ac586d204d6ec7eca5b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:89c93b42c3ba8aedbc29da759f152731196c2492a2154371c0aae3ef8ba8301b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b905e808df61b677eb972f915f8a751960284358b520d0601c8cbc476ba2df6"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ef954d0655f93a34d07d0cc7e02765ec779ff0b59dc898ee08c6326ad614d5"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:199b20301b6acc9022661412346714ce764d322068ef387c4de38062474db76c"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0956a8ab0f0d3f9011ba480f1e1271b703d11542375ef73eb8695a6bd4b78b"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffcb57ca1be338d69edad93cf59aac7c6bb4dbb92fd7bf8d456c69ea42f7e6d2"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f0563196ee54756fe2047627d316977dc77d11acd7a07970336e1a711e934db"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc354f086f926a1c7f04886f97880fed1a26d20e3bc338d0d965fd161dbdb8ab"}, - {file = "xattr-0.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c0cd2d02ef2fb45ecf2b0da066a58472d54682c6d4f0452dfe7ae2f3a76a42ea"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49626096ddd72dcc1654aadd84b103577d8424f26524a48d199847b5d55612d0"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceaa26bef8fcb17eb59d92a7481c2d15d20211e217772fb43c08c859b01afc6a"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c014c371391f28f8cd27d73ea59f42b30772cd640b5a2538ad4f440fd9190b"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:46c32cd605673606b9388a313b0050ee7877a0640d7561eea243ace4fa2cc5a6"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:772b22c4ff791fe5816a7c2a1c9fcba83f9ab9bea138eb44d4d70f34676232b4"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:183ad611a2d70b5a3f5f7aadef0fcef604ea33dcf508228765fd4ddac2c7321d"}, - {file = "xattr-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8068df3ebdfa9411e58d5ae4a05d807ec5994645bb01af66ec9f6da718b65c5b"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bc40570155beb85e963ae45300a530223d9822edfdf09991b880e69625ba38a"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:436e1aaf23c07e15bed63115f1712d2097e207214fc6bcde147c1efede37e2c5"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7298455ccf3a922d403339781b10299b858bb5ec76435445f2da46fb768e31a5"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:986c2305c6c1a08f78611eb38ef9f1f47682774ce954efb5a4f3715e8da00d5f"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5dc6099e76e33fa3082a905fe59df766b196534c705cf7a2e3ad9bed2b8a180e"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:042ad818cda6013162c0bfd3816f6b74b7700e73c908cde6768da824686885f8"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d4c306828a45b41b76ca17adc26ac3dc00a80e01a5ba85d71df2a3e948828f2"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a606280b0c9071ef52572434ecd3648407b20df3d27af02c6592e84486b05894"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5b49d591cf34cda2079fd7a5cb2a7a1519f54dc2e62abe3e0720036f6ed41a85"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8705ac6791426559c1a5c2b88bb2f0e83dc5616a09b4500899bfff6a929302"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5ea974930e876bc5c146f54ac0f85bb39b7b5de2b6fc63f90364712ae368ebe"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f55a2dd73a12a1ae5113c5d9cd4b4ab6bf7950f4d76d0a1a0c0c4264d50da61d"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:475c38da0d3614cc5564467c4efece1e38bd0705a4dbecf8deeb0564a86fb010"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:925284a4a28e369459b2b7481ea22840eed3e0573a4a4c06b6b0614ecd27d0a7"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa32f1b45fed9122bed911de0fcc654da349e1f04fa4a9c8ef9b53e1cc98b91e"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c5d3d0e728bace64b74c475eb4da6148cd172b2d23021a1dcd055d92f17619ac"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8faaacf311e2b5cc67c030c999167a78a9906073e6abf08eaa8cf05b0416515c"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc6b8d5ca452674e1a96e246a3d2db5f477aecbc7c945c73f890f56323e75203"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3725746a6502f40f72ef27e0c7bfc31052a239503ff3eefa807d6b02a249be22"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789bd406d1aad6735e97b20c6d6a1701e1c0661136be9be862e6a04564da771f"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a7a807ab538210ff8532220d8fc5e2d51c212681f63dbd4e7ede32543b070f"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e5825b5fc99ecdd493b0cc09ec35391e7a451394fdf623a88b24726011c950d"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80638d1ce7189dc52f26c234cee3522f060fadab6a8bc3562fe0ddcbe11ba5a4"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3ff0dbe4a6ce2ce065c6de08f415bcb270ecfd7bf1655a633ddeac695ce8b250"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5267e5f9435c840d2674194150b511bef929fa7d3bc942a4a75b9eddef18d8d8"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b27dfc13b193cb290d5d9e62f806bb9a99b00cd73bb6370d556116ad7bb5dc12"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:636ebdde0277bce4d12d2ef2550885804834418fee0eb456b69be928e604ecc4"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d60c27922ec80310b45574351f71e0dd3a139c5295e8f8b19d19c0010196544f"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b34df5aad035d0343bd740a95ca30db99b776e2630dca9cc1ba8e682c9cc25ea"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f24a7c04ff666d0fe905dfee0a84bc899d624aeb6dccd1ea86b5c347f15c20c1"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3878e1aff8eca64badad8f6d896cb98c52984b1e9cd9668a3ab70294d1ef92d"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4abef557028c551d59cf2fb3bf63f2a0c89f00d77e54c1c15282ecdd56943496"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e14bd5965d3db173d6983abdc1241c22219385c22df8b0eb8f1846c15ce1fee"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9be588a4b6043b03777d50654c6079af3da60cc37527dbb80d36ec98842b1e"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bc4ae264aa679aacf964abf3ea88e147eb4a22aea6af8c6d03ebdebd64cfd6"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:827b5a97673b9997067fde383a7f7dc67342403093b94ea3c24ae0f4f1fec649"}, - {file = "xattr-0.10.1.tar.gz", hash = "sha256:c12e7d81ffaa0605b3ac8c22c2994a8e18a9cf1c59287a1b7722a2289c952ec5"}, -] - -[package.dependencies] -cffi = ">=1.0" - [[package]] name = "yarl" version = "1.8.2" @@ -3187,7 +2224,7 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} name = "zipp" version = "3.11.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3211,4 +2248,4 @@ uvloop = [] [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "098f0b6b51ca17e933a156a48d09385b67139302ac3a355897d264a773be7c70" +content-hash = "66f7693da6c5fadd973d50b2d381906ff979d1781e560713d7d27819dce04333" diff --git a/pyproject.toml b/pyproject.toml index 85e722d7..9df11818 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,6 @@ packages = [ python = "^3.7" colorlog = "^6.0" logging-journald = [{ version = '*', platform = 'linux' }] -poetry = "^1.3.1" [tool.poetry.group.dev.dependencies] aiocontextvars = "0.2.2" From 75aa742d5abf2e81b517d0e247adf49cced11daf Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 29 Dec 2022 15:54:13 +0300 Subject: [PATCH 35/45] rework how to develop article --- docs/source/index.rst | 11 ++-- docs/source/locale/ru/LC_MESSAGES/index.po | 59 +++++++++++++--------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 73976a10..4b602a32 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -313,17 +313,20 @@ which takes the number of commits between tag to the head of branch. How to develop? --------------- +This project, like most open source projects, is developed by enthusiasts, +you can join the development, submit issues, or send your merge requests. + +In order to start developing in this repository, you need to do the +following things. + Should be installed: -* ``virtualenv`` -* GNU Make as ``make`` * Python 3.7+ as ``python3`` * Installed Poetry_ as ``poetry`` .. _Poetry: https://python-poetry.org/docs/ - -For setting up developer environment just type +For setting up developer environment just execute: .. code-block:: diff --git a/docs/source/locale/ru/LC_MESSAGES/index.po b/docs/source/locale/ru/LC_MESSAGES/index.po index bffa4f5e..8af057e7 100644 --- a/docs/source/locale/ru/LC_MESSAGES/index.po +++ b/docs/source/locale/ru/LC_MESSAGES/index.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-12-29 15:24+0300\n" +"POT-Creation-Date: 2022-12-29 15:50+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -510,7 +510,9 @@ msgstr "МАЖОРНУЮ версию, когда сделаны обратно #: ../../source/index.rst:301 msgid "MINOR version when you add functionality in a backwards compatible manner" -msgstr "МИНОРНУЮ версию, когда вы добавляете новую функциональность, не нарушая обратной совместимости." +msgstr "" +"МИНОРНУЮ версию, когда вы добавляете новую функциональность, не нарушая " +"обратной совместимости." #: ../../source/index.rst:302 msgid "PATCH version when you make backwards compatible bug fixes" @@ -521,53 +523,62 @@ msgid "" "Additional labels for pre-release and build metadata are available as " "extensions to the MAJOR.MINOR.PATCH format." msgstr "" -"Дополнительные обозначения для предрелизных и билд-метаданных возможны как " -"дополнения к МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ формату." +"Дополнительные обозначения для предрелизных и билд-метаданных возможны " +"как дополнения к МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ формату." #: ../../source/index.rst:306 msgid "" -"In this project, the package version is assigned automatically with poem-" +"In this case, the package version is assigned automatically with poem-" "plugins_, it using on the tag in the repository as a major and minor and " "the counter, which takes the number of commits between tag to the head of" " branch." msgstr "" -"В этом проекте версия пакета назначается автоматически с помощью " -"poem-plugins_, он использует тег в репозитории как МАЖОР и МИНОР, " -"а также счетчик, который берет количество коммитов между тегом и " -"головой ветки." +"В этом проекте версия пакета назначается автоматически с помощью poem-" +"plugins_, он использует тег в репозитории как МАЖОР и МИНОР, а также " +"счетчик, который берет количество коммитов между тегом и головой ветки." #: ../../source/index.rst:314 msgid "How to develop?" -msgstr "Как начать разработку?" +msgstr "Как разрабатывать этот проект?" #: ../../source/index.rst:316 -msgid "Should be installed:" -msgstr "Должно быть установлено" - -#: ../../source/index.rst:318 -msgid "``virtualenv``" -msgstr "``virtualenv``" +msgid "" +"This project, like most open source projects, is developed by " +"enthusiasts, you can join the development, submit issues, or send your " +"merge requests." +msgstr "" +"Этот проект, как и многие другие open source проекты, разрабатывается " +"энтузиастами, и вы можете присоединиться к разработке, создавайте " +"issues в github или присылайте свои правки как merge request." #: ../../source/index.rst:319 -msgid "GNU Make as ``make``" -msgstr "GNU Make как ``make``" +msgid "" +"In order to start developing in this repository, you need to do the " +"following things." +msgstr "" +"Чтобы начать разработку в этом репозитории, вам необходимо сделать следующее:" + +#: ../../source/index.rst:322 +msgid "Should be installed:" +msgstr "Должно быть установлено" -#: ../../source/index.rst:320 +#: ../../source/index.rst:324 msgid "Python 3.7+ as ``python3``" msgstr "Python 3.7+ как ``python3``" -#: ../../source/index.rst:321 +#: ../../source/index.rst:325 msgid "Installed Poetry_ as ``poetry``" msgstr "Установлен Poetry_ как ``poetry``" -#: ../../source/index.rst:326 -msgid "For setting up developer environment just type" +#: ../../source/index.rst:329 +#, fuzzy +msgid "For setting up developer environment just execute:" msgstr "Для настройки окружения разработчика просто наберите" -#: ../../source/index.rst:328 +#: ../../source/index.rst:331 msgid "poetry install" msgstr "" -#: ../../source/index.rst:336 +#: ../../source/index.rst:339 msgid "Table Of Contents" msgstr "Содержание" From 1201c99404802592f7e65bdbfa6e1b3b27815e7b Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Thu, 29 Dec 2022 16:02:57 +0300 Subject: [PATCH 36/45] improve docs --- README.rst | 283 ++++++++++++++++-- docs/source/index.rst | 2 +- docs/source/locale/ru/LC_MESSAGES/index.po | 17 +- docs/source/locale/ru/LC_MESSAGES/services.po | 11 +- docs/source/locale/ru/LC_MESSAGES/signal.po | 3 +- 5 files changed, 272 insertions(+), 44 deletions(-) diff --git a/README.rst b/README.rst index a27bd9b0..651e7f11 100644 --- a/README.rst +++ b/README.rst @@ -25,25 +25,49 @@ aiomisc - miscellaneous utils for asyncio Miscellaneous utils for asyncio. -The complete documentation is available in the following languages: - -* `English documentation`_ -* `Russian documentation`_ - -.. _English documentation: https://aiomisc.readthedocs.io/en/latest/ -.. _Russian documentation: https://aiomisc.readthedocs.io/ru/latest/ - -.. contents:: Table of contents +As a programmer, you are no stranger to the challenges that come with building +and maintaining software applications. One area that can be particularly +difficult is making architecture of the software that using asynchronous I/O. + +This is where aiomisc comes in. aiomisc is a Python library that provides a +collection of utility functions and classes for working with asynchronous I/O +in a more intuitive and efficient way. It is built on top of the ``asyncio`` +library and is designed to make it easier for developers to write +asynchronous code that is both reliable and scalable. + +With aiomisc, you can take advantage of powerful features like +``worker pools``, ``connection pools``, ``circuit breaker pattern``, +and retry mechanisms such as ``asyncbackoff`` and ``asyncretry`` to make your +asyncio code more robust and easier to maintain. In this documentation, +we'll take a closer look at what ``aiomisc`` has to offer and how it can +help you streamline your asyncio service development. Installation ------------ -Installing from pypi: +Installation is possible in standard ways, such as PyPI or installation from +a git repository directly. + +Installing from PyPI_: .. code-block:: bash pip3 install aiomisc +Installing from github.com: + +.. code-block:: bash + + # Using git tool + pip3 install git+https://github.com/aiokitchen/aiomisc.git + + # Alternative way using http + pip3 install \ + https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip + +The package contains several extras and you can install additional dependencies +if you specify them in this way. + With uvloop_: .. code-block:: bash @@ -57,24 +81,215 @@ With aiohttp_: pip3 install "aiomisc[aiohttp]" +Complete table of extras bellow: + ++-----------------------------------+------------------------------------------------+ +| example | description | ++===================================+================================================+ +| ``pip install aiomisc[aiohttp]`` | For running aiohttp_ applications. | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[asgi]`` | For running ASGI_ applications | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[carbon]`` | Sending metrics to carbon_ (part of graphite_) | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[cron]`` | use croniter_ for scheduling tasks | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[raven]`` | Sending exceptions to sentry_ using raven_ | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[rich]`` | You might using rich_ for logging | ++-----------------------------------+------------------------------------------------+ +| ``pip install aiomisc[uvloop]`` | use uvloop_ as a default event loop | ++-----------------------------------+------------------------------------------------+ + +.. _ASGI: https://asgi.readthedocs.io/en/latest/ +.. _PyPI: https://pypi.org/ +.. _aiohttp: https://pypi.org/project/aiohttp +.. _carbon: https://pypi.org/project/carbon +.. _croniter: https://pypi.org/project/croniter +.. _graphite: http://graphiteapp.org +.. _raven: https://pypi.org/project/raven +.. _rich: https://pypi.org/project/rich +.. _sentry: https://sentry.io/ +.. _uvloop: https://pypi.org/project/uvloop -Installing from github.com: +You can combine extras values by separating them with commas, for example: .. code-block:: bash - pip3 install git+https://github.com/aiokitchen/aiomisc.git - pip3 install \ - https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip + pip3 install "aiomisc[aiohttp,cron,rich,uvloop]" -.. _uvloop: https://pypi.org/project/uvloop -.. _aiohttp: https://pypi.org/project/aiohttp +Quick Start +----------- + +This section will cover how this library creates and uses the event loop and +creates services. Of course, you can't write about everything here, but you +can read about a lot in the Tutorial_ section, and you can +always refer to the Modules_ and `API reference`_ sections for help. + +Event-loop and entrypoint ++++++++++++++++++++++++++ + +Let's look at this simple example first: + +.. code-block:: python + + import asyncio + import logging + + import aiomisc + + log = logging.getLogger(__name__) + + async def main(): + log.info('Starting') + await asyncio.sleep(3) + log.info('Exiting') + + + if __name__ == '__main__': + with entrypoint(log_level="info", log_format="color") as loop: + loop.run_until_complete(main()) + + +This code declares an asynchronous ``main()`` function that exits after +3 seconds. It would seem nothing interesting, but the whole point is in +the ``entrypoint``. + +What does the ``entrypoint`` do, it would seem not so much, it creates an +event-loop and transfers control to the user. However, under the hood, the +logger is configured in a separate thread, a pool of threads is created, +services are started, but more on that later and there are no services +in this example. + +Alternatively, you can choose not to use an entrypoint, just create an +event-loop and set this as a default event loop for current thread: + +.. code-block:: python + :name: test_index_get_loop + + import asyncio + import aiomisc + + # * Installs uvloop event loop is it's has been installed. + # * Creates and set `aiomisc.thread_pool.ThreadPoolExecutor` + # as a default executor + # * Sets just created event-loop as a current event-loop for this thread. + aiomisc.new_event_loop() + + async def main(): + await asyncio.sleep(1) + + if __name__ == '__main__': + loop = asyncio.get_event_loop() + loop.run_until_complete(main()) + +The example above is useful if your code is already using an implicitly created +event loop, you will have to modify less code, just add +``aiomisc.new_event_loop()`` and all calls to ``asyncio.get_event_loop()`` +will return the created instance. + +However, you can do with one call. Following example closes implicitly created +asyncio event loop and install a new one: + +.. code-block:: python + :name: test_index_new_loop + + import asyncio + import aiomisc + + async def main(): + await asyncio.sleep(3) + + if __name__ == '__main__': + loop = aiomisc.new_event_loop() + loop.run_until_complete(main()) + +Services +++++++++ + +The main thing that an ``entrypoint`` does is start and gracefully +stop services. + +The service concept within this library means a class derived from +the ``aiosmic.Service`` class and implementing the +``async def start(self) -> None:`` method and optionally the +``async def stop(self, exc: Optional[ Exception]) -> None`` method. + +The concept of stopping a service is not necessarily is pressing ``Ctrl+C`` +keys by user, it's actually just exiting the ``entrypoint`` context manager. + +The example below shows what your service might look like: + +.. code-block:: python + + from aiomisc import entrypoint, Service + + class MyService(Service): + async def start(self): + do_something_when_start() + + async def stop(self, exc): + do_graceful_shutdown() + + + with entrypoint(MyService()) as loop: + loop.run_forever() + +The entry point can start as many instances of the service as it likes, +and all of them will start concurrently. + +There is also a way if the ``start`` method is a payload for a service, +and then there is no need to implement the stop method, since the running +task with the ``start`` function will be canceled at the stop stage. +But in this case, you will have to notify the ``entrypoint`` that the +initialization of the service instance is complete and it can continue. + +Like this: + +.. code-block:: python + + import asyncio + from threading import Event + from aiomisc import entrypoint, Service + + event = Event() + + class MyService(Service): + async def start(self): + # Send signal to entrypoint for continue running + self.start_event.set() + await asyncio.sleep(3600) + + + with entrypoint(MyService()) as loop: + assert event.is_set() + +.. note:: + + The ``entrypoint`` passes control to the body of the context manager only + after all service instances have started. As mentioned above, a start is + considered to be the completion of the ``start`` method or the setting of + an start event with ``self.start_event.set()``. + +The whole power of this library is in the set of already implemented or +abstract services. +Such as: ``AIOHTTPService``, ``ASGIService``, ``TCPServer``, +``UDPServer``, ``TCPClient``, ``PeriodicService``, ``CronService`` and so on. + +Unfortunately in this section it is not possible to pay more attention to this, +please pay attention to the Tutorial_ section section, there are more +examples and explanations, and of cource you always can find out an answer on +the :doc:`/api/index` or in the source code. The authors have tried to make +the source code as clear and simple as possible, so feel free to explore it. + Versioning ---------- This software follows `Semantic Versioning`_ + Summary: it's given a version number MAJOR.MINOR.PATCH, increment the: * MAJOR version when you make incompatible API changes @@ -93,22 +308,40 @@ which takes the number of commits between tag to the head of branch. How to develop? --------------- +This project, like most open source projects, is developed by enthusiasts, +you can join the development, submit issues, or send your merge requests. + +In order to start developing in this repository, you need to do the +following things. + Should be installed: -* `virtualenv` -* GNU Make as `make` -* Python 3.5+ as `python3` +* Python 3.7+ as ``python3`` +* Installed Poetry_ as ``poetry`` +.. _Poetry: https://python-poetry.org/docs/ -For setting up developer environment just type +For setting up developer environment just execute: .. code-block:: - # install development dependencies - $ poetry install - - # Install pre-commit git hook - $ poetry run pre-commit install + poetry install .. _Semantic Versioning: http://semver.org/ + +.. _API reference: https://aiomisc.readthedocs.io/en/latest/api/index.html +.. _Modules: https://aiomisc.readthedocs.io/en/latest/modules.html +.. _Tutorial: https://aiomisc.readthedocs.io/en/latest/tutorial.html + +Table Of Contents ++++++++++++++++++ + +.. toctree:: + :glob: + :numbered: + :maxdepth: 3 + + tutorial + modules + api/index diff --git a/docs/source/index.rst b/docs/source/index.rst index 4b602a32..9e0856f2 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -94,7 +94,7 @@ Complete table of extras bellow: +-----------------------------------+------------------------------------------------+ | ``pip install aiomisc[carbon]`` | Sending metrics to carbon_ (part of graphite_) | +-----------------------------------+------------------------------------------------+ -| ``pip install aiomisc[cron]`` | use croniter_ for sheduling tasks | +| ``pip install aiomisc[cron]`` | use croniter_ for scheduling tasks | +-----------------------------------+------------------------------------------------+ | ``pip install aiomisc[raven]`` | Sending exceptions to sentry_ using raven_ | +-----------------------------------+------------------------------------------------+ diff --git a/docs/source/locale/ru/LC_MESSAGES/index.po b/docs/source/locale/ru/LC_MESSAGES/index.po index 8af057e7..bbb0e823 100644 --- a/docs/source/locale/ru/LC_MESSAGES/index.po +++ b/docs/source/locale/ru/LC_MESSAGES/index.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-12-29 15:50+0300\n" +"POT-Creation-Date: 2022-12-29 15:56+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -181,8 +181,8 @@ msgid "``pip install aiomisc[cron]``" msgstr "" #: ../../source/index.rst:97 -msgid "use croniter_ for sheduling tasks" -msgstr "планирование задачи с croniter_" +msgid "use croniter_ for scheduling tasks" +msgstr "планирование задач с библиотекой croniter_" #: ../../source/index.rst:99 msgid "``pip install aiomisc[raven]``" @@ -371,7 +371,6 @@ msgstr "" "Exception]) -> None``." #: ../../source/index.rst:221 -#, fuzzy msgid "" "The concept of stopping a service is not necessarily is pressing " "``Ctrl+C`` keys by user, it's actually just exiting the ``entrypoint`` " @@ -548,15 +547,16 @@ msgid "" "merge requests." msgstr "" "Этот проект, как и многие другие open source проекты, разрабатывается " -"энтузиастами, и вы можете присоединиться к разработке, создавайте " -"issues в github или присылайте свои правки как merge request." +"энтузиастами, и вы можете присоединиться к разработке, создавайте issues " +"в github или присылайте свои правки как merge request." #: ../../source/index.rst:319 msgid "" "In order to start developing in this repository, you need to do the " "following things." msgstr "" -"Чтобы начать разработку в этом репозитории, вам необходимо сделать следующее:" +"Чтобы начать разработку в этом репозитории, вам необходимо сделать " +"следующее:" #: ../../source/index.rst:322 msgid "Should be installed:" @@ -571,9 +571,8 @@ msgid "Installed Poetry_ as ``poetry``" msgstr "Установлен Poetry_ как ``poetry``" #: ../../source/index.rst:329 -#, fuzzy msgid "For setting up developer environment just execute:" -msgstr "Для настройки окружения разработчика просто наберите" +msgstr "Для настройки окружения разработчика выполните:" #: ../../source/index.rst:331 msgid "poetry install" diff --git a/docs/source/locale/ru/LC_MESSAGES/services.po b/docs/source/locale/ru/LC_MESSAGES/services.po index a0304011..434e395e 100644 --- a/docs/source/locale/ru/LC_MESSAGES/services.po +++ b/docs/source/locale/ru/LC_MESSAGES/services.po @@ -546,9 +546,8 @@ msgid "requires installed croniter_:" msgstr "необходимо установить библиотеку croniter_:" #: ../../source/services.rst:406 -#, fuzzy msgid "pip install croniter" -msgstr "необходимо установить библиотеку croniter_:" +msgstr "" #: ../../source/services.rst:410 ../../source/services.rst:552 #: ../../source/services.rst:618 @@ -760,9 +759,8 @@ msgid "pip install aiohttp" msgstr "требуется установленная библиотека aiohttp" #: ../../source/services.rst:554 -#, fuzzy msgid "pip install aiomisc[aiohttp]" -msgstr "требуется установленная библиотека aiohttp" +msgstr "" #: ../../source/services.rst:559 msgid "aiohttp application can be started as a service:" @@ -1221,13 +1219,12 @@ msgid "``SDWatchdogService``" msgstr "``SDWatchdogService``" #: ../../source/services.rst:883 -#, fuzzy msgid "" "Ready to use service just adding to your entrypoint and notifying SystemD" " service watchdog timer." msgstr "" -"Просто добавьте этот сервис в entrypoint и он будет отправлять " -"уведомления сторожевому таймеру SystemD." +"Готовый к использованию сервис, просто добавьте его в entrypoint и он будет " +"отправлять уведомления сторожевому таймеру SystemD." #: ../../source/services.rst:886 msgid "" diff --git a/docs/source/locale/ru/LC_MESSAGES/signal.po b/docs/source/locale/ru/LC_MESSAGES/signal.po index 2f4ac426..00de0ef1 100644 --- a/docs/source/locale/ru/LC_MESSAGES/signal.po +++ b/docs/source/locale/ru/LC_MESSAGES/signal.po @@ -28,9 +28,8 @@ msgstr "" "entrypoint." #: ../../source/signal.rst:7 -#, fuzzy msgid "``pre_start``" -msgstr "pre_start" +msgstr "``pre_start``" #: ../../source/signal.rst:9 msgid "" From 950bf27742ce378653929b7981c39be3b8124db9 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 13:46:49 +0300 Subject: [PATCH 37/45] Add compression for io --- aiomisc/io.py | 98 ++++++++++++++++++++++++++++++++++++++++------ docs/source/io.rst | 41 ++++++++++++++++++- 2 files changed, 126 insertions(+), 13 deletions(-) diff --git a/aiomisc/io.py b/aiomisc/io.py index 1c4e65c0..142b1182 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -1,5 +1,10 @@ import asyncio +import bz2 +import gzip +import lzma +import sys from concurrent.futures import Executor +from enum import Enum from functools import partial, total_ordering from pathlib import Path from typing import ( @@ -62,6 +67,8 @@ class AsyncFileIO(EventLoopMixin, Generic[T]): "_fp", "executor", "__iterator_lock", ) + EventLoopMixin.__slots__ + opener = staticmethod(open) + _fp: Optional[Union[IO, BinaryIO, TextIO]] def __init__( @@ -72,7 +79,7 @@ def __init__( self.executor = executor self._loop = loop self._fp = None - self.__open_args = (fname, mode, *args), kwargs + self.__open_args = (str(fname), mode, *args), kwargs self.__iterator_lock = asyncio.Lock() @classmethod @@ -89,7 +96,7 @@ async def open(self) -> None: return args, kwargs = self.__open_args - self._fp = await self.__execute_in_thread(open, *args, **kwargs) + self._fp = await self.__execute_in_thread(self.opener, *args, **kwargs) @property def fp(self) -> Union[IO, BinaryIO, TextIO]: @@ -152,9 +159,11 @@ def __hash__(self) -> int: return hash((self.__class__, self.fp)) async def __execute_in_thread( - self, method: Callable[..., Any], *args: Any, + self, method: Callable[..., Any], *args: Any, **kwargs: Any, ) -> Any: - return await self.loop.run_in_executor(self.executor, method, *args) + return await self.loop.run_in_executor( + self.executor, partial(method, *args, **kwargs), + ) @property def mode(self) -> str: @@ -265,23 +274,88 @@ async def __aenter__(self) -> "AsyncTextIO": return await super().__aenter__() # type: ignore -AsyncFileType = Union[ +# Aliases +AsyncBytesFileIO = AsyncBinaryIO +AsyncTextFileIO = AsyncTextIO + + +class AsyncGzipBinaryIO(AsyncBytesFileIO): + opener = staticmethod(gzip.open) # type: ignore + + +class AsyncGzipTextIO(AsyncTextFileIO): + opener = staticmethod(gzip.open) # type: ignore + + +class AsyncBz2BinaryIO(AsyncBytesFileIO): + opener = staticmethod(bz2.open) # type: ignore + + +class AsyncBz2TextIO(AsyncTextFileIO): + opener = staticmethod(bz2.open) # type: ignore + + +class AsyncLzmaBinaryIO(AsyncBytesFileIO): + opener = staticmethod(lzma.open) # type: ignore + + +class AsyncLzmaTextIO(AsyncTextFileIO): + opener = staticmethod(lzma.open) # type: ignore + + +class Compression(Enum): + NONE = (AsyncBinaryIO, AsyncTextIO) + GZIP = (AsyncGzipBinaryIO, AsyncGzipTextIO) + BZ2 = (AsyncBz2BinaryIO, AsyncBz2TextIO) + LZMA = (AsyncLzmaBinaryIO, AsyncLzmaTextIO) + + +AsyncBinaryIOType = Union[ AsyncBinaryIO, + AsyncBz2BinaryIO, + AsyncGzipBinaryIO, + AsyncLzmaBinaryIO, +] + +AsyncTextIOType = Union[ + AsyncBz2TextIO, + AsyncGzipTextIO, + AsyncLzmaTextIO, AsyncTextIO, ] -# Aliases -AsyncBytesFileIO = AsyncBinaryIO -AsyncTextFileIO = AsyncTextIO +AsyncFileType = Union[AsyncBinaryIOType, AsyncTextIOType] AsyncFileT = AsyncFileType def async_open( fname: Union[str, Path], mode: str = "r", + compression: Compression = Compression.NONE, + encoding: str = sys.getdefaultencoding(), *args: Any, **kwargs: Any, ) -> AsyncFileType: + binary_io_class, text_io_class = compression.value + if "b" in mode: - return AsyncBytesFileIO( - fname, mode, *args, **kwargs, - ) - return AsyncTextFileIO(fname, mode, *args, **kwargs) + return binary_io_class(fname, mode, *args, **kwargs) + + if "t" not in mode: + mode = f"t{mode}" + + return text_io_class(fname, mode, encoding=encoding, *args, **kwargs) + + +__all__ = ( + "AsyncBinaryIO", + "AsyncBz2BinaryIO", + "AsyncBz2TextIO", + "AsyncFileT", + "AsyncFileType", + "AsyncGzipBinaryIO", + "AsyncGzipTextIO", + "AsyncLzmaBinaryIO", + "AsyncLzmaTextIO", + "AsyncTextIO", + "Compression", + "async_open", +) diff --git a/docs/source/io.rst b/docs/source/io.rst index 2f988f84..415b6ca4 100644 --- a/docs/source/io.rst +++ b/docs/source/io.rst @@ -1,7 +1,8 @@ asynchronous file operations ============================ -Asynchronous files operations. Based on the thread pool under the hood. +Asynchronous files operations including support for data compression on the fly. +Based on the thread pool under the hood. .. code-block:: python :name: test_io @@ -97,6 +98,44 @@ In general, for light loads, I would advise you to adhere to the following rules main(Path(path)) ) +In the fly compression +---------------------- + +To enable compression, you need to pass the `compression` argument to the +`async_open` function. + +Supported compressors: + +* :class:`aiomisc.io.Compression.NONE` +* :class:`aiomisc.io.Compression.GZIP` +* :class:`aiomisc.io.Compression.BZ2` +* :class:`aiomisc.io.Compression.LZMA` + +An example of usage: + +.. code-block:: python + :name: test_compressed_gzip_io + + import tempfile + from aiomisc import run + from aiomisc.io import async_open, Compression + from pathlib import Path + + + async def file_write(): + with tempfile.TemporaryDirectory() as tmp: + fname = Path(tmp) / 'test.txt' + + async with async_open( + fname, 'w+', compression=Compression.GZIP + ) as afp: + for _ in range(10000): + await afp.write("Hello World\n") + + assert fname.stat().st_size < 10000 + + run(file_write()) + .. _aiofiles: https://pypi.org/project/aiofiles/ .. _aiofile: https://pypi.org/project/aiofile/ From 0e0ac627bb6e03febab7e1b5095bb51fc2fcccc8 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 13:54:43 +0300 Subject: [PATCH 38/45] Add translations --- docs/source/locale/ru/LC_MESSAGES/io.po | 87 +++++++++++++++++++++---- tests/test_io.py | 29 ++++++++- 2 files changed, 101 insertions(+), 15 deletions(-) diff --git a/docs/source/locale/ru/LC_MESSAGES/io.po b/docs/source/locale/ru/LC_MESSAGES/io.po index 79e68d4e..5865563c 100644 --- a/docs/source/locale/ru/LC_MESSAGES/io.po +++ b/docs/source/locale/ru/LC_MESSAGES/io.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-12-29 11:36+0300\n" +"POT-Creation-Date: 2023-01-20 13:47+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -20,12 +20,14 @@ msgid "asynchronous file operations" msgstr "асинхронные операции с файлами" #: ../../source/io.rst:4 -msgid "Asynchronous files operations. Based on the thread pool under the hood." +msgid "" +"Asynchronous files operations including support for data compression on " +"the fly. Based on the thread pool under the hood." msgstr "" -"Асинхронные файловые операции запускающиеся в пуле потоков \"под " -"капотом\"." +"Асинхронные файловые операции, включая поточную компрессию данных. " +"Работают в пуле потоков \"под капотом\"." -#: ../../source/io.rst:6 +#: ../../source/io.rst:7 msgid "" "import aiomisc\n" "import tempfile\n" @@ -49,7 +51,7 @@ msgid "" " loop.run_until_complete(file_write())" msgstr "" -#: ../../source/io.rst:31 +#: ../../source/io.rst:32 msgid "" "This is the way to working with files based on threads. It's very similar" " to `aiofiles`_ project and same limitations." @@ -57,7 +59,7 @@ msgstr "" "Этот способ работы с файлами основан на потоках. Это очень похоже на то " "как сделано в библиотеке `aiofiles`_ с теми-же ограничениями." -#: ../../source/io.rst:34 +#: ../../source/io.rst:35 msgid "" "Of course, you can use `aiofile`_ project for this. But it's not a silver" " bullet and has OS API-related limitations." @@ -66,7 +68,7 @@ msgstr "" " не панацея, так как имеет ограничения связанные с API операционной " "системы." -#: ../../source/io.rst:37 +#: ../../source/io.rst:38 msgid "" "In general, for light loads, I would advise you to adhere to the " "following rules:" @@ -74,7 +76,7 @@ msgstr "" "В основном, для небольших нагрузок приложений, я рекомендую " "придерживаться следующих правил:" -#: ../../source/io.rst:39 +#: ../../source/io.rst:40 msgid "" "If reading and writing small or big chunks from files with random access " "is the main task in your project, use `aiofile`_." @@ -82,11 +84,11 @@ msgstr "" "Если чтение и запись маленьких или больших кусочков в файлы со случайным " "доступом основная задача приложения - стоит использовать `aiofile`_." -#: ../../source/io.rst:41 +#: ../../source/io.rst:42 msgid "Otherwise use this module or `aiofiles`_" msgstr "Иначе можно взять этот модуль или `aiofiles`_" -#: ../../source/io.rst:42 +#: ../../source/io.rst:43 msgid "" "If the main task is to read large chunks of files for processing, both of" " the above methods are not optimal cause you will switch context each IO " @@ -104,7 +106,7 @@ msgstr "" "потоками может оказаться выше чем суммарно время исполнения всех IO " "операций." -#: ../../source/io.rst:50 +#: ../../source/io.rst:51 msgid "" "Just try pack all blocking staff in separate functions and call it in a " "thread pool, see the example bellow:" @@ -112,7 +114,7 @@ msgstr "" "Просто попробуйте завернуть все блокирующие вызовы в отдельные функции и " "вызывайте их используя пул потоков (см. пример ниже):" -#: ../../source/io.rst:53 +#: ../../source/io.rst:54 msgid "" "import os\n" "import aiomisc\n" @@ -158,3 +160,62 @@ msgid "" " main(Path(path))\n" " )" msgstr "" + +#: ../../source/io.rst:102 +msgid "In the fly compression" +msgstr "Поточное сжатие" + +#: ../../source/io.rst:104 +msgid "" +"To enable compression, you need to pass the `compression` argument to the" +" `async_open` function." +msgstr "" +"Чтобы включить поточное сжатие, нужно передать аргумент `compression` в " +"функцию `async_open`." + +#: ../../source/io.rst:107 +msgid "Supported compressors:" +msgstr "Поддерживаемые алгоритмы сжатия:" + +#: ../../source/io.rst:109 +msgid ":class:`aiomisc.io.Compression.NONE`" +msgstr "" + +#: ../../source/io.rst:110 +msgid ":class:`aiomisc.io.Compression.GZIP`" +msgstr "" + +#: ../../source/io.rst:111 +msgid ":class:`aiomisc.io.Compression.BZ2`" +msgstr "" + +#: ../../source/io.rst:112 +msgid ":class:`aiomisc.io.Compression.LZMA`" +msgstr "" + +#: ../../source/io.rst:114 +msgid "An example of usage:" +msgstr "Пример использования" + +#: ../../source/io.rst:116 +msgid "" +"import tempfile\n" +"from aiomisc import run\n" +"from aiomisc.io import async_open, Compression\n" +"from pathlib import Path\n" +"\n" +"\n" +"async def file_write():\n" +" with tempfile.TemporaryDirectory() as tmp:\n" +" fname = Path(tmp) / 'test.txt'\n" +"\n" +" async with async_open(\n" +" fname, 'w+', compression=Compression.GZIP\n" +" ) as afp:\n" +" for _ in range(10000):\n" +" await afp.write(\"Hello World\\n\")\n" +"\n" +" assert fname.stat().st_size < 10000\n" +"\n" +"run(file_write())" +msgstr "" diff --git a/tests/test_io.py b/tests/test_io.py index e74ee138..051c9783 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -8,13 +8,19 @@ import pytest import aiomisc -from aiomisc.io import AsyncTextFileIO +from aiomisc.io import AsyncTextIO from tests import unix_only pytestmark = pytest.mark.catch_loop_exceptions +compressors = pytest.mark.parametrize( + "compression", list(aiomisc.io.Compression), + ids=list(map(lambda c: c.name.lower(), aiomisc.io.Compression)), +) + + async def test_simple(loop, tmp_path): tdir = Path(tmp_path) @@ -71,7 +77,7 @@ async def test_ordering(loop, tmp_path): async def test_async_for(loop, tmp_path): tdir = Path(tmp_path) - afp: AsyncTextFileIO + afp: AsyncTextIO async with aiomisc.io.async_open(tdir / "path", "w", loop=loop) as afp: await afp.write("foo\nbar\nbaz\n") @@ -149,3 +155,22 @@ async def test_object(loop): assert isinstance(afp.errors, str) assert isinstance(afp.line_buffering, bool) assert afp.newlines is None + + +@compressors +async def test_compression(compression: aiomisc.io.Compression, tmp_path): + fname = Path(tmp_path) / "test.file" + + afp: aiomisc.io.AsyncTextIOType + + async with aiomisc.io.async_open( + fname, "w", compression=compression, + ) as afp: + for i in range(1000): + await afp.write(f"{i}\n") + + async with aiomisc.io.async_open( + fname, "r", compression=compression, + ) as afp: + for i in range(1000): + assert await afp.readline() == f"{i}\n" From 2fa14264379304d51591f62738923ada08612c07 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 17:26:26 +0300 Subject: [PATCH 39/45] Use AnyStr --- aiomisc/io.py | 103 +++--- docs/source/index.rst | 35 +-- .../locale/ru/LC_MESSAGES/api/aiomisc.po | 96 +++++- docs/source/locale/ru/LC_MESSAGES/index.po | 212 ++++++------- docs/source/locale/ru/LC_MESSAGES/services.po | 6 +- docs/source/locale/ru/LC_MESSAGES/signal.po | 3 +- poetry.lock | 294 ++++++++++-------- pyproject.toml | 1 - 8 files changed, 429 insertions(+), 321 deletions(-) diff --git a/aiomisc/io.py b/aiomisc/io.py index 142b1182..8573e7b3 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -8,23 +8,20 @@ from functools import partial, total_ordering from pathlib import Path from typing import ( - IO, Any, Awaitable, BinaryIO, Callable, Generator, Generic, List, Optional, - TextIO, TypeVar, Union, + IO, Any, AnyStr, Awaitable, Callable, Generator, Generic, List, Optional, + TextIO, Union, ) from .compat import EventLoopMixin -T = TypeVar("T", bound=Union[str, bytes]) - - def proxy_method_async( name: str, in_executor: bool = True, ) -> Callable[..., Any]: def wrap_to_future( loop: asyncio.AbstractEventLoop, - func: Callable[..., T], + func: Callable[..., AnyStr], *args: Any, **kwargs: Any, ) -> asyncio.Future: future = loop.create_future() @@ -39,10 +36,10 @@ def _inner(): # type: ignore return future def wrap_to_thread( - loop: asyncio.AbstractEventLoop, func: Callable[..., T], + loop: asyncio.AbstractEventLoop, func: Callable[..., AnyStr], executor: Executor, *args: Any, **kwargs: Any, - ) -> Awaitable[T]: + ) -> Awaitable[AnyStr]: callee = partial(func, *args, **kwargs) # noinspection PyTypeChecker return loop.run_in_executor(executor, callee) @@ -62,14 +59,16 @@ async def method(self, *args, **kwargs): # type: ignore @total_ordering -class AsyncFileIO(EventLoopMixin, Generic[T]): +class AsyncFileIO(EventLoopMixin, Generic[AnyStr]): __slots__ = ( "_fp", "executor", "__iterator_lock", ) + EventLoopMixin.__slots__ - opener = staticmethod(open) + _fp: Optional[IO[AnyStr]] - _fp: Optional[Union[IO, BinaryIO, TextIO]] + @staticmethod + def get_opener() -> Callable[..., IO[AnyStr]]: + return open def __init__( self, fname: Union[str, Path], mode: str = "r", @@ -96,10 +95,12 @@ async def open(self) -> None: return args, kwargs = self.__open_args - self._fp = await self.__execute_in_thread(self.opener, *args, **kwargs) + self._fp = await self.__execute_in_thread( + self.get_opener(), *args, **kwargs, + ) @property - def fp(self) -> Union[IO, BinaryIO, TextIO]: + def fp(self) -> IO[AnyStr]: if self._fp is not None: return self._fp raise RuntimeError("file is not opened") @@ -111,7 +112,7 @@ def __await__(self) -> Generator[Any, Any, "AsyncFileIO"]: yield from self.open().__await__() return self - async def __aenter__(self) -> "AsyncFileIOBase": + async def __aenter__(self) -> "AsyncFileIO[AnyStr]": await self.open() return self @@ -133,10 +134,10 @@ def __del__(self) -> None: self.fp.close() del self._fp - def __aiter__(self) -> "AsyncFileIOBase": + def __aiter__(self) -> "AsyncFileIO[AnyStr]": return self - async def __anext__(self) -> T: + async def __anext__(self) -> AnyStr: async with self.__iterator_lock: line = await self.readline() @@ -206,13 +207,13 @@ async def writable(self) -> bool: async def flush(self) -> None: await self.__execute_in_thread(self.fp.flush) - async def read(self, n: int = -1) -> T: + async def read(self, n: int = -1) -> AnyStr: return await self.__execute_in_thread(self.fp.read, n) - async def readline(self, limit: int = -1) -> T: + async def readline(self, limit: int = -1) -> AnyStr: return await self.__execute_in_thread(self.fp.readline, limit) - async def readlines(self, limit: int = -1) -> List[T]: + async def readlines(self, limit: int = -1) -> List[AnyStr]: return await self.__execute_in_thread(self.fp.readlines, limit) async def seek(self, offset: int, whence: int = 0) -> int: @@ -221,10 +222,10 @@ async def seek(self, offset: int, whence: int = 0) -> int: async def truncate(self, size: Optional[int] = None) -> int: return await self.__execute_in_thread(self.fp.truncate, size) - async def write(self, s: T) -> int: + async def write(self, s: AnyStr) -> int: return await self.__execute_in_thread(self.fp.write, s) - async def writelines(self, lines: List[T]) -> None: + async def writelines(self, lines: List[AnyStr]) -> None: await self.__execute_in_thread(self.fp.writelines, lines) @@ -232,15 +233,7 @@ async def writelines(self, lines: List[T]) -> None: class AsyncBinaryIO(AsyncFileIO[bytes]): - @property - def fp(self) -> BinaryIO: - return self._fp # type: ignore - - def __aiter__(self) -> "AsyncBytesFileIO": - return self - - async def __aenter__(self) -> "AsyncBinaryIO": - return await super().__aenter__() # type: ignore + pass class AsyncTextIO(AsyncFileIO[str]): @@ -267,40 +260,52 @@ def encoding(self) -> str: def buffer(self) -> AsyncBinaryIO: return AsyncBinaryIO.open_fp(self.fp.buffer) # type: ignore - def __aiter__(self) -> "AsyncTextFileIO": - return self - - async def __aenter__(self) -> "AsyncTextIO": - return await super().__aenter__() # type: ignore - # Aliases AsyncBytesFileIO = AsyncBinaryIO AsyncTextFileIO = AsyncTextIO -class AsyncGzipBinaryIO(AsyncBytesFileIO): - opener = staticmethod(gzip.open) # type: ignore +class GzipIOMixin(Generic[AnyStr]): + @staticmethod + def get_opener() -> Callable[..., IO[AnyStr]]: + return gzip.open # type: ignore + + +class AsyncGzipBinaryIO(AsyncBytesFileIO, GzipIOMixin[bytes]): + pass + + +class AsyncGzipTextIO(AsyncTextFileIO, GzipIOMixin[str]): + pass + + +class Bz2IOMixin(Generic[AnyStr]): + @staticmethod + def get_opener() -> Callable[..., IO[AnyStr]]: + return bz2.open -class AsyncGzipTextIO(AsyncTextFileIO): - opener = staticmethod(gzip.open) # type: ignore +class AsyncBz2BinaryIO(AsyncBytesFileIO, Bz2IOMixin[bytes]): + pass -class AsyncBz2BinaryIO(AsyncBytesFileIO): - opener = staticmethod(bz2.open) # type: ignore +class AsyncBz2TextIO(AsyncTextFileIO, Bz2IOMixin[str]): + pass -class AsyncBz2TextIO(AsyncTextFileIO): - opener = staticmethod(bz2.open) # type: ignore +class LzmaIOMixin(Generic[AnyStr]): + @staticmethod + def get_opener() -> Callable[..., IO[AnyStr]]: + return lzma.open -class AsyncLzmaBinaryIO(AsyncBytesFileIO): - opener = staticmethod(lzma.open) # type: ignore +class AsyncLzmaBinaryIO(AsyncBytesFileIO, LzmaIOMixin[bytes]): + pass -class AsyncLzmaTextIO(AsyncTextFileIO): - opener = staticmethod(lzma.open) # type: ignore +class AsyncLzmaTextIO(AsyncTextFileIO, LzmaIOMixin[str]): + pass class Compression(Enum): @@ -333,7 +338,7 @@ def async_open( compression: Compression = Compression.NONE, encoding: str = sys.getdefaultencoding(), *args: Any, **kwargs: Any, -) -> AsyncFileType: +) -> AsyncFileIO[AnyStr]: binary_io_class, text_io_class = compression.value if "b" in mode: diff --git a/docs/source/index.rst b/docs/source/index.rst index 9e0856f2..9b52127e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -23,19 +23,17 @@ aiomisc - miscellaneous utils for asyncio :target: https://pypi.python.org/pypi/aiomisc/ -Miscellaneous utils for asyncio. - As a programmer, you are no stranger to the challenges that come with building and maintaining software applications. One area that can be particularly -difficult is making architecture of the software that using asynchronous I/O. +difficult is making architecture of the asynchronous I/O software. -This is where aiomisc comes in. aiomisc is a Python library that provides a -collection of utility functions and classes for working with asynchronous I/O -in a more intuitive and efficient way. It is built on top of the ``asyncio`` -library and is designed to make it easier for developers to write -asynchronous code that is both reliable and scalable. +This is where ``aiomisc`` comes in. It is a Python library that +provides a collection of utility functions and classes for working with +asynchronous I/O in a more intuitive and efficient way. It is built on +top of the ``asyncio`` library and is designed to make it easier for +developers to write asynchronous code that is both reliable and scalable. -With aiomisc, you can take advantage of powerful features like +With ``aiomisc``, you can take advantage of powerful features like :doc:`worker pools `, :doc:`connection pools `, :doc:`circuit breaker pattern `, and retry mechanisms such as :doc:`asyncbackoff ` and @@ -125,9 +123,8 @@ Quick Start ----------- This section will cover how this library creates and uses the event loop and -creates services. Of course, you can't write about everything here, but you -can read about a lot in the :doc:`/tutorial` section, and you can always refer -to the :doc:`/modules` and :doc:`/api/index` sections for help. +creates services. For more details see :doc:`/tutorial` section, and you can +always refer to the :doc:`/modules` and :doc:`/api/index` sections for help. Event-loop and entrypoint +++++++++++++++++++++++++ @@ -150,22 +147,22 @@ Let's look at this simple example first: if __name__ == '__main__': - with entrypoint(log_level="info", log_format="color") as loop: + with aiomisc.entrypoint(log_level="info", log_format="color") as loop: loop.run_until_complete(main()) -This code declares an asynchronous ``main()`` function that exits after +This code declares an asynchronous ``main()`` function that exits for 3 seconds. It would seem nothing interesting, but the whole point is in the ``entrypoint``. -What does the ``entrypoint`` do, it would seem not so much, it creates an +At the first glance the ``entrypoint`` did not do much, just creates an event-loop and transfers control to the user. However, under the hood, the logger is configured in a separate thread, a pool of threads is created, -services are started, but more on that later and there are no services +services are started, but more on that later as there are no services in this example. -Alternatively, you can choose not to use an entrypoint, just create an -event-loop and set this as a default event loop for current thread: +Alternatively, you can choose not to use an ``entrypoint``, just create an +event-loop and set it as a default for current thread: .. code-block:: python :name: test_index_get_loop @@ -335,8 +332,6 @@ For setting up developer environment just execute: .. _Semantic Versioning: http://semver.org/ -Table Of Contents -+++++++++++++++++ .. toctree:: :glob: diff --git a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po index b00a0449..8841e8a5 100644 --- a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po +++ b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 16.1.16\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-29 11:05+0300\n" +"POT-Creation-Date: 2023-01-20 13:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -307,6 +307,100 @@ msgstr "" msgid "``aiomisc.io`` module" msgstr "Модуль ``aiomisc.io``" +#: bz2.open:1 of +msgid "Open a bzip2-compressed file in binary or text mode." +msgstr "" + +#: bz2.open:3 of +msgid "" +"The filename argument can be an actual filename (a str, bytes, or " +"PathLike object), or an existing file object to read from or write to." +msgstr "" + +#: bz2.open:7 gzip.open:6 of +msgid "" +"The mode argument can be \"r\", \"rb\", \"w\", \"wb\", \"x\", \"xb\", " +"\"a\" or \"ab\" for binary mode, or \"rt\", \"wt\", \"xt\" or \"at\" for " +"text mode. The default mode is \"rb\", and the default compresslevel is " +"9." +msgstr "" + +#: bz2.open:11 of +msgid "" +"For binary mode, this function is equivalent to the BZ2File constructor: " +"BZ2File(filename, mode, compresslevel). In this case, the encoding, " +"errors and newline arguments must not be provided." +msgstr "" + +#: bz2.open:15 of +msgid "" +"For text mode, a BZ2File object is created, and wrapped in an " +"io.TextIOWrapper instance with the specified encoding, error handling " +"behavior, and line ending(s)." +msgstr "" + +#: gzip.open:1 of +msgid "Open a gzip-compressed file in binary or text mode." +msgstr "" + +#: gzip.open:3 of +msgid "" +"The filename argument can be an actual filename (a str or bytes object), " +"or an existing file object to read from or write to." +msgstr "" + +#: gzip.open:10 of +msgid "" +"For binary mode, this function is equivalent to the GzipFile constructor:" +" GzipFile(filename, mode, compresslevel). In this case, the encoding, " +"errors and newline arguments must not be provided." +msgstr "" + +#: gzip.open:14 of +msgid "" +"For text mode, a GzipFile object is created, and wrapped in an " +"io.TextIOWrapper instance with the specified encoding, error handling " +"behavior, and line ending(s)." +msgstr "" + +#: lzma.open:1 of +msgid "Open an LZMA-compressed file in binary or text mode." +msgstr "" + +#: lzma.open:3 of +msgid "" +"filename can be either an actual file name (given as a str, bytes, or " +"PathLike object), in which case the named file is opened, or it can be an" +" existing file object to read from or write to." +msgstr "" + +#: lzma.open:7 of +msgid "" +"The mode argument can be \"r\", \"rb\" (default), \"w\", \"wb\", \"x\", " +"\"xb\", \"a\", or \"ab\" for binary mode, or \"rt\", \"wt\", \"xt\", or " +"\"at\" for text mode." +msgstr "" + +#: lzma.open:11 of +msgid "" +"The format, check, preset and filters arguments specify the compression " +"settings, as for LZMACompressor, LZMADecompressor and LZMAFile." +msgstr "" + +#: lzma.open:15 of +msgid "" +"For binary mode, this function is equivalent to the LZMAFile constructor:" +" LZMAFile(filename, mode, ...). In this case, the encoding, errors and " +"newline arguments must not be provided." +msgstr "" + +#: lzma.open:19 of +msgid "" +"For text mode, an LZMAFile object is created, and wrapped in an " +"io.TextIOWrapper instance with the specified encoding, error handling " +"behavior, and line ending(s)." +msgstr "" + #: ../../source/api/aiomisc.rst:68 msgid "``aiomisc.iterator_wrapper`` module" msgstr "Модуль ``aiomisc.iterator_wrapper``" diff --git a/docs/source/locale/ru/LC_MESSAGES/index.po b/docs/source/locale/ru/LC_MESSAGES/index.po index bbb0e823..32740057 100644 --- a/docs/source/locale/ru/LC_MESSAGES/index.po +++ b/docs/source/locale/ru/LC_MESSAGES/index.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2022-12-29 15:56+0300\n" +"POT-Creation-Date: 2023-01-20 13:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -32,39 +32,34 @@ msgid "Latest Version" msgstr "Актуальная версия" #: ../../source/index.rst:26 -msgid "Miscellaneous utils for asyncio." -msgstr "Различные утилиты для asyncio" - -#: ../../source/index.rst:28 msgid "" "As a programmer, you are no stranger to the challenges that come with " "building and maintaining software applications. One area that can be " -"particularly difficult is making architecture of the software that using " -"asynchronous I/O." +"particularly difficult is making architecture of the asynchronous I/O " +"software." msgstr "" -"Вам, как программисту, знакомы проблемы, связанные с созданием и " -"обслуживанием программных приложений. Одной из областей, которая может " -"быть особенно сложной, является создание архитектуры программного " -"обеспечения, использующего асинхронный ввод-вывод." +"Вам, как программисту, знакомы проблемы, связанные с дизайном и " +"обслуживанием программ. Одним из мест, которое может " +"быть особенно сложным, является создание архитектуры программы, " +"использующего асинхронный ввод-вывод." -#: ../../source/index.rst:32 +#: ../../source/index.rst:30 msgid "" -"This is where aiomisc comes in. aiomisc is a Python library that provides" -" a collection of utility functions and classes for working with " +"This is where ``aiomisc`` comes in. It is a Python library that provides " +"a collection of utility functions and classes for working with " "asynchronous I/O in a more intuitive and efficient way. It is built on " "top of the ``asyncio`` library and is designed to make it easier for " "developers to write asynchronous code that is both reliable and scalable." msgstr "" -"Здесь на помощь приходит aiomisc. aiomisc — это библиотека Python, " -"которая предоставляет набор служебных функций и классов для работы с " -"асинхронным вводом-выводом более интуитивно понятным и эффективным " -"способом. Он построен на основе популярной библиотеки ``asyncio`` и " -"предназначен для облегчения написания асинхронного кода разработчиками, " -"который является одновременно надежным и масштабируемым." +"Вот тут на сцену выходит ``aiomisc``. Это библиотека Python, которая " +"предоставляет набор служебных функций и классов для работы с асинхронным " +"IO более интуитивно понятным и эффективным способом. Она построена " +"используя библиотеку asyncio и предназначена для облегчения написания " +"асинхронного кода разработчиками, который является надежным и масштабируемым." -#: ../../source/index.rst:38 +#: ../../source/index.rst:36 msgid "" -"With aiomisc, you can take advantage of powerful features like " +"With ``aiomisc``, you can take advantage of powerful features like " ":doc:`worker pools `, :doc:`connection pools `, " ":doc:`circuit breaker pattern `, and retry mechanisms " "such as :doc:`asyncbackoff ` and :ref:`asyncretry " @@ -82,11 +77,11 @@ msgstr "" "может предложить ``aiomisc`` и как он может помочь вам упростить " "разработку сервисов с asyncio." -#: ../../source/index.rst:48 +#: ../../source/index.rst:46 msgid "Installation" msgstr "Установка" -#: ../../source/index.rst:50 +#: ../../source/index.rst:48 msgid "" "Installation is possible in standard ways, such as PyPI or installation " "from a git repository directly." @@ -94,19 +89,19 @@ msgstr "" "Возможна установка стандартными способами, такими как PyPI или установка " "из репозитория git напрямую." -#: ../../source/index.rst:53 +#: ../../source/index.rst:51 msgid "Installing from PyPI_:" msgstr "Установка с PyPI_:" -#: ../../source/index.rst:55 +#: ../../source/index.rst:53 msgid "pip3 install aiomisc" msgstr "" -#: ../../source/index.rst:59 +#: ../../source/index.rst:57 msgid "Installing from github.com:" msgstr "Установка из репозитория на github.com:" -#: ../../source/index.rst:61 +#: ../../source/index.rst:59 msgid "" "# Using git tool\n" "pip3 install git+https://github.com/aiokitchen/aiomisc.git\n" @@ -116,7 +111,7 @@ msgid "" " https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip" msgstr "" -#: ../../source/index.rst:70 +#: ../../source/index.rst:68 msgid "" "The package contains several extras and you can install additional " "dependencies if you specify them in this way." @@ -124,109 +119,108 @@ msgstr "" "Пакет содержит несколько дополнений, и вы можете установить " "дополнительные зависимости, если вы укажете их таким образом." -#: ../../source/index.rst:73 +#: ../../source/index.rst:71 msgid "With uvloop_:" msgstr "Вместе с uvloop_" -#: ../../source/index.rst:75 +#: ../../source/index.rst:73 msgid "pip3 install \"aiomisc[uvloop]\"" msgstr "" -#: ../../source/index.rst:80 +#: ../../source/index.rst:78 msgid "With aiohttp_:" msgstr "Вместе с aiohttp_:" -#: ../../source/index.rst:82 +#: ../../source/index.rst:80 msgid "pip3 install \"aiomisc[aiohttp]\"" msgstr "" -#: ../../source/index.rst:86 +#: ../../source/index.rst:84 msgid "Complete table of extras bellow:" msgstr "Полная таблица дополнений ниже:" -#: ../../source/index.rst:89 +#: ../../source/index.rst:87 msgid "example" msgstr "пример" -#: ../../source/index.rst:89 +#: ../../source/index.rst:87 msgid "description" msgstr "описание" -#: ../../source/index.rst:91 +#: ../../source/index.rst:89 msgid "``pip install aiomisc[aiohttp]``" msgstr "" -#: ../../source/index.rst:91 +#: ../../source/index.rst:89 msgid "For running aiohttp_ applications." msgstr "Для запуска приложений написанных с aiohttp_." -#: ../../source/index.rst:93 +#: ../../source/index.rst:91 msgid "``pip install aiomisc[asgi]``" msgstr "" -#: ../../source/index.rst:93 +#: ../../source/index.rst:91 msgid "For running ASGI_ applications" msgstr "Для запуска ASGI_ приложений" -#: ../../source/index.rst:95 +#: ../../source/index.rst:93 msgid "``pip install aiomisc[carbon]``" msgstr "" -#: ../../source/index.rst:95 +#: ../../source/index.rst:93 msgid "Sending metrics to carbon_ (part of graphite_)" msgstr "Чтобы посылать метрики в carbon_ (часть graphite_)" -#: ../../source/index.rst:97 +#: ../../source/index.rst:95 msgid "``pip install aiomisc[cron]``" msgstr "" -#: ../../source/index.rst:97 +#: ../../source/index.rst:95 msgid "use croniter_ for scheduling tasks" msgstr "планирование задач с библиотекой croniter_" -#: ../../source/index.rst:99 +#: ../../source/index.rst:97 msgid "``pip install aiomisc[raven]``" msgstr "" -#: ../../source/index.rst:99 +#: ../../source/index.rst:97 msgid "Sending exceptions to sentry_ using raven_" msgstr "Чтобы посылать исключения в sentry_ используя raven_" -#: ../../source/index.rst:101 +#: ../../source/index.rst:99 msgid "``pip install aiomisc[rich]``" msgstr "" -#: ../../source/index.rst:101 +#: ../../source/index.rst:99 msgid "You might using rich_ for logging" msgstr "Можете использовать rich_ для логирования" -#: ../../source/index.rst:103 +#: ../../source/index.rst:101 msgid "``pip install aiomisc[uvloop]``" msgstr "" -#: ../../source/index.rst:103 +#: ../../source/index.rst:101 msgid "use uvloop_ as a default event loop" msgstr "используйте uvloop_ как основной event-loop" -#: ../../source/index.rst:117 +#: ../../source/index.rst:115 msgid "You can combine extras values by separating them with commas, for example:" msgstr "Вы можете комбинировать эти значения разделяя их запятыми, пример:" -#: ../../source/index.rst:119 +#: ../../source/index.rst:117 msgid "pip3 install \"aiomisc[aiohttp,cron,rich,uvloop]\"" msgstr "" -#: ../../source/index.rst:125 +#: ../../source/index.rst:123 msgid "Quick Start" msgstr "Быстрый старт" -#: ../../source/index.rst:127 +#: ../../source/index.rst:125 msgid "" "This section will cover how this library creates and uses the event loop " -"and creates services. Of course, you can't write about everything here, " -"but you can read about a lot in the :doc:`/tutorial` section, and you can" -" always refer to the :doc:`/modules` and :doc:`/api/index` sections for " -"help." +"and creates services. For more details see :doc:`/tutorial` section, and " +"you can always refer to the :doc:`/modules` and :doc:`/api/index` " +"sections for help." msgstr "" "В этом разделе будет рассказано, как эта библиотека создает и использует " "цикл обработки событий и создает службы. Конечно, обо всем тут не " @@ -234,15 +228,15 @@ msgstr "" "всегда можно обратиться к разделу :doc:`/modules` и разделу " ":doc:`/api/index` для справки." -#: ../../source/index.rst:133 +#: ../../source/index.rst:130 msgid "Event-loop and entrypoint" msgstr "Eventloop и entrypoint" -#: ../../source/index.rst:135 +#: ../../source/index.rst:132 msgid "Let's look at this simple example first:" msgstr "Сначала рассмотрим этот простой пример:" -#: ../../source/index.rst:137 +#: ../../source/index.rst:134 msgid "" "import asyncio\n" "import logging\n" @@ -258,26 +252,28 @@ msgid "" "\n" "\n" "if __name__ == '__main__':\n" -" with entrypoint(log_level=\"info\", log_format=\"color\") as loop:\n" +" with aiomisc.entrypoint(log_level=\"info\", log_format=\"color\") as " +"loop:\n" " loop.run_until_complete(main())" msgstr "" -#: ../../source/index.rst:157 +#: ../../source/index.rst:154 msgid "" -"This code declares an asynchronous ``main()`` function that exits after 3" -" seconds. It would seem nothing interesting, but the whole point is in " -"the ``entrypoint``." +"This code declares an asynchronous ``main()`` function that exits for 3 " +"seconds. It would seem nothing interesting, but the whole point is in the" +" ``entrypoint``." msgstr "" "Этот код объявляет асинхронную функцию ``main()``, которая завершается " "через 3 секунды. Казалось бы, ничего интересного, но все дело в " "``entrypoint``." -#: ../../source/index.rst:161 +#: ../../source/index.rst:158 + msgid "" -"What does the ``entrypoint`` do, it would seem not so much, it creates an" -" event-loop and transfers control to the user. However, under the hood, " +"At the first glance the ``entrypoint`` did not do much, just creates an " +"event-loop and transfers control to the user. However, under the hood, " "the logger is configured in a separate thread, a pool of threads is " -"created, services are started, but more on that later and there are no " +"created, services are started, but more on that later as there are no " "services in this example." msgstr "" "Что делает ``entrypoint``, казалось бы не так уж и много, она создает " @@ -285,15 +281,15 @@ msgstr "" "настраивается журналирование в отдельном потоке, создается пул потоков, " "запускаются сервисы, но об этом позже и сервисов в данном примере нет." -#: ../../source/index.rst:167 +#: ../../source/index.rst:164 msgid "" -"Alternatively, you can choose not to use an entrypoint, just create an " -"event-loop and set this as a default event loop for current thread:" +"Alternatively, you can choose not to use an ``entrypoint``, just create " +"an event-loop and set it as a default for current thread:" msgstr "" "В принципе вы можете не использовать точку входа, а просто создать " "eventloop и установите его по умолчанию для текущего потока:" -#: ../../source/index.rst:170 +#: ../../source/index.rst:167 msgid "" "import asyncio\n" "import aiomisc\n" @@ -313,7 +309,7 @@ msgid "" " loop.run_until_complete(main())" msgstr "" -#: ../../source/index.rst:189 +#: ../../source/index.rst:186 msgid "" "The example above is useful if your code is already using an implicitly " "created event loop, you will have to modify less code, just add " @@ -325,7 +321,7 @@ msgstr "" "кода, просто добавьте ``aiomisc.new_event_loop()`` и все вызовы " "``asyncio.get_event_loop()`` вернет созданный экземпляр." -#: ../../source/index.rst:194 +#: ../../source/index.rst:191 msgid "" "However, you can do with one call. Following example closes implicitly " "created asyncio event loop and install a new one:" @@ -333,7 +329,7 @@ msgstr "" "Однако можно обойтись и одним вызовом. Следующий пример закрывает неявно " "созданный eventloop asyncio и устанавливает новый:" -#: ../../source/index.rst:197 +#: ../../source/index.rst:194 msgid "" "import asyncio\n" "import aiomisc\n" @@ -346,11 +342,11 @@ msgid "" " loop.run_until_complete(main())" msgstr "" -#: ../../source/index.rst:211 +#: ../../source/index.rst:208 msgid "Services" msgstr "Сервисы" -#: ../../source/index.rst:213 +#: ../../source/index.rst:210 msgid "" "The main thing that an ``entrypoint`` does is start and gracefully stop " "services." @@ -358,7 +354,7 @@ msgstr "" "Главное, что делает точка входа, — это запускает и корректно " "останавливает «Сервисы»." -#: ../../source/index.rst:216 +#: ../../source/index.rst:213 msgid "" "The service concept within this library means a class derived from the " "``aiosmic.Service`` class and implementing the ``async def start(self) ->" @@ -370,7 +366,7 @@ msgstr "" " None`` и, опционально, метод ``async def stop(self, exc: Optional[ " "Exception]) -> None``." -#: ../../source/index.rst:221 +#: ../../source/index.rst:218 msgid "" "The concept of stopping a service is not necessarily is pressing " "``Ctrl+C`` keys by user, it's actually just exiting the ``entrypoint`` " @@ -380,11 +376,11 @@ msgstr "" "пользователем клавиш ``Ctrl+C``, на самом деле это просто выход из " "контекстного менеджера ``entrypoint``." -#: ../../source/index.rst:224 +#: ../../source/index.rst:221 msgid "The example below shows what your service might look like:" msgstr "Пример ниже иллюстрирует, как может выглядеть ваш сервис:" -#: ../../source/index.rst:226 +#: ../../source/index.rst:223 msgid "" "from aiomisc import entrypoint, Service\n" "\n" @@ -400,7 +396,7 @@ msgid "" " loop.run_forever()" msgstr "" -#: ../../source/index.rst:241 +#: ../../source/index.rst:238 msgid "" "The entry point can start as many instances of the service as it likes, " "and all of them will start concurrently." @@ -408,7 +404,7 @@ msgstr "" "Точка входа может запускать любое количество экземпляров службы, и все " "они будут запускаться конкурентно." -#: ../../source/index.rst:244 +#: ../../source/index.rst:241 msgid "" "There is also a way if the ``start`` method is a payload for a service, " "and then there is no need to implement the stop method, since the running" @@ -422,11 +418,11 @@ msgstr "" " Но в этом случае вам придется уведомить ``entrypoint`` о том, что " "инициализация экземпляра службы завершена и ее можно продолжить." -#: ../../source/index.rst:250 +#: ../../source/index.rst:247 msgid "Like this:" msgstr "Примерно так:" -#: ../../source/index.rst:252 +#: ../../source/index.rst:249 msgid "" "import asyncio\n" "from threading import Event\n" @@ -445,7 +441,7 @@ msgid "" " assert event.is_set()" msgstr "" -#: ../../source/index.rst:272 +#: ../../source/index.rst:269 msgid "" "The ``entrypoint`` passes control to the body of the context manager only" " after all service instances have started. As mentioned above, a start is" @@ -457,7 +453,7 @@ msgstr "" "стартом считается завершение метода ``start`` или установка стартового " "события с помощью ``self.start_event.set()``." -#: ../../source/index.rst:277 +#: ../../source/index.rst:274 msgid "" "The whole power of this library is in the set of already implemented or " "abstract services. Such as: :ref:`AIOHTTPService `, " @@ -473,7 +469,7 @@ msgstr "" ":ref:`PeriodicService `, :ref:`CronService ` и так далее." -#: ../../source/index.rst:285 +#: ../../source/index.rst:282 msgid "" "Unfortunately in this section it is not possible to pay more attention to" " this, please pay attention to the :doc:`/tutorial` section section, " @@ -489,35 +485,35 @@ msgstr "" "исходный код максимально понятным и простым, поэтому не стесняйтесь " "исследовать его." -#: ../../source/index.rst:293 +#: ../../source/index.rst:290 msgid "Versioning" msgstr "Версионирование" -#: ../../source/index.rst:295 +#: ../../source/index.rst:292 msgid "This software follows `Semantic Versioning`_" msgstr "" "Это программное обеспечение следует методологиии `Семантического " "Версионирования`_" -#: ../../source/index.rst:298 +#: ../../source/index.rst:295 msgid "Summary: it's given a version number MAJOR.MINOR.PATCH, increment the:" msgstr "Кратко: учитывая номер версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ, следует увеличивать:" -#: ../../source/index.rst:300 +#: ../../source/index.rst:297 msgid "MAJOR version when you make incompatible API changes" msgstr "МАЖОРНУЮ версию, когда сделаны обратно несовместимые изменения API." -#: ../../source/index.rst:301 +#: ../../source/index.rst:298 msgid "MINOR version when you add functionality in a backwards compatible manner" msgstr "" "МИНОРНУЮ версию, когда вы добавляете новую функциональность, не нарушая " "обратной совместимости." -#: ../../source/index.rst:302 +#: ../../source/index.rst:299 msgid "PATCH version when you make backwards compatible bug fixes" msgstr "ПАТЧ-версию, когда вы делаете обратно совместимые исправления." -#: ../../source/index.rst:303 +#: ../../source/index.rst:300 msgid "" "Additional labels for pre-release and build metadata are available as " "extensions to the MAJOR.MINOR.PATCH format." @@ -525,7 +521,7 @@ msgstr "" "Дополнительные обозначения для предрелизных и билд-метаданных возможны " "как дополнения к МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ формату." -#: ../../source/index.rst:306 +#: ../../source/index.rst:303 msgid "" "In this case, the package version is assigned automatically with poem-" "plugins_, it using on the tag in the repository as a major and minor and " @@ -536,11 +532,11 @@ msgstr "" "plugins_, он использует тег в репозитории как МАЖОР и МИНОР, а также " "счетчик, который берет количество коммитов между тегом и головой ветки." -#: ../../source/index.rst:314 +#: ../../source/index.rst:311 msgid "How to develop?" msgstr "Как разрабатывать этот проект?" -#: ../../source/index.rst:316 +#: ../../source/index.rst:313 msgid "" "This project, like most open source projects, is developed by " "enthusiasts, you can join the development, submit issues, or send your " @@ -550,7 +546,7 @@ msgstr "" "энтузиастами, и вы можете присоединиться к разработке, создавайте issues " "в github или присылайте свои правки как merge request." -#: ../../source/index.rst:319 +#: ../../source/index.rst:316 msgid "" "In order to start developing in this repository, you need to do the " "following things." @@ -558,26 +554,22 @@ msgstr "" "Чтобы начать разработку в этом репозитории, вам необходимо сделать " "следующее:" -#: ../../source/index.rst:322 +#: ../../source/index.rst:319 msgid "Should be installed:" msgstr "Должно быть установлено" -#: ../../source/index.rst:324 +#: ../../source/index.rst:321 msgid "Python 3.7+ as ``python3``" msgstr "Python 3.7+ как ``python3``" -#: ../../source/index.rst:325 +#: ../../source/index.rst:322 msgid "Installed Poetry_ as ``poetry``" msgstr "Установлен Poetry_ как ``poetry``" -#: ../../source/index.rst:329 +#: ../../source/index.rst:326 msgid "For setting up developer environment just execute:" msgstr "Для настройки окружения разработчика выполните:" -#: ../../source/index.rst:331 +#: ../../source/index.rst:328 msgid "poetry install" msgstr "" - -#: ../../source/index.rst:339 -msgid "Table Of Contents" -msgstr "Содержание" diff --git a/docs/source/locale/ru/LC_MESSAGES/services.po b/docs/source/locale/ru/LC_MESSAGES/services.po index 434e395e..80997f98 100644 --- a/docs/source/locale/ru/LC_MESSAGES/services.po +++ b/docs/source/locale/ru/LC_MESSAGES/services.po @@ -754,9 +754,8 @@ msgid "requires installed aiohttp:" msgstr "требуется установленная библиотека aiohttp" #: ../../source/services.rst:548 -#, fuzzy msgid "pip install aiohttp" -msgstr "требуется установленная библиотека aiohttp" +msgstr "" #: ../../source/services.rst:554 msgid "pip install aiomisc[aiohttp]" @@ -825,9 +824,8 @@ msgid "requires installed aiohttp-asgi:" msgstr "требуется установленная библиотека aiohttp-asgi:" #: ../../source/services.rst:614 -#, fuzzy msgid "pip install aiohttp-asgi" -msgstr "требуется установленная библиотека aiohttp-asgi:" +msgstr "" #: ../../source/services.rst:620 msgid "pip install aiomisc[asgi]" diff --git a/docs/source/locale/ru/LC_MESSAGES/signal.po b/docs/source/locale/ru/LC_MESSAGES/signal.po index 00de0ef1..7864df0e 100644 --- a/docs/source/locale/ru/LC_MESSAGES/signal.po +++ b/docs/source/locale/ru/LC_MESSAGES/signal.po @@ -76,9 +76,8 @@ msgid "" msgstr "" #: ../../source/signal.rst:42 -#, fuzzy msgid "``pre_stop``" -msgstr "pre_stop" +msgstr "" #: ../../source/signal.rst:44 msgid "" diff --git a/poetry.lock b/poetry.lock index 9fa5c113..e284b8f5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -158,14 +158,14 @@ frozenlist = ">=1.1.0" [[package]] name = "alabaster" -version = "0.7.12" +version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, - {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] [[package]] @@ -616,14 +616,14 @@ testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest (>=7.2)", "pyt [[package]] name = "freezegun" -version = "1.0.0" +version = "1.2.2" description = "Let your Python tests travel through time" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "freezegun-1.0.0-py2.py3-none-any.whl", hash = "sha256:02b35de52f4699a78f6ac4518e4cd3390dddc43b0aeb978335a8f270a2d9668b"}, - {file = "freezegun-1.0.0.tar.gz", hash = "sha256:1cf08e441f913ff5e59b19cc065a8faa9dd1ddc442eaf0375294f344581a0643"}, + {file = "freezegun-1.2.2-py3-none-any.whl", hash = "sha256:ea1b963b993cb9ea195adbd893a48d573fda951b0da64f60883d7e988b606c9f"}, + {file = "freezegun-1.2.2.tar.gz", hash = "sha256:cd22d1ba06941384410cd967d8a99d5ae2442f57dfafeff2fda5de8dc5c05446"}, ] [package.dependencies] @@ -733,14 +733,14 @@ sphinx-basic-ng = "*" [[package]] name = "identify" -version = "2.5.11" +version = "2.5.13" description = "File identification library for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "identify-2.5.11-py2.py3-none-any.whl", hash = "sha256:e7db36b772b188099616aaf2accbee122949d1c6a1bac4f38196720d6f9f06db"}, - {file = "identify-2.5.11.tar.gz", hash = "sha256:14b7076b29c99b1b0b8b08e96d448c7b877a9b07683cd8cfda2ea06af85ffa1c"}, + {file = "identify-2.5.13-py2.py3-none-any.whl", hash = "sha256:8aa48ce56e38c28b6faa9f261075dea0a942dfbb42b341b4e711896cbb40f3f7"}, + {file = "identify-2.5.13.tar.gz", hash = "sha256:abb546bca6f470228785338a01b539de8a85bbf46491250ae03363956d8ebb10"}, ] [package.extras] @@ -772,14 +772,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "5.2.0" +version = "4.13.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-5.2.0-py3-none-any.whl", hash = "sha256:0eafa39ba42bf225fc00e67f701d71f85aead9f878569caf13c3724f704b970f"}, - {file = "importlib_metadata-5.2.0.tar.gz", hash = "sha256:404d48d62bba0b7a77ff9d405efd91501bef2e67ff4ace0bed40a0cf28c3c7cd"}, + {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"}, + {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"}, ] [package.dependencies] @@ -787,20 +787,20 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] perf = ["ipython"] testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] @@ -851,52 +851,62 @@ files = [ [[package]] name = "markupsafe" -version = "2.1.1" +version = "2.1.2" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, - {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, + {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, ] [[package]] @@ -1076,14 +1086,14 @@ setuptools = "*" [[package]] name = "packaging" -version = "22.0" +version = "23.0" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-22.0-py3-none-any.whl", hash = "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3"}, - {file = "packaging-22.0.tar.gz", hash = "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3"}, + {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, + {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, ] [[package]] @@ -1170,52 +1180,52 @@ files = [ [[package]] name = "pydantic" -version = "1.10.3" +version = "1.10.4" description = "Data validation and settings management using python type hints" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef012251ca6bc899f0b5a9239c527dec30915462f35c3a58aab6ddff09708484"}, - {file = "pydantic-1.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:810e1510da10bc6c59300221ba55e17cfb7b62279fe87c6466f9e293975a6dd5"}, - {file = "pydantic-1.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a83e92f7311c703fb1d64dba81d1e374786465a4e260b0616f731401e1f875a8"}, - {file = "pydantic-1.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4efd2e1f63cdd0877e24ca5d5edd7dc65a24b915da04e67b1fe485a0f7f3508"}, - {file = "pydantic-1.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d15d22b5d666b7b610d9a99a73de6b27be8982ee3af4de0cb32586ee72557f25"}, - {file = "pydantic-1.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d29e5353593117937901a6329c7295955eacbf4856a0c01da5319f416ad18967"}, - {file = "pydantic-1.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:106302e18978c22c51b013d347db6ef5589776137663b16dc77ea3162bc82711"}, - {file = "pydantic-1.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85e48eb95c39a5fd4500d148e8330d878fafe9e3eca6c253bdf0bd0af2b71371"}, - {file = "pydantic-1.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9862e881689e1c067c11b307513465e6509647f9f10e3c48d100120351449087"}, - {file = "pydantic-1.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21cca3b77f9a7a69f51991e26780427396226a5a576c72635e25b8439dd0170"}, - {file = "pydantic-1.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df2fa7102d1bec588d360833777d47772ce7f6aecc0335be43de710a8d034f42"}, - {file = "pydantic-1.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f7eb71ad9fb1f6911ca2b7010039a9d61a3f14bd4f60a1c57e9250f8d87375fb"}, - {file = "pydantic-1.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:762a6560e6d31d0a5558ee95cdece616dd6d92c94e3a9a41fb46f2d733a66f49"}, - {file = "pydantic-1.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:38dc429316685a3b13ca008c907e2cc9e164068e49612b5284d7cbb01504c3a3"}, - {file = "pydantic-1.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:000a7d934e182f6e368340382338dea5423b0503a3a5cafd3f2b75e684fe67f2"}, - {file = "pydantic-1.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec151222823911a72aeb3c855947fe10b31e718484b233eb7d2d98a5df3d3c7b"}, - {file = "pydantic-1.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a63805997d1ab9082c2c89017d3368369689660a35a7d8a8fccb67f77d5cf4d8"}, - {file = "pydantic-1.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5fa3374562b3d4ea45bdff711c01854e5ce6c9ca9e2f37a6e94313412249000e"}, - {file = "pydantic-1.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bf121ec413f943803e9401fae0e58898bf9e68a97bdd9eea4d055499936a2e75"}, - {file = "pydantic-1.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:e580ec5dcb7ff6861ef2de3b7c8a9af4112691bebd392221ed70de57fe846ae9"}, - {file = "pydantic-1.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:495ad4077575e2629f775a7635c4f383d279b3de2439880b76ce27758db98902"}, - {file = "pydantic-1.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cf20586026691c7aa59f0372488a75699194ab6ff7142577d585272b45e12ba"}, - {file = "pydantic-1.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f918f2dcd740ac3b2603a1a8bf091a151385a31d02fac5903a2bbf2336d2025"}, - {file = "pydantic-1.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddcec93519cb0ea63d0d7e8462042b46191020f862b88302815586707f4e8acc"}, - {file = "pydantic-1.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3701a2971a8d0c7274b28a2d3fa9146390a51e7ffda4bc2406d10fda64d6f727"}, - {file = "pydantic-1.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e8b895bf2faf61dba6ab9990e01e99d0b96e3d6a23e810d85060a51fbc27e1dc"}, - {file = "pydantic-1.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:85bbea6c5b9bbd07532a875ab09a6d4987d89eb5566c6b8d2cc60f2dcdec5300"}, - {file = "pydantic-1.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0627a759a14dc47cdca10e3590c86df368d96b46b23db44c986286656007d253"}, - {file = "pydantic-1.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9197d3f22eefa113bcb0564cfc5812ccf889aaff08a6459c9ed04796b8f88c14"}, - {file = "pydantic-1.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aef6dc6b7c6ae2dea27eea5fde6b5c766397a6c765c19414713dbc832a245d"}, - {file = "pydantic-1.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac2a986c200c1739ce1a358d545f133d3a50b896c88c0c02a35c661120d85692"}, - {file = "pydantic-1.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9ee33436a271e46ed3be422cb23f8c75c2dce53abf7259b7dd173ed1b7cabb66"}, - {file = "pydantic-1.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e7c2d9ffca1124e751db9ae529968dbbcefd0b8db69ce958bb7cf777716e7b8"}, - {file = "pydantic-1.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:6804f70ebf7e1d37bf8e0d0baf2bee20e3b07229b600db4c46eddd5f3738308a"}, - {file = "pydantic-1.10.3-py3-none-any.whl", hash = "sha256:c50085e5ebd9da2e7d67353969185f6a6c190ed4142f93a46aa294c8213c466a"}, - {file = "pydantic-1.10.3.tar.gz", hash = "sha256:01d450f1b6a642c98f58630e807f7554df0a8ce669ffaff087ce9e1fd4ff7ec8"}, + {file = "pydantic-1.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5635de53e6686fe7a44b5cf25fcc419a0d5e5c1a1efe73d49d48fe7586db854"}, + {file = "pydantic-1.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6dc1cc241440ed7ca9ab59d9929075445da6b7c94ced281b3dd4cfe6c8cff817"}, + {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51bdeb10d2db0f288e71d49c9cefa609bca271720ecd0c58009bd7504a0c464c"}, + {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78cec42b95dbb500a1f7120bdf95c401f6abb616bbe8785ef09887306792e66e"}, + {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8775d4ef5e7299a2f4699501077a0defdaac5b6c4321173bcb0f3c496fbadf85"}, + {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:572066051eeac73d23f95ba9a71349c42a3e05999d0ee1572b7860235b850cc6"}, + {file = "pydantic-1.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:7feb6a2d401f4d6863050f58325b8d99c1e56f4512d98b11ac64ad1751dc647d"}, + {file = "pydantic-1.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39f4a73e5342b25c2959529f07f026ef58147249f9b7431e1ba8414a36761f53"}, + {file = "pydantic-1.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:983e720704431a6573d626b00662eb78a07148c9115129f9b4351091ec95ecc3"}, + {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d52162fe6b2b55964fbb0af2ee58e99791a3138588c482572bb6087953113a"}, + {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdf8d759ef326962b4678d89e275ffc55b7ce59d917d9f72233762061fd04a2d"}, + {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05a81b006be15655b2a1bae5faa4280cf7c81d0e09fcb49b342ebf826abe5a72"}, + {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d88c4c0e5c5dfd05092a4b271282ef0588e5f4aaf345778056fc5259ba098857"}, + {file = "pydantic-1.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:6a05a9db1ef5be0fe63e988f9617ca2551013f55000289c671f71ec16f4985e3"}, + {file = "pydantic-1.10.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:887ca463c3bc47103c123bc06919c86720e80e1214aab79e9b779cda0ff92a00"}, + {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdf88ab63c3ee282c76d652fc86518aacb737ff35796023fae56a65ced1a5978"}, + {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a48f1953c4a1d9bd0b5167ac50da9a79f6072c63c4cef4cf2a3736994903583e"}, + {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a9f2de23bec87ff306aef658384b02aa7c32389766af3c5dee9ce33e80222dfa"}, + {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cd8702c5142afda03dc2b1ee6bc358b62b3735b2cce53fc77b31ca9f728e4bc8"}, + {file = "pydantic-1.10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6e7124d6855b2780611d9f5e1e145e86667eaa3bd9459192c8dc1a097f5e9903"}, + {file = "pydantic-1.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b53e1d41e97063d51a02821b80538053ee4608b9a181c1005441f1673c55423"}, + {file = "pydantic-1.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:55b1625899acd33229c4352ce0ae54038529b412bd51c4915349b49ca575258f"}, + {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:301d626a59edbe5dfb48fcae245896379a450d04baeed50ef40d8199f2733b06"}, + {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6f9d649892a6f54a39ed56b8dfd5e08b5f3be5f893da430bed76975f3735d15"}, + {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7b5a3821225f5c43496c324b0d6875fde910a1c2933d726a743ce328fbb2a8c"}, + {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f2f7eb6273dd12472d7f218e1fef6f7c7c2f00ac2e1ecde4db8824c457300416"}, + {file = "pydantic-1.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:4b05697738e7d2040696b0a66d9f0a10bec0efa1883ca75ee9e55baf511909d6"}, + {file = "pydantic-1.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a9a6747cac06c2beb466064dda999a13176b23535e4c496c9d48e6406f92d42d"}, + {file = "pydantic-1.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb992a1ef739cc7b543576337bebfc62c0e6567434e522e97291b251a41dad7f"}, + {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:990406d226dea0e8f25f643b370224771878142155b879784ce89f633541a024"}, + {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e82a6d37a95e0b1b42b82ab340ada3963aea1317fd7f888bb6b9dfbf4fff57c"}, + {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9193d4f4ee8feca58bc56c8306bcb820f5c7905fd919e0750acdeeeef0615b28"}, + {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2b3ce5f16deb45c472dde1a0ee05619298c864a20cded09c4edd820e1454129f"}, + {file = "pydantic-1.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9cbdc268a62d9a98c56e2452d6c41c0263d64a2009aac69246486f01b4f594c4"}, + {file = "pydantic-1.10.4-py3-none-any.whl", hash = "sha256:4948f264678c703f3877d1c8877c4e3b2e12e549c57795107f08cf70c6ec7774"}, + {file = "pydantic-1.10.4.tar.gz", hash = "sha256:b9a3859f24eb4e097502a3be1fb4b2abb79b6103dd9e2e0edb70613a4459a648"}, ] [package.dependencies] -typing-extensions = ">=4.1.0" +typing-extensions = ">=4.2.0" [package.extras] dotenv = ["python-dotenv (>=0.10.4)"] @@ -1223,21 +1233,22 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pydocstyle" -version = "6.1.1" +version = "6.3.0" description = "Python docstring style checker" category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, - {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, + {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, + {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, ] [package.dependencies] -snowballstemmer = "*" +importlib-metadata = {version = ">=2.0.0,<5.0.0", markers = "python_version < \"3.8\""} +snowballstemmer = ">=2.2.0" [package.extras] -toml = ["toml"] +toml = ["tomli (>=1.2.3)"] [[package]] name = "pyflakes" @@ -1253,14 +1264,14 @@ files = [ [[package]] name = "pygments" -version = "2.13.0" +version = "2.14.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, - {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, + {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, + {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, ] [package.extras] @@ -1296,14 +1307,14 @@ vulture = ["vulture"] [[package]] name = "pytest" -version = "7.2.0" +version = "7.2.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, - {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, + {file = "pytest-7.2.1-py3-none-any.whl", hash = "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5"}, + {file = "pytest-7.2.1.tar.gz", hash = "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42"}, ] [package.dependencies] @@ -1403,14 +1414,14 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2022.7" +version = "2022.7.1" description = "World timezone definitions, modern and historical" category = "dev" optional = false python-versions = "*" files = [ - {file = "pytz-2022.7-py2.py3-none-any.whl", hash = "sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd"}, - {file = "pytz-2022.7.tar.gz", hash = "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a"}, + {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, + {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, ] [[package]] @@ -1481,19 +1492,19 @@ tests = ["Flask (>=0.8)", "Flask-Login (>=0.2.0)", "ZConfig", "aiohttp", "anyjso [[package]] name = "requests" -version = "2.28.1" +version = "2.28.2" description = "Python HTTP for Humans." category = "dev" optional = false python-versions = ">=3.7, <4" files = [ - {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, - {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, + {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, + {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, ] [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = ">=2,<3" +charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" @@ -1608,18 +1619,18 @@ test = ["pytest"] [[package]] name = "setuptools" -version = "65.6.3" +version = "66.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"}, - {file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"}, + {file = "setuptools-66.0.0-py3-none-any.whl", hash = "sha256:a78d01d1e2c175c474884671dde039962c9d74c7223db7369771fcf6e29ceeab"}, + {file = "setuptools-66.0.0.tar.gz", hash = "sha256:bd6eb2d6722568de6d14b87c44a96fac54b2a45ff5e940e639979a3d1792adb6"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] @@ -1960,28 +1971,43 @@ files = [ [[package]] name = "types-croniter" -version = "1.3.2.1" +version = "1.3.2.2" description = "Typing stubs for croniter" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-croniter-1.3.2.1.tar.gz", hash = "sha256:1f0a14b9465471f460640de935e8e4a9b3fe90537ff1f287594e6e53f3ff6b86"}, - {file = "types_croniter-1.3.2.1-py3-none-any.whl", hash = "sha256:469e795a71f45fd2895af3accfccfbf337c9df364fcc23a8768417cbf1447339"}, + {file = "types-croniter-1.3.2.2.tar.gz", hash = "sha256:c9faac268046df4c4a7c9df3632e743f531711568d09bffc3a99621ad1e8594d"}, + {file = "types_croniter-1.3.2.2-py3-none-any.whl", hash = "sha256:46ce48b34ef47ccba78bf6df69ec2cf1059dd135802123a14d51f50b3934fc1a"}, +] + +[[package]] +name = "types-docutils" +version = "0.19.1.2" +description = "Typing stubs for docutils" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "types-docutils-0.19.1.2.tar.gz", hash = "sha256:ca3d2135484adb52dd042bbddbd6eddcbbda8c608ba3f5e5f908bd548ffcb399"}, + {file = "types_docutils-0.19.1.2-py3-none-any.whl", hash = "sha256:7be44dac1b160901308ac43762d5e89175105ed682092a3a1f08911d2573a470"}, ] [[package]] name = "types-setuptools" -version = "65.6.0.2" +version = "65.7.0.3" description = "Typing stubs for setuptools" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-setuptools-65.6.0.2.tar.gz", hash = "sha256:ad60ccf01d626de9762224448f36c13e0660e863afd6dc11d979b3739a6c7d24"}, - {file = "types_setuptools-65.6.0.2-py3-none-any.whl", hash = "sha256:2c2b4f756f79778074ce2d21f745aa737b12160d9f8dfa274f47a7287c7a2fee"}, + {file = "types-setuptools-65.7.0.3.tar.gz", hash = "sha256:c00f2dd1e6dcbb893faea4a57dbae80bb96d826b865d9ade8ae250a830cba10c"}, + {file = "types_setuptools-65.7.0.3-py3-none-any.whl", hash = "sha256:b823969ea92a6d41d35933881d4c732248df834062e0d6f044c3eb36c446254e"}, ] +[package.dependencies] +types-docutils = "*" + [[package]] name = "typing-extensions" version = "4.4.0" @@ -1996,14 +2022,14 @@ files = [ [[package]] name = "urllib3" -version = "1.26.13" +version = "1.26.14" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, - {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, + {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, + {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, ] [package.extras] @@ -2248,4 +2274,4 @@ uvloop = [] [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "66f7693da6c5fadd973d50b2d381906ff979d1781e560713d7d27819dce04333" +content-hash = "1a8cd1f5e8f849a459108e8318b9c09434c9adc0737ecdbc54f80150126fa860" diff --git a/pyproject.toml b/pyproject.toml index 9df11818..beee676a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,6 @@ collective-checkdocs = "^0.2" coveralls = "^3.3.1" croniter = "^1.3.8" fastapi = "^0.88.0" -freezegun = "<1.1" mypy = "^0.991" pre-commit = "^2.20.0" pytest = "^7.2.0" From cf5e1145bad833b9c2486007cfe95bc5a96da8fd Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 18:31:47 +0300 Subject: [PATCH 40/45] Fix tests --- aiomisc/io.py | 62 ++---- docs/source/io.rst | 9 +- .../locale/ru/LC_MESSAGES/api/aiomisc.po | 202 ++++++++++-------- docs/source/locale/ru/LC_MESSAGES/io.po | 69 ++++-- tests/test_io.py | 6 +- 5 files changed, 191 insertions(+), 157 deletions(-) diff --git a/aiomisc/io.py b/aiomisc/io.py index 8573e7b3..20221c5c 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -266,46 +266,40 @@ def buffer(self) -> AsyncBinaryIO: AsyncTextFileIO = AsyncTextIO -class GzipIOMixin(Generic[AnyStr]): +class AsyncGzipBinaryIO(AsyncBytesFileIO): @staticmethod def get_opener() -> Callable[..., IO[AnyStr]]: - return gzip.open # type: ignore + return gzip.open # type: ignore -class AsyncGzipBinaryIO(AsyncBytesFileIO, GzipIOMixin[bytes]): - pass - - -class AsyncGzipTextIO(AsyncTextFileIO, GzipIOMixin[str]): - pass - - -class Bz2IOMixin(Generic[AnyStr]): +class AsyncGzipTextIO(AsyncTextFileIO): @staticmethod def get_opener() -> Callable[..., IO[AnyStr]]: - return bz2.open - + return gzip.open # type: ignore -class AsyncBz2BinaryIO(AsyncBytesFileIO, Bz2IOMixin[bytes]): - pass - -class AsyncBz2TextIO(AsyncTextFileIO, Bz2IOMixin[str]): - pass +class AsyncBz2BinaryIO(AsyncBytesFileIO): + @staticmethod + def get_opener() -> Callable[..., IO[AnyStr]]: + return bz2.open # type: ignore -class LzmaIOMixin(Generic[AnyStr]): +class AsyncBz2TextIO(AsyncTextFileIO): @staticmethod def get_opener() -> Callable[..., IO[AnyStr]]: - return lzma.open + return bz2.open # type: ignore -class AsyncLzmaBinaryIO(AsyncBytesFileIO, LzmaIOMixin[bytes]): - pass +class AsyncLzmaBinaryIO(AsyncBytesFileIO): + @staticmethod + def get_opener() -> Callable[..., IO[AnyStr]]: + return lzma.open # type: ignore -class AsyncLzmaTextIO(AsyncTextFileIO, LzmaIOMixin[str]): - pass +class AsyncLzmaTextIO(AsyncTextFileIO): + @staticmethod + def get_opener() -> Callable[..., IO[AnyStr]]: + return lzma.open # type: ignore class Compression(Enum): @@ -315,21 +309,9 @@ class Compression(Enum): LZMA = (AsyncLzmaBinaryIO, AsyncLzmaTextIO) -AsyncBinaryIOType = Union[ - AsyncBinaryIO, - AsyncBz2BinaryIO, - AsyncGzipBinaryIO, - AsyncLzmaBinaryIO, -] - -AsyncTextIOType = Union[ - AsyncBz2TextIO, - AsyncGzipTextIO, - AsyncLzmaTextIO, - AsyncTextIO, -] +AsyncFileType = Union[AsyncFileIO[AnyStr], AsyncTextIO, AsyncBinaryIO] -AsyncFileType = Union[AsyncBinaryIOType, AsyncTextIOType] +# Deprecated excluded from __all__ AsyncFileT = AsyncFileType @@ -338,7 +320,7 @@ def async_open( compression: Compression = Compression.NONE, encoding: str = sys.getdefaultencoding(), *args: Any, **kwargs: Any, -) -> AsyncFileIO[AnyStr]: +) -> AsyncFileType: binary_io_class, text_io_class = compression.value if "b" in mode: @@ -354,7 +336,7 @@ def async_open( "AsyncBinaryIO", "AsyncBz2BinaryIO", "AsyncBz2TextIO", - "AsyncFileT", + "AsyncFileIO", "AsyncFileType", "AsyncGzipBinaryIO", "AsyncGzipTextIO", diff --git a/docs/source/io.rst b/docs/source/io.rst index 415b6ca4..63f0b7af 100644 --- a/docs/source/io.rst +++ b/docs/source/io.rst @@ -16,6 +16,12 @@ Based on the thread pool under the hood. with tempfile.TemporaryDirectory() as tmp: fname = Path(tmp) / 'test.txt' + # Some tools, such as mypy, will not be able to infer the type + # from the `async_open` function based on the `b` character passed + # to the mode. + # We'll have to tell the type here explicitly. + afp: aiomisc.io.AsyncTextIO + async with aiomisc.io.async_open(fname, 'w+') as afp: await afp.write("Hello") await afp.write(" ") @@ -132,7 +138,8 @@ An example of usage: for _ in range(10000): await afp.write("Hello World\n") - assert fname.stat().st_size < 10000 + file_size = fname.stat().st_size + assert file_size < 10000, f"File too large {file_size} bytes" run(file_write()) diff --git a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po index 8841e8a5..3f4298ce 100644 --- a/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po +++ b/docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: aiomisc 16.1.16\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-01-20 13:36+0300\n" +"POT-Creation-Date: 2023-01-20 17:50+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -307,100 +307,6 @@ msgstr "" msgid "``aiomisc.io`` module" msgstr "Модуль ``aiomisc.io``" -#: bz2.open:1 of -msgid "Open a bzip2-compressed file in binary or text mode." -msgstr "" - -#: bz2.open:3 of -msgid "" -"The filename argument can be an actual filename (a str, bytes, or " -"PathLike object), or an existing file object to read from or write to." -msgstr "" - -#: bz2.open:7 gzip.open:6 of -msgid "" -"The mode argument can be \"r\", \"rb\", \"w\", \"wb\", \"x\", \"xb\", " -"\"a\" or \"ab\" for binary mode, or \"rt\", \"wt\", \"xt\" or \"at\" for " -"text mode. The default mode is \"rb\", and the default compresslevel is " -"9." -msgstr "" - -#: bz2.open:11 of -msgid "" -"For binary mode, this function is equivalent to the BZ2File constructor: " -"BZ2File(filename, mode, compresslevel). In this case, the encoding, " -"errors and newline arguments must not be provided." -msgstr "" - -#: bz2.open:15 of -msgid "" -"For text mode, a BZ2File object is created, and wrapped in an " -"io.TextIOWrapper instance with the specified encoding, error handling " -"behavior, and line ending(s)." -msgstr "" - -#: gzip.open:1 of -msgid "Open a gzip-compressed file in binary or text mode." -msgstr "" - -#: gzip.open:3 of -msgid "" -"The filename argument can be an actual filename (a str or bytes object), " -"or an existing file object to read from or write to." -msgstr "" - -#: gzip.open:10 of -msgid "" -"For binary mode, this function is equivalent to the GzipFile constructor:" -" GzipFile(filename, mode, compresslevel). In this case, the encoding, " -"errors and newline arguments must not be provided." -msgstr "" - -#: gzip.open:14 of -msgid "" -"For text mode, a GzipFile object is created, and wrapped in an " -"io.TextIOWrapper instance with the specified encoding, error handling " -"behavior, and line ending(s)." -msgstr "" - -#: lzma.open:1 of -msgid "Open an LZMA-compressed file in binary or text mode." -msgstr "" - -#: lzma.open:3 of -msgid "" -"filename can be either an actual file name (given as a str, bytes, or " -"PathLike object), in which case the named file is opened, or it can be an" -" existing file object to read from or write to." -msgstr "" - -#: lzma.open:7 of -msgid "" -"The mode argument can be \"r\", \"rb\" (default), \"w\", \"wb\", \"x\", " -"\"xb\", \"a\", or \"ab\" for binary mode, or \"rt\", \"wt\", \"xt\", or " -"\"at\" for text mode." -msgstr "" - -#: lzma.open:11 of -msgid "" -"The format, check, preset and filters arguments specify the compression " -"settings, as for LZMACompressor, LZMADecompressor and LZMAFile." -msgstr "" - -#: lzma.open:15 of -msgid "" -"For binary mode, this function is equivalent to the LZMAFile constructor:" -" LZMAFile(filename, mode, ...). In this case, the encoding, errors and " -"newline arguments must not be provided." -msgstr "" - -#: lzma.open:19 of -msgid "" -"For text mode, an LZMAFile object is created, and wrapped in an " -"io.TextIOWrapper instance with the specified encoding, error handling " -"behavior, and line ending(s)." -msgstr "" - #: ../../source/api/aiomisc.rst:68 msgid "``aiomisc.iterator_wrapper`` module" msgstr "Модуль ``aiomisc.iterator_wrapper``" @@ -925,3 +831,109 @@ msgstr "Модуль ``aiomisc.worker_pool``" #~ "used like a file opened in a " #~ "binary mode." #~ msgstr "" + +#~ msgid "Open a bzip2-compressed file in binary or text mode." +#~ msgstr "" + +#~ msgid "" +#~ "The filename argument can be an " +#~ "actual filename (a str, bytes, or " +#~ "PathLike object), or an existing file" +#~ " object to read from or write " +#~ "to." +#~ msgstr "" + +#~ msgid "" +#~ "The mode argument can be \"r\", " +#~ "\"rb\", \"w\", \"wb\", \"x\", \"xb\", " +#~ "\"a\" or \"ab\" for binary mode, " +#~ "or \"rt\", \"wt\", \"xt\" or \"at\" " +#~ "for text mode. The default mode is" +#~ " \"rb\", and the default compresslevel " +#~ "is 9." +#~ msgstr "" + +#~ msgid "" +#~ "For binary mode, this function is " +#~ "equivalent to the BZ2File constructor: " +#~ "BZ2File(filename, mode, compresslevel). In " +#~ "this case, the encoding, errors and " +#~ "newline arguments must not be provided." +#~ msgstr "" + +#~ msgid "" +#~ "For text mode, a BZ2File object is" +#~ " created, and wrapped in an " +#~ "io.TextIOWrapper instance with the specified" +#~ " encoding, error handling behavior, and " +#~ "line ending(s)." +#~ msgstr "" + +#~ msgid "Open a gzip-compressed file in binary or text mode." +#~ msgstr "" + +#~ msgid "" +#~ "The filename argument can be an " +#~ "actual filename (a str or bytes " +#~ "object), or an existing file object " +#~ "to read from or write to." +#~ msgstr "" + +#~ msgid "" +#~ "For binary mode, this function is " +#~ "equivalent to the GzipFile constructor: " +#~ "GzipFile(filename, mode, compresslevel). In " +#~ "this case, the encoding, errors and " +#~ "newline arguments must not be provided." +#~ msgstr "" + +#~ msgid "" +#~ "For text mode, a GzipFile object " +#~ "is created, and wrapped in an " +#~ "io.TextIOWrapper instance with the specified" +#~ " encoding, error handling behavior, and " +#~ "line ending(s)." +#~ msgstr "" + +#~ msgid "Open an LZMA-compressed file in binary or text mode." +#~ msgstr "" + +#~ msgid "" +#~ "filename can be either an actual " +#~ "file name (given as a str, bytes," +#~ " or PathLike object), in which case" +#~ " the named file is opened, or " +#~ "it can be an existing file object" +#~ " to read from or write to." +#~ msgstr "" + +#~ msgid "" +#~ "The mode argument can be \"r\", " +#~ "\"rb\" (default), \"w\", \"wb\", \"x\", " +#~ "\"xb\", \"a\", or \"ab\" for binary " +#~ "mode, or \"rt\", \"wt\", \"xt\", or " +#~ "\"at\" for text mode." +#~ msgstr "" + +#~ msgid "" +#~ "The format, check, preset and filters" +#~ " arguments specify the compression " +#~ "settings, as for LZMACompressor, " +#~ "LZMADecompressor and LZMAFile." +#~ msgstr "" + +#~ msgid "" +#~ "For binary mode, this function is " +#~ "equivalent to the LZMAFile constructor: " +#~ "LZMAFile(filename, mode, ...). In this " +#~ "case, the encoding, errors and newline" +#~ " arguments must not be provided." +#~ msgstr "" + +#~ msgid "" +#~ "For text mode, an LZMAFile object " +#~ "is created, and wrapped in an " +#~ "io.TextIOWrapper instance with the specified" +#~ " encoding, error handling behavior, and " +#~ "line ending(s)." +#~ msgstr "" diff --git a/docs/source/locale/ru/LC_MESSAGES/io.po b/docs/source/locale/ru/LC_MESSAGES/io.po index 5865563c..f36d5333 100644 --- a/docs/source/locale/ru/LC_MESSAGES/io.po +++ b/docs/source/locale/ru/LC_MESSAGES/io.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 14\n" "Report-Msgid-Bugs-To: me@mosquito.su\n" -"POT-Creation-Date: 2023-01-20 13:47+0300\n" +"POT-Creation-Date: 2023-01-20 17:50+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Orlov \n" "Language-Team: LANGUAGE \n" @@ -38,6 +38,13 @@ msgid "" " with tempfile.TemporaryDirectory() as tmp:\n" " fname = Path(tmp) / 'test.txt'\n" "\n" +" # Some tools, such as mypy, will not be able to infer the type\n" +" # from the `async_open` function based on the `b` character " +"passed\n" +" # to the mode.\n" +" # We'll have to tell the type here explicitly.\n" +" afp: aiomisc.io.AsyncTextIO\n" +"\n" " async with aiomisc.io.async_open(fname, 'w+') as afp:\n" " await afp.write(\"Hello\")\n" " await afp.write(\" \")\n" @@ -50,8 +57,34 @@ msgid "" "with aiomisc.entrypoint() as loop:\n" " loop.run_until_complete(file_write())" msgstr "" +"import aiomisc\n" +"import tempfile\n" +"from pathlib import Path\n" +"\n" +"\n" +"async def file_write():\n" +" with tempfile.TemporaryDirectory() as tmp:\n" +" fname = Path(tmp) / 'test.txt'\n" +"\n" +" # Некоторые инструменты, такие как mypy, не смогут вывести тип \n" +" # из функции async_open основываясь на переданном символе `b` в режим." +"\n" +" # Придется тут подсказать тип явно.\n" +" afp: aiomisc.io.AsyncTextIO\n" +"\n" +" async with aiomisc.io.async_open(fname, 'w+') as afp:\n" +" await afp.write(\"Hello\")\n" +" await afp.write(\" \")\n" +" await afp.write(\"world\")\n" +"\n" +" await afp.seek(0)\n" +" print(await afp.read())\n" +"\n" +"\n" +"with aiomisc.entrypoint() as loop:\n" +" loop.run_until_complete(file_write())" -#: ../../source/io.rst:32 +#: ../../source/io.rst:38 msgid "" "This is the way to working with files based on threads. It's very similar" " to `aiofiles`_ project and same limitations." @@ -59,7 +92,7 @@ msgstr "" "Этот способ работы с файлами основан на потоках. Это очень похоже на то " "как сделано в библиотеке `aiofiles`_ с теми-же ограничениями." -#: ../../source/io.rst:35 +#: ../../source/io.rst:41 msgid "" "Of course, you can use `aiofile`_ project for this. But it's not a silver" " bullet and has OS API-related limitations." @@ -68,7 +101,7 @@ msgstr "" " не панацея, так как имеет ограничения связанные с API операционной " "системы." -#: ../../source/io.rst:38 +#: ../../source/io.rst:44 msgid "" "In general, for light loads, I would advise you to adhere to the " "following rules:" @@ -76,7 +109,7 @@ msgstr "" "В основном, для небольших нагрузок приложений, я рекомендую " "придерживаться следующих правил:" -#: ../../source/io.rst:40 +#: ../../source/io.rst:46 msgid "" "If reading and writing small or big chunks from files with random access " "is the main task in your project, use `aiofile`_." @@ -84,11 +117,11 @@ msgstr "" "Если чтение и запись маленьких или больших кусочков в файлы со случайным " "доступом основная задача приложения - стоит использовать `aiofile`_." -#: ../../source/io.rst:42 +#: ../../source/io.rst:48 msgid "Otherwise use this module or `aiofiles`_" msgstr "Иначе можно взять этот модуль или `aiofiles`_" -#: ../../source/io.rst:43 +#: ../../source/io.rst:49 msgid "" "If the main task is to read large chunks of files for processing, both of" " the above methods are not optimal cause you will switch context each IO " @@ -106,7 +139,7 @@ msgstr "" "потоками может оказаться выше чем суммарно время исполнения всех IO " "операций." -#: ../../source/io.rst:51 +#: ../../source/io.rst:57 msgid "" "Just try pack all blocking staff in separate functions and call it in a " "thread pool, see the example bellow:" @@ -114,7 +147,7 @@ msgstr "" "Просто попробуйте завернуть все блокирующие вызовы в отдельные функции и " "вызывайте их используя пул потоков (см. пример ниже):" -#: ../../source/io.rst:54 +#: ../../source/io.rst:60 msgid "" "import os\n" "import aiomisc\n" @@ -161,11 +194,11 @@ msgid "" " )" msgstr "" -#: ../../source/io.rst:102 +#: ../../source/io.rst:108 msgid "In the fly compression" msgstr "Поточное сжатие" -#: ../../source/io.rst:104 +#: ../../source/io.rst:110 msgid "" "To enable compression, you need to pass the `compression` argument to the" " `async_open` function." @@ -173,31 +206,31 @@ msgstr "" "Чтобы включить поточное сжатие, нужно передать аргумент `compression` в " "функцию `async_open`." -#: ../../source/io.rst:107 +#: ../../source/io.rst:113 msgid "Supported compressors:" msgstr "Поддерживаемые алгоритмы сжатия:" -#: ../../source/io.rst:109 +#: ../../source/io.rst:115 msgid ":class:`aiomisc.io.Compression.NONE`" msgstr "" -#: ../../source/io.rst:110 +#: ../../source/io.rst:116 msgid ":class:`aiomisc.io.Compression.GZIP`" msgstr "" -#: ../../source/io.rst:111 +#: ../../source/io.rst:117 msgid ":class:`aiomisc.io.Compression.BZ2`" msgstr "" -#: ../../source/io.rst:112 +#: ../../source/io.rst:118 msgid ":class:`aiomisc.io.Compression.LZMA`" msgstr "" -#: ../../source/io.rst:114 +#: ../../source/io.rst:120 msgid "An example of usage:" msgstr "Пример использования" -#: ../../source/io.rst:116 +#: ../../source/io.rst:122 msgid "" "import tempfile\n" "from aiomisc import run\n" diff --git a/tests/test_io.py b/tests/test_io.py index 051c9783..55a02160 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -8,7 +8,7 @@ import pytest import aiomisc -from aiomisc.io import AsyncTextIO +from aiomisc.io import AsyncFileIO from tests import unix_only @@ -77,7 +77,7 @@ async def test_ordering(loop, tmp_path): async def test_async_for(loop, tmp_path): tdir = Path(tmp_path) - afp: AsyncTextIO + afp: AsyncFileIO[str] async with aiomisc.io.async_open(tdir / "path", "w", loop=loop) as afp: await afp.write("foo\nbar\nbaz\n") @@ -161,7 +161,7 @@ async def test_object(loop): async def test_compression(compression: aiomisc.io.Compression, tmp_path): fname = Path(tmp_path) / "test.file" - afp: aiomisc.io.AsyncTextIOType + afp: aiomisc.io.AsyncTextIO async with aiomisc.io.async_open( fname, "w", compression=compression, From 9a8f7598b6cf40d1cccb716720416199d44b22c4 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 18:47:59 +0300 Subject: [PATCH 41/45] revert pylama.ini --- pylama.ini | 6 ++++++ pyproject.toml | 10 ---------- 2 files changed, 6 insertions(+), 10 deletions(-) create mode 100644 pylama.ini diff --git a/pylama.ini b/pylama.ini new file mode 100644 index 00000000..905c8f3b --- /dev/null +++ b/pylama.ini @@ -0,0 +1,6 @@ +[pylama] +ignore=C901,E252 +skip = *env*,.tox*,*build*,.* + +[pylama:pycodestyle] +max_line_length = 80 diff --git a/pyproject.toml b/pyproject.toml index beee676a..6cfdf86b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -121,13 +121,3 @@ disallow_incomplete_defs = false disallow_untyped_calls = false disallow_untyped_decorators = false disallow_untyped_defs = false - -[tool.pylama] -linters = "mccabe,pycodestyle,pyflakes" -skip = "*env*,.tox*,*build*,.*,env/*,.venv/*" -ignore = "C901" - -[tool.pylama.linter.pycodestyle] -max_line_length = 80 -show-pep8 = true -show-source = true From 2d2b56377b1ad57bdddade3f32f8266d76d519bf Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 19:00:42 +0300 Subject: [PATCH 42/45] Update copyright --- COPYING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYING b/COPYING index ba25bccd..21aa69f5 100644 --- a/COPYING +++ b/COPYING @@ -1,7 +1,7 @@ The MIT License (MIT) ===================== -Copyright © 2022 Dmitry Orlov +Copyright © 2023 Dmitry Orlov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation From a4f70711bf2e44b138a67987266c9adc27ec19e2 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 19:37:46 +0300 Subject: [PATCH 43/45] fix precommit hook --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 974f53fe..8533cc0b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: hooks: - id: pylama name: Check codestyle with Pylama - entry: poetry run mypy + entry: poetry run pylama language: system types: [ python ] From b65233511126a57bc2e4b012c4348ab7e4a644a6 Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Fri, 20 Jan 2023 19:45:18 +0300 Subject: [PATCH 44/45] add typevar for io wrap_to_thread --- aiomisc/io.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/aiomisc/io.py b/aiomisc/io.py index 20221c5c..bf13d994 100644 --- a/aiomisc/io.py +++ b/aiomisc/io.py @@ -9,19 +9,22 @@ from pathlib import Path from typing import ( IO, Any, AnyStr, Awaitable, Callable, Generator, Generic, List, Optional, - TextIO, Union, + TextIO, TypeVar, Union, ) from .compat import EventLoopMixin +T = TypeVar("T", bound=Any) + + def proxy_method_async( name: str, in_executor: bool = True, ) -> Callable[..., Any]: def wrap_to_future( loop: asyncio.AbstractEventLoop, - func: Callable[..., AnyStr], + func: Callable[..., T], *args: Any, **kwargs: Any, ) -> asyncio.Future: future = loop.create_future() @@ -36,10 +39,10 @@ def _inner(): # type: ignore return future def wrap_to_thread( - loop: asyncio.AbstractEventLoop, func: Callable[..., AnyStr], + loop: asyncio.AbstractEventLoop, func: Callable[..., T], executor: Executor, *args: Any, **kwargs: Any, - ) -> Awaitable[AnyStr]: + ) -> Awaitable[T]: callee = partial(func, *args, **kwargs) # noinspection PyTypeChecker return loop.run_in_executor(executor, callee) From 70d2ef117aa64f2fa03c8b3b2f987d14fde061bc Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Mon, 23 Jan 2023 09:20:53 +0300 Subject: [PATCH 45/45] Add precommit and poem-plugins info to the README.rst --- README.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.rst b/README.rst index 651e7f11..2c145876 100644 --- a/README.rst +++ b/README.rst @@ -325,8 +325,15 @@ For setting up developer environment just execute: .. code-block:: + # installing all dependencies poetry install + # setting up pre-commit hooks + poetry run pre-commit install + + # adding poem-plugins to the poetry + poetry self add poem-plugins + .. _Semantic Versioning: http://semver.org/