pax_global_header00006660000000000000000000000064146177137570014534gustar00rootroot0000000000000052 comment=8c83d26603ca94f2e203bfded7b6d7f530960e06 poetry-plugin-export-1.8.0/000077500000000000000000000000001461771375700156775ustar00rootroot00000000000000poetry-plugin-export-1.8.0/.github/000077500000000000000000000000001461771375700172375ustar00rootroot00000000000000poetry-plugin-export-1.8.0/.github/workflows/000077500000000000000000000000001461771375700212745ustar00rootroot00000000000000poetry-plugin-export-1.8.0/.github/workflows/main.yml000066400000000000000000000042621461771375700227470ustar00rootroot00000000000000name: Tests on: pull_request: {} push: branches: - main concurrency: group: tests-${{ github.head_ref || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: tests: name: ${{ matrix.os }} / ${{ matrix.python-version }} ${{ matrix.suffix }} runs-on: ${{ matrix.image }} strategy: matrix: os: [Ubuntu, macOS, Windows] python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] include: - os: Ubuntu image: ubuntu-latest - os: Windows image: windows-2022 - os: macOS image: macos-11 fail-fast: false defaults: run: shell: bash steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: Get full Python version id: full-python-version run: echo "version=$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")" >> $GITHUB_OUTPUT - name: Bootstrap poetry run: | curl -sL https://install.python-poetry.org | python - -y ${{ matrix.bootstrap-args }} - name: Update PATH if: ${{ matrix.os != 'Windows' }} run: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Update Path for Windows if: ${{ matrix.os == 'Windows' }} run: echo "$APPDATA\Python\Scripts" >> $GITHUB_PATH - name: Configure poetry run: poetry config virtualenvs.in-project true - name: Set up cache uses: actions/cache@v3 id: cache with: path: .venv key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} - name: Ensure cache is healthy if: steps.cache.outputs.cache-hit == 'true' run: timeout 10s poetry run pip --version || rm -rf .venv - name: Install dependencies run: poetry install --with github-actions - name: Run mypy run: poetry run mypy - name: Run pytest run: poetry run pytest -v poetry-plugin-export-1.8.0/.github/workflows/release.yml000066400000000000000000000022411461771375700234360ustar00rootroot00000000000000name: Release on: push: tags: - '*.*.*' jobs: release: name: Release runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.9 uses: actions/setup-python@v4 with: python-version: "3.9" - name: Install Poetry run: | curl -sL https://install.python-poetry.org | python - -y ${{ matrix.bootstrap-args }} - name: Update PATH run: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Build project for distribution run: poetry build - name: Check Version id: check-version run: | [[ "$(poetry version --short)" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] \ || echo "prerelease=true" >> $GITHUB_OUTPUT - name: Create Release uses: ncipollo/release-action@v1 with: artifacts: "dist/*" token: ${{ secrets.GITHUB_TOKEN }} draft: false prerelease: steps.check-version.outputs.prerelease == 'true' - name: Publish to PyPI env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} run: poetry publish poetry-plugin-export-1.8.0/.gitignore000066400000000000000000000006101461771375700176640ustar00rootroot00000000000000*.pyc # Packages *.egg !/tests/**/*.egg /*.egg-info /dist/* build _build .cache *.so # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox .pytest_cache .DS_Store .idea/* .python-version .vscode/* /test.py /test_*.* /setup.cfg MANIFEST.in /setup.py /docs/site/* /tests/fixtures/simple_project/setup.py .mypy_cache .venv /releases/* pip-wheel-metadata /poetry.toml poetry-plugin-export-1.8.0/.pre-commit-config.yaml000066400000000000000000000012061461771375700221570ustar00rootroot00000000000000ci: autofix_prs: false repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer exclude: ^.*\.egg-info/ - id: check-merge-conflict - id: check-case-conflict - id: check-json - id: check-toml - id: check-yaml - id: pretty-format-json args: [--autofix, --no-ensure-ascii, --no-sort-keys] - id: check-ast - id: debug-statements - id: check-docstring-first - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.4.3 hooks: - id: ruff - id: ruff-format poetry-plugin-export-1.8.0/.pre-commit-hooks.yaml000066400000000000000000000004451461771375700220410ustar00rootroot00000000000000- id: poetry-export name: poetry-export description: run poetry export to sync lock file with requirements.txt entry: poetry export language: python language_version: python3 pass_filenames: false files: ^poetry.lock$ args: ["-f", "requirements.txt", "-o", "requirements.txt"] poetry-plugin-export-1.8.0/CHANGELOG.md000066400000000000000000000225021461771375700175110ustar00rootroot00000000000000# Change Log ## [1.8.0] - 2024-05-11 ### Changed - Relax the constraint on `poetry` and `poetry-core` to allow (future) `2.*` versions ([#280](https://github.com/python-poetry/poetry-plugin-export/pull/280)). ### Fixed - Fix an issue where editable installs where not exported correctly ([#258](https://github.com/python-poetry/poetry-plugin-export/pull/258)). ## [1.7.1] - 2024-03-19 ### Changed - Export `--index-url` before `--extra-index-url` to work around a pip bug ([#270](https://github.com/python-poetry/poetry-plugin-export/pull/270)). ### Fixed - Fix an issue where the source with the highest priority was exported with `--index-url` despite PyPI being among the sources ([#270](https://github.com/python-poetry/poetry-plugin-export/pull/270)). ## [1.7.0] - 2024-03-14 ### Changed - Bump minimum required poetry version to 1.8.0 ([#263](https://github.com/python-poetry/poetry-plugin-export/pull/263)). ### Fixed - Fix an issue where all sources were exported with `--extra-index-url` even though PyPI was deactivated ([#263](https://github.com/python-poetry/poetry-plugin-export/pull/263)). ## [1.6.0] - 2023-10-30 ### Added - Add an `--all-extras` option ([#241](https://github.com/python-poetry/poetry-plugin-export/pull/241)). ### Fixed - Fix an issue where git dependencies are exported with the branch name instead of the resolved commit hash ([#213](https://github.com/python-poetry/poetry-plugin-export/pull/213)). ## [1.5.0] - 2023-08-20 ### Changed - Drop support for Python 3.7 ([#189](https://github.com/python-poetry/poetry-plugin-export/pull/189)). - Improve warning when the lock file is not consistent with pyproject.toml ([#215](https://github.com/python-poetry/poetry-plugin-export/pull/215)). ### Fixed - Fix an issue where markers for dependencies required by an extra were not generated correctly ([#209](https://github.com/python-poetry/poetry-plugin-export/pull/209)). ## [1.4.0] - 2023-05-29 ### Changed - Bump minimum required poetry version to 1.5.0 ([#196](https://github.com/python-poetry/poetry-plugin-export/pull/196)). ### Fixed - Fix an issue where `--extra-index-url` and `--trusted-host` was not generated for sources with priority `explicit` ([#205](https://github.com/python-poetry/poetry-plugin-export/pull/205)). ## [1.3.1] - 2023-04-17 This release mainly fixes test suite compatibility with upcoming Poetry releases. ### Changed - Improve error message in some cases when the dependency walk fails ([#184](https://github.com/python-poetry/poetry-plugin-export/pull/184)). ## [1.3.0] - 2023-01-30 ### Changed - Drop some compatibility code and bump minimum required poetry version to 1.3.0 ([#167](https://github.com/python-poetry/poetry-plugin-export/pull/167)). ### Fixed - Fix an issue where the export failed if there was a circular dependency on the root package ([#118](https://github.com/python-poetry/poetry-plugin-export/pull/118)). ## [1.2.0] - 2022-11-05 ### Changed - Drop some compatibility code and bump minimum required poetry version to 1.2.2 ([#143](https://github.com/python-poetry/poetry-plugin-export/pull/143)). - Ensure compatibility with upcoming Poetry releases ([#151](https://github.com/python-poetry/poetry-plugin-export/pull/151)). ## [1.1.2] - 2022-10-09 ### Fixed - Fix an issue where exporting a `constraints.txt` file fails if an editable dependency is locked ([#140](https://github.com/python-poetry/poetry-plugin-export/pull/140)). ## [1.1.1] - 2022-10-03 This release fixes test suite compatibility with upcoming Poetry releases. No functional changes. ## [1.1.0] - 2022-10-01 ### Added - Add support for exporting `constraints.txt` files ([#128](https://github.com/python-poetry/poetry-plugin-export/pull/128)). ### Fixed - Fix an issue where a relative path passed via `-o` was not interpreted relative to the current working directory ([#130](https://github.com/python-poetry/poetry-plugin-export/pull/130)). - Fix an issue where the names of extras were not normalized according to PEP 685 ([#123](https://github.com/python-poetry/poetry-plugin-export/pull/123)). ## [1.0.7] - 2022-09-13 ### Added - Add support for multiple extras in a single flag ([#103](https://github.com/python-poetry/poetry-plugin-export/pull/103)). - Add `homepage` and `repository` to metadata ([#113](https://github.com/python-poetry/poetry-plugin-export/pull/113)). - Add a `poetry-export` pre-commit hook ([#85](https://github.com/python-poetry/poetry-plugin-export/pull/85)). ### Fixed - Fix an issue where a virtual environment was created unnecessarily when running `poetry export` (requires poetry 1.2.1) ([#106](https://github.com/python-poetry/poetry-plugin-export/pull/106)). - Fix an issue where package sources were not taken into account ([#111](https://github.com/python-poetry/poetry-plugin-export/pull/111)). - Fix an issue where trying to export with extras that do not exist results in empty output ([#103](https://github.com/python-poetry/poetry-plugin-export/pull/103)). - Fix an issue where exporting a dependency on a package with a non-existent extra fails ([#109](https://github.com/python-poetry/poetry-plugin-export/pull/109)). - Fix an issue where only one of `--index-url` and `--extra-index-url` were exported ([#117](https://github.com/python-poetry/poetry-plugin-export/pull/117)). ## [1.0.6] - 2022-08-07 ### Fixed - Fixed an issue the markers of exported dependencies overlapped. [#94](https://github.com/python-poetry/poetry-plugin-export/pull/94) ## [1.0.5] - 2022-07-12 ### Added - Added LICENSE file. [#81](https://github.com/python-poetry/poetry-plugin-export/pull/81) ## [1.0.4] - 2022-05-26 ### Fixed - Fixed an issue where the exported dependencies did not list their active extras. [#65](https://github.com/python-poetry/poetry-plugin-export/pull/65) ## [1.0.3] - 2022-05-23 This release fixes test suite compatibility with upcoming Poetry releases. No functional changes. ## [1.0.2] - 2022-05-10 ### Fixed - Fixed an issue where the exported hashes were not sorted. [#54](https://github.com/python-poetry/poetry-plugin-export/pull/54) ### Changes - The implicit dependency group was renamed from "default" to "main". (Requires poetry-core > 1.1.0a7 to take effect.) [#52](https://github.com/python-poetry/poetry-plugin-export/pull/52) ## [1.0.1] - 2022-04-11 ### Fixed - Fixed a regression where export incorrectly always exported default group only. [#50](https://github.com/python-poetry/poetry-plugin-export/pull/50) ## [1.0.0] - 2022-04-05 ### Fixed - Fixed an issue with dependency selection when duplicates exist with different markers. [poetry#4932](https://github.com/python-poetry/poetry/pull/4932) - Fixed an issue where unconstrained duplicate dependencies are listed with conditional on python version. [poetry#5141](https://github.com/python-poetry/poetry/issues/5141) ### Changes - Export command now constraints all exported dependencies with the root project's python version constraint. [poetry#5156](https://github.com/python-poetry/poetry/pull/5156) ### Added - Added support for `--without-urls` option. [poetry#4763](https://github.com/python-poetry/poetry/pull/4763) ## [0.2.1] - 2021-11-24 ### Fixed - Fixed the output for packages with markers. [#13](https://github.com/python-poetry/poetry-plugin-export/pull/13) - Check the existence of the `export` command before attempting to delete it. [#18](https://github.com/python-poetry/poetry-plugin-export/pull/18) ## [0.2.0] - 2021-09-13 ### Added - Added support for dependency groups. [#6](https://github.com/python-poetry/poetry-plugin-export/pull/6) [Unreleased]: https://github.com/python-poetry/poetry-plugin-export/compare/1.8.0...main [1.8.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.8.0 [1.7.1]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.7.1 [1.7.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.7.0 [1.6.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.6.0 [1.5.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.5.0 [1.4.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.4.0 [1.3.1]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.3.1 [1.3.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.3.0 [1.2.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.2.0 [1.1.2]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.1.2 [1.1.1]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.1.1 [1.1.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.1.0 [1.0.7]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.7 [1.0.6]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.6 [1.0.5]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.5 [1.0.4]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.4 [1.0.3]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.3 [1.0.2]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.2 [1.0.1]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.1 [1.0.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/1.0.0 [0.2.1]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/0.2.1 [0.2.0]: https://github.com/python-poetry/poetry-plugin-export/releases/tag/0.2.0 poetry-plugin-export-1.8.0/LICENSE000066400000000000000000000020461461771375700167060ustar00rootroot00000000000000Copyright (c) 2022 Sébastien Eustace Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 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. poetry-plugin-export-1.8.0/README.md000066400000000000000000000036701461771375700171640ustar00rootroot00000000000000# Poetry Plugin: Export [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/) This package is a plugin that allows the export of locked packages to various formats. **Note**: For now, only the `constraints.txt` and `requirements.txt` formats are available. This plugin provides the same features as the existing `export` command of Poetry which it will eventually replace. ## Installation The easiest way to install the `export` plugin is via the `self add` command of Poetry. ```bash poetry self add poetry-plugin-export ``` If you used `pipx` to install Poetry you can add the plugin via the `pipx inject` command. ```bash pipx inject poetry poetry-plugin-export ``` Otherwise, if you used `pip` to install Poetry you can add the plugin packages via the `pip install` command. ```bash pip install poetry-plugin-export ``` ## Usage The plugin provides an `export` command to export to the desired format. ```bash poetry export -f requirements.txt --output requirements.txt ``` **Note**: Only the `constraints.txt` and `requirements.txt` formats are currently supported. ### Available options * `--format (-f)`: The format to export to (default: `requirements.txt`). Currently, only `constraints.txt` and `requirements.txt` are supported. * `--output (-o)`: The name of the output file. If omitted, print to standard output. * `--without`: The dependency groups to ignore when exporting. * `--with`: The optional dependency groups to include when exporting. * `--only`: The only dependency groups to include when exporting. * `--default`: Only export the main dependencies. (**Deprecated**) * `--dev`: Include development dependencies. (**Deprecated**) * `--extras (-E)`: Extra sets of dependencies to include. * `--all-extras`: Include all sets of extra dependencies. * `--without-hashes`: Exclude hashes from the exported file. * `--with-credentials`: Include credentials for extra indices. poetry-plugin-export-1.8.0/docs/000077500000000000000000000000001461771375700166275ustar00rootroot00000000000000poetry-plugin-export-1.8.0/docs/_index.md000066400000000000000000000045261461771375700204260ustar00rootroot00000000000000--- title: "Export plugin" draft: false type: docs layout: single menu: docs: weight: 1001 --- # Export plugin The export plugin allows the export of locked packages to various formats. {{% note %}} Only the `constraints.txt` and `requirements.txt` formats are currently supported. {{% /note %}} ## Exporting packages The plugin provides an `export` command to export the locked packages to various formats. The default export format is the `requirements.txt` format which is currently the most compatible one. You can specify a format with the `--format (-f)` option: ```bash poetry export -f requirements.txt ``` By default, the `export` command will export to the standard output. You can specify a file to export to with the `--output (-o)` option: ```bash poetry export --output requirements.txt ``` Similarly to the [`install`]({{< relref "../cli#install" >}}) command, you can control which [dependency groups]({{< relref "managing-dependencies#dependency-groups" >}}) need to be exported. If you want to exclude one or more dependency group from the export, you can use the `--without` option. ```bash poetry export --without test,docs ``` You can also select optional dependency groups with the `--with` option. ```bash poetry export --with test,docs ``` {{% note %}} The `--dev` option is now deprecated. You should use the `--with dev` notation instead. {{% /note %}} It's also possible to only export specific dependency groups by using the `only` option. ```bash poetry export --only test,docs ``` ### Available options * `--format (-f)`: The format to export to (default: `requirements.txt`). Currently, only `constraints.txt` and `requirements.txt` are supported. * `--output (-o)`: The name of the output file. If omitted, print to standard output. * `--without`: The dependency groups to ignore when exporting. * `--with`: The optional dependency groups to include when exporting. * `--only`: The only dependency groups to include when exporting. * `--default`: Only export the main dependencies. (**Deprecated**) * {{< option name="dev" deprecated=true >}}Include development dependencies.{{< /option >}} * `--extras (-E)`: Extra sets of dependencies to include. * `--all-extras`: Include all sets of extra dependencies. * `--without-hashes`: Exclude hashes from the exported file. * `--with-credentials`: Include credentials for extra indices. poetry-plugin-export-1.8.0/poetry.lock000066400000000000000000003746701461771375700201140ustar00rootroot00000000000000# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "build" version = "1.1.1" description = "A simple, correct Python build frontend" optional = false python-versions = ">= 3.7" files = [ {file = "build-1.1.1-py3-none-any.whl", hash = "sha256:8ed0851ee76e6e38adce47e4bee3b51c771d86c64cf578d0c2245567ee200e73"}, {file = "build-1.1.1.tar.gz", hash = "sha256:8eea65bb45b1aac2e734ba2cc8dad3a6d97d97901a395bd0ed3e7b46953d2a31"}, ] [package.dependencies] colorama = {version = "*", markers = "os_name == \"nt\""} importlib-metadata = {version = ">=4.6", markers = "python_full_version < \"3.10.2\""} packaging = ">=19.0" pyproject_hooks = "*" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [package.extras] docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"] test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"] typing = ["importlib-metadata (>=5.1)", "mypy (>=1.5.0,<1.6.0)", "tomli", "typing-extensions (>=3.7.4.3)"] virtualenv = ["virtualenv (>=20.0.35)"] [[package]] name = "cachecontrol" version = "0.14.0" description = "httplib2 caching for requests" optional = false python-versions = ">=3.7" files = [ {file = "cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0"}, {file = "cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938"}, ] [package.dependencies] filelock = {version = ">=3.8.0", optional = true, markers = "extra == \"filecache\""} msgpack = ">=0.5.2,<2.0.0" requests = ">=2.16.0" [package.extras] dev = ["CacheControl[filecache,redis]", "black", "build", "cherrypy", "furo", "mypy", "pytest", "pytest-cov", "sphinx", "sphinx-copybutton", "tox", "types-redis", "types-requests"] filecache = ["filelock (>=3.8.0)"] redis = ["redis (>=2.10.5)"] [[package]] name = "certifi" version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, ] [package.dependencies] pycparser = "*" [[package]] name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] [[package]] name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] name = "cleo" version = "2.1.0" description = "Cleo allows you to create beautiful and testable command-line interfaces." optional = false python-versions = ">=3.7,<4.0" files = [ {file = "cleo-2.1.0-py3-none-any.whl", hash = "sha256:4a31bd4dd45695a64ee3c4758f583f134267c2bc518d8ae9a29cf237d009b07e"}, {file = "cleo-2.1.0.tar.gz", hash = "sha256:0b2c880b5d13660a7ea651001fb4acb527696c01f15c9ee650f377aa543fd523"}, ] [package.dependencies] crashtest = ">=0.4.1,<0.5.0" rapidfuzz = ">=3.0.0,<4.0.0" [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." 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 = "coverage" version = "7.4.3" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, ] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] toml = ["tomli"] [[package]] name = "crashtest" version = "0.4.1" description = "Manage Python errors with ease" 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 = "cryptography" version = "42.0.5" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ {file = "cryptography-42.0.5-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16"}, {file = "cryptography-42.0.5-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec"}, {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb"}, {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4"}, {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278"}, {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7"}, {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee"}, {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1"}, {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d"}, {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da"}, {file = "cryptography-42.0.5-cp37-abi3-win32.whl", hash = "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74"}, {file = "cryptography-42.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940"}, {file = "cryptography-42.0.5-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8"}, {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1"}, {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e"}, {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc"}, {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a"}, {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7"}, {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922"}, {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc"}, {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30"}, {file = "cryptography-42.0.5-cp39-abi3-win32.whl", hash = "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413"}, {file = "cryptography-42.0.5-cp39-abi3-win_amd64.whl", hash = "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400"}, {file = "cryptography-42.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8"}, {file = "cryptography-42.0.5-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2"}, {file = "cryptography-42.0.5-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c"}, {file = "cryptography-42.0.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576"}, {file = "cryptography-42.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6"}, {file = "cryptography-42.0.5-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e"}, {file = "cryptography-42.0.5-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac"}, {file = "cryptography-42.0.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd"}, {file = "cryptography-42.0.5.tar.gz", hash = "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1"}, ] [package.dependencies] cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] name = "distlib" version = "0.3.8" description = "Distribution utilities" optional = false python-versions = "*" files = [ {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] [[package]] name = "dulwich" version = "0.21.7" description = "Python Git Library" optional = false python-versions = ">=3.7" files = [ {file = "dulwich-0.21.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d4c0110798099bb7d36a110090f2688050703065448895c4f53ade808d889dd3"}, {file = "dulwich-0.21.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2bc12697f0918bee324c18836053644035362bb3983dc1b210318f2fed1d7132"}, {file = "dulwich-0.21.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:471305af74790827fcbafe330fc2e8bdcee4fb56ca1177c8c481b1c8f806c4a4"}, {file = "dulwich-0.21.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d54c9d0e845be26f65f954dff13a1cd3f2b9739820c19064257b8fd7435ab263"}, {file = "dulwich-0.21.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12d61334a575474e707614f2e93d6ed4cdae9eb47214f9277076d9e5615171d3"}, {file = "dulwich-0.21.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e274cebaf345f0b1e3b70197f2651de92b652386b68020cfd3bf61bc30f6eaaa"}, {file = "dulwich-0.21.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:817822f970e196e757ae01281ecbf21369383285b9f4a83496312204cf889b8c"}, {file = "dulwich-0.21.7-cp310-cp310-win32.whl", hash = "sha256:7836da3f4110ce684dcd53489015fb7fa94ed33c5276e3318b8b1cbcb5b71e08"}, {file = "dulwich-0.21.7-cp310-cp310-win_amd64.whl", hash = "sha256:4a043b90958cec866b4edc6aef5fe3c2c96a664d0b357e1682a46f6c477273c4"}, {file = "dulwich-0.21.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ce8db196e79c1f381469410d26fb1d8b89c6b87a4e7f00ff418c22a35121405c"}, {file = "dulwich-0.21.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:62bfb26bdce869cd40be443dfd93143caea7089b165d2dcc33de40f6ac9d812a"}, {file = "dulwich-0.21.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c01a735b9a171dcb634a97a3cec1b174cfbfa8e840156870384b633da0460f18"}, {file = "dulwich-0.21.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa4d14767cf7a49c9231c2e52cb2a3e90d0c83f843eb6a2ca2b5d81d254cf6b9"}, {file = "dulwich-0.21.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bca4b86e96d6ef18c5bc39828ea349efb5be2f9b1f6ac9863f90589bac1084d"}, {file = "dulwich-0.21.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a7b5624b02ef808cdc62dabd47eb10cd4ac15e8ac6df9e2e88b6ac6b40133673"}, {file = "dulwich-0.21.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c3a539b4696a42fbdb7412cb7b66a4d4d332761299d3613d90a642923c7560e1"}, {file = "dulwich-0.21.7-cp311-cp311-win32.whl", hash = "sha256:675a612ce913081beb0f37b286891e795d905691dfccfb9bf73721dca6757cde"}, {file = "dulwich-0.21.7-cp311-cp311-win_amd64.whl", hash = "sha256:460ba74bdb19f8d498786ae7776745875059b1178066208c0fd509792d7f7bfc"}, {file = "dulwich-0.21.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4c51058ec4c0b45dc5189225b9e0c671b96ca9713c1daf71d622c13b0ab07681"}, {file = "dulwich-0.21.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4bc4c5366eaf26dda3fdffe160a3b515666ed27c2419f1d483da285ac1411de0"}, {file = "dulwich-0.21.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a0650ec77d89cb947e3e4bbd4841c96f74e52b4650830112c3057a8ca891dc2f"}, {file = "dulwich-0.21.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f18f0a311fb7734b033a3101292b932158cade54b74d1c44db519e42825e5a2"}, {file = "dulwich-0.21.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c589468e5c0cd84e97eb7ec209ab005a2cb69399e8c5861c3edfe38989ac3a8"}, {file = "dulwich-0.21.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d62446797163317a397a10080c6397ffaaca51a7804c0120b334f8165736c56a"}, {file = "dulwich-0.21.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e84cc606b1f581733df4350ca4070e6a8b30be3662bbb81a590b177d0c996c91"}, {file = "dulwich-0.21.7-cp312-cp312-win32.whl", hash = "sha256:c3d1685f320907a52c40fd5890627945c51f3a5fa4bcfe10edb24fec79caadec"}, {file = "dulwich-0.21.7-cp312-cp312-win_amd64.whl", hash = "sha256:6bd69921fdd813b7469a3c77bc75c1783cc1d8d72ab15a406598e5a3ba1a1503"}, {file = "dulwich-0.21.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d8ab29c660125db52106775caa1f8f7f77a69ed1fe8bc4b42bdf115731a25bf"}, {file = "dulwich-0.21.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0d2e4485b98695bf95350ce9d38b1bb0aaac2c34ad00a0df789aa33c934469b"}, {file = "dulwich-0.21.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e138d516baa6b5bafbe8f030eccc544d0d486d6819b82387fc0e285e62ef5261"}, {file = "dulwich-0.21.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f34bf9b9fa9308376263fd9ac43143c7c09da9bc75037bb75c6c2423a151b92c"}, {file = "dulwich-0.21.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2e2c66888207b71cd1daa2acb06d3984a6bc13787b837397a64117aa9fc5936a"}, {file = "dulwich-0.21.7-cp37-cp37m-win32.whl", hash = "sha256:10893105c6566fc95bc2a67b61df7cc1e8f9126d02a1df6a8b2b82eb59db8ab9"}, {file = "dulwich-0.21.7-cp37-cp37m-win_amd64.whl", hash = "sha256:460b3849d5c3d3818a80743b4f7a0094c893c559f678e56a02fff570b49a644a"}, {file = "dulwich-0.21.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74700e4c7d532877355743336c36f51b414d01e92ba7d304c4f8d9a5946dbc81"}, {file = "dulwich-0.21.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c92e72c43c9e9e936b01a57167e0ea77d3fd2d82416edf9489faa87278a1cdf7"}, {file = "dulwich-0.21.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d097e963eb6b9fa53266146471531ad9c6765bf390849230311514546ed64db2"}, {file = "dulwich-0.21.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:808e8b9cc0aa9ac74870b49db4f9f39a52fb61694573f84b9c0613c928d4caf8"}, {file = "dulwich-0.21.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1957b65f96e36c301e419d7adaadcff47647c30eb072468901bb683b1000bc5"}, {file = "dulwich-0.21.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4b09bc3a64fb70132ec14326ecbe6e0555381108caff3496898962c4136a48c6"}, {file = "dulwich-0.21.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5882e70b74ac3c736a42d3fdd4f5f2e6570637f59ad5d3e684760290b58f041"}, {file = "dulwich-0.21.7-cp38-cp38-win32.whl", hash = "sha256:29bb5c1d70eba155ded41ed8a62be2f72edbb3c77b08f65b89c03976292f6d1b"}, {file = "dulwich-0.21.7-cp38-cp38-win_amd64.whl", hash = "sha256:25c3ab8fb2e201ad2031ddd32e4c68b7c03cb34b24a5ff477b7a7dcef86372f5"}, {file = "dulwich-0.21.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8929c37986c83deb4eb500c766ee28b6670285b512402647ee02a857320e377c"}, {file = "dulwich-0.21.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cc1e11be527ac06316539b57a7688bcb1b6a3e53933bc2f844397bc50734e9ae"}, {file = "dulwich-0.21.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0fc3078a1ba04c588fabb0969d3530efd5cd1ce2cf248eefb6baf7cbc15fc285"}, {file = "dulwich-0.21.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40dcbd29ba30ba2c5bfbab07a61a5f20095541d5ac66d813056c122244df4ac0"}, {file = "dulwich-0.21.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8869fc8ec3dda743e03d06d698ad489b3705775fe62825e00fa95aa158097fc0"}, {file = "dulwich-0.21.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d96ca5e0dde49376fbcb44f10eddb6c30284a87bd03bb577c59bb0a1f63903fa"}, {file = "dulwich-0.21.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0064363bd5e814359657ae32517fa8001e8573d9d040bd997908d488ab886ed"}, {file = "dulwich-0.21.7-cp39-cp39-win32.whl", hash = "sha256:869eb7be48243e695673b07905d18b73d1054a85e1f6e298fe63ba2843bb2ca1"}, {file = "dulwich-0.21.7-cp39-cp39-win_amd64.whl", hash = "sha256:404b8edeb3c3a86c47c0a498699fc064c93fa1f8bab2ffe919e8ab03eafaaad3"}, {file = "dulwich-0.21.7-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e598d743c6c0548ebcd2baf94aa9c8bfacb787ea671eeeb5828cfbd7d56b552f"}, {file = "dulwich-0.21.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a2d76c96426e791556836ef43542b639def81be4f1d6d4322cd886c115eae1"}, {file = "dulwich-0.21.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6c88acb60a1f4d31bd6d13bfba465853b3df940ee4a0f2a3d6c7a0778c705b7"}, {file = "dulwich-0.21.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ecd315847dea406a4decfa39d388a2521e4e31acde3bd9c2609c989e817c6d62"}, {file = "dulwich-0.21.7-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d05d3c781bc74e2c2a2a8f4e4e2ed693540fbe88e6ac36df81deac574a6dad99"}, {file = "dulwich-0.21.7-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6de6f8de4a453fdbae8062a6faa652255d22a3d8bce0cd6d2d6701305c75f2b3"}, {file = "dulwich-0.21.7-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e25953c7acbbe4e19650d0225af1c0c0e6882f8bddd2056f75c1cc2b109b88ad"}, {file = "dulwich-0.21.7-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:4637cbd8ed1012f67e1068aaed19fcc8b649bcf3e9e26649826a303298c89b9d"}, {file = "dulwich-0.21.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:858842b30ad6486aacaa607d60bab9c9a29e7c59dc2d9cb77ae5a94053878c08"}, {file = "dulwich-0.21.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:739b191f61e1c4ce18ac7d520e7a7cbda00e182c3489552408237200ce8411ad"}, {file = "dulwich-0.21.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:274c18ec3599a92a9b67abaf110e4f181a4f779ee1aaab9e23a72e89d71b2bd9"}, {file = "dulwich-0.21.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2590e9b431efa94fc356ae33b38f5e64f1834ec3a94a6ac3a64283b206d07aa3"}, {file = "dulwich-0.21.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed60d1f610ef6437586f7768254c2a93820ccbd4cfdac7d182cf2d6e615969bb"}, {file = "dulwich-0.21.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8278835e168dd097089f9e53088c7a69c6ca0841aef580d9603eafe9aea8c358"}, {file = "dulwich-0.21.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffc27fb063f740712e02b4d2f826aee8bbed737ed799962fef625e2ce56e2d29"}, {file = "dulwich-0.21.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:61e3451bd3d3844f2dca53f131982553be4d1b1e1ebd9db701843dd76c4dba31"}, {file = "dulwich-0.21.7.tar.gz", hash = "sha256:a9e9c66833cea580c3ac12927e4b9711985d76afca98da971405d414de60e968"}, ] [package.dependencies] urllib3 = ">=1.25" [package.extras] fastimport = ["fastimport"] https = ["urllib3 (>=1.24.1)"] paramiko = ["paramiko"] pgp = ["gpg"] [[package]] name = "exceptiongroup" version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, ] [package.extras] test = ["pytest (>=6)"] [[package]] name = "execnet" version = "2.0.2" description = "execnet: rapid multi-Python deployment" optional = false python-versions = ">=3.7" files = [ {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, ] [package.extras] testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "fastjsonschema" version = "2.19.1" description = "Fastest Python implementation of JSON schema" optional = false python-versions = "*" files = [ {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, ] [package.extras] devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] [[package]] name = "filelock" version = "3.13.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] name = "identify" version = "2.5.35" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ {file = "identify-2.5.35-py2.py3-none-any.whl", hash = "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e"}, {file = "identify-2.5.35.tar.gz", hash = "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791"}, ] [package.extras] license = ["ukkonen"] [[package]] name = "idna" version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] [[package]] name = "importlib-metadata" version = "7.0.2" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ {file = "importlib_metadata-7.0.2-py3-none-any.whl", hash = "sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100"}, {file = "importlib_metadata-7.0.2.tar.gz", hash = "sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "importlib-resources" version = "6.3.0" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ {file = "importlib_resources-6.3.0-py3-none-any.whl", hash = "sha256:783407aa1cd05550e3aa123e8f7cfaebee35ffa9cb0242919e2d1e4172222705"}, {file = "importlib_resources-6.3.0.tar.gz", hash = "sha256:166072a97e86917a9025876f34286f549b9caf1d10b35a1b372bffa1600c6569"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["jaraco.collections", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] name = "installer" version = "0.7.0" description = "A library for installing Python wheels." optional = false python-versions = ">=3.7" files = [ {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"}, {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"}, ] [[package]] name = "jaraco-classes" version = "3.3.1" description = "Utility functions for Python class constructs" optional = false python-versions = ">=3.8" files = [ {file = "jaraco.classes-3.3.1-py3-none-any.whl", hash = "sha256:86b534de565381f6b3c1c830d13f931d7be1a75f0081c57dff615578676e2206"}, {file = "jaraco.classes-3.3.1.tar.gz", hash = "sha256:cb28a5ebda8bc47d8c8015307d93163464f9f2b91ab4006e09ff0ce07e8bfb30"}, ] [package.dependencies] more-itertools = "*" [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [[package]] name = "jeepney" version = "0.8.0" description = "Low-level, pure Python DBus protocol wrapper." 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 = "keyring" version = "24.3.1" description = "Store and access your passwords safely." optional = false python-versions = ">=3.8" files = [ {file = "keyring-24.3.1-py3-none-any.whl", hash = "sha256:df38a4d7419a6a60fea5cef1e45a948a3e8430dd12ad88b0f423c5c143906218"}, {file = "keyring-24.3.1.tar.gz", hash = "sha256:c3327b6ffafc0e8befbdb597cacdb4928ffe5c1212f7645f186e6d9957a898db"}, ] [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 (>=1.1.0)"] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [[package]] name = "more-itertools" version = "10.2.0" description = "More routines for operating on iterables, beyond itertools" optional = false python-versions = ">=3.8" files = [ {file = "more-itertools-10.2.0.tar.gz", hash = "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1"}, {file = "more_itertools-10.2.0-py3-none-any.whl", hash = "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684"}, ] [[package]] name = "msgpack" version = "1.0.8" description = "MessagePack serializer" optional = false python-versions = ">=3.8" files = [ {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"}, {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] [[package]] name = "mypy" version = "1.9.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] [[package]] name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, ] [package.dependencies] setuptools = "*" [[package]] name = "packaging" version = "24.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, ] [package.dependencies] ptyprocess = ">=0.5" [[package]] name = "pkginfo" version = "1.10.0" description = "Query metadata from sdists / bdists / installed packages." optional = false python-versions = ">=3.6" files = [ {file = "pkginfo-1.10.0-py3-none-any.whl", hash = "sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097"}, {file = "pkginfo-1.10.0.tar.gz", hash = "sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297"}, ] [package.extras] testing = ["pytest", "pytest-cov", "wheel"] [[package]] name = "platformdirs" version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.8" files = [ {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "poetry" version = "1.8.2" description = "Python dependency management and packaging made easy." optional = false python-versions = ">=3.8,<4.0" files = [ {file = "poetry-1.8.2-py3-none-any.whl", hash = "sha256:b42b400d9a803af6e788a30a6f3e9998020b77860e28df20647eb10b6f414910"}, {file = "poetry-1.8.2.tar.gz", hash = "sha256:49cceb3838104647c3e1021f3a4f13c6053704cc18d33f849a90fe687a29cb73"}, ] [package.dependencies] build = ">=1.0.3,<2.0.0" cachecontrol = {version = ">=0.14.0,<0.15.0", extras = ["filecache"]} cleo = ">=2.1.0,<3.0.0" crashtest = ">=0.4.1,<0.5.0" dulwich = ">=0.21.2,<0.22.0" fastjsonschema = ">=2.18.0,<3.0.0" importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} installer = ">=0.7.0,<0.8.0" keyring = ">=24.0.0,<25.0.0" packaging = ">=23.1" pexpect = ">=4.7.0,<5.0.0" pkginfo = ">=1.9.4,<2.0.0" platformdirs = ">=3.0.0,<5" poetry-core = "1.9.0" poetry-plugin-export = ">=1.6.0,<2.0.0" pyproject-hooks = ">=1.0.0,<2.0.0" requests = ">=2.26,<3.0" requests-toolbelt = ">=1.0.0,<2.0.0" shellingham = ">=1.5,<2.0" tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""} tomlkit = ">=0.11.4,<1.0.0" trove-classifiers = ">=2022.5.19" virtualenv = ">=20.23.0,<21.0.0" xattr = {version = ">=1.0.0,<2.0.0", markers = "sys_platform == \"darwin\""} [[package]] name = "poetry-core" version = "1.9.0" description = "Poetry PEP 517 Build Backend" optional = false python-versions = ">=3.8,<4.0" files = [ {file = "poetry_core-1.9.0-py3-none-any.whl", hash = "sha256:4e0c9c6ad8cf89956f03b308736d84ea6ddb44089d16f2adc94050108ec1f5a1"}, {file = "poetry_core-1.9.0.tar.gz", hash = "sha256:fa7a4001eae8aa572ee84f35feb510b321bd652e5cf9293249d62853e1f935a2"}, ] [[package]] name = "pre-commit" version = "3.5.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.8" files = [ {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, ] [package.dependencies] cfgv = ">=2.0.0" identify = ">=1.0.0" nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" [[package]] name = "psutil" version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, ] [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] [[package]] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" 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 = "pycparser" version = "2.21" description = "C parser in Python" 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 = "pyproject-hooks" version = "1.0.0" description = "Wrappers to call pyproject.toml-based build backend hooks." optional = false python-versions = ">=3.7" files = [ {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"}, {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"}, ] [package.dependencies] tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [[package]] name = "pytest" version = "8.1.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=1.4,<2.0" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.7" files = [ {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, ] [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-github-actions-annotate-failures" version = "0.1.8" description = "pytest plugin to annotate failed tests with a workflow command for GitHub Actions" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" files = [ {file = "pytest-github-actions-annotate-failures-0.1.8.tar.gz", hash = "sha256:2d6e6cb5f8d0aae4a27a20cc4e20fabd3199a121c57f44bc48fe28e372e0be23"}, {file = "pytest_github_actions_annotate_failures-0.1.8-py2.py3-none-any.whl", hash = "sha256:6a882ff21672fa79deae8d917eb965a6bde2b25191e7632e1adfc23ffac008ab"}, ] [package.dependencies] pytest = ">=4.0.0" [[package]] name = "pytest-mock" version = "3.12.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" files = [ {file = "pytest-mock-3.12.0.tar.gz", hash = "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9"}, {file = "pytest_mock-3.12.0-py3-none-any.whl", hash = "sha256:0972719a7263072da3a21c7f4773069bcc7486027d7e8e1f81d98a47e701bc4f"}, ] [package.dependencies] pytest = ">=5.0" [package.extras] dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-randomly" version = "3.15.0" description = "Pytest plugin to randomly order tests and control random.seed." optional = false python-versions = ">=3.8" files = [ {file = "pytest_randomly-3.15.0-py3-none-any.whl", hash = "sha256:0516f4344b29f4e9cdae8bce31c4aeebf59d0b9ef05927c33354ff3859eeeca6"}, {file = "pytest_randomly-3.15.0.tar.gz", hash = "sha256:b908529648667ba5e54723088edd6f82252f540cc340d748d1fa985539687047"}, ] [package.dependencies] importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} pytest = "*" [[package]] name = "pytest-xdist" version = "3.5.0" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false python-versions = ">=3.7" files = [ {file = "pytest-xdist-3.5.0.tar.gz", hash = "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a"}, {file = "pytest_xdist-3.5.0-py3-none-any.whl", hash = "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24"}, ] [package.dependencies] execnet = ">=1.1" psutil = {version = ">=3.0", optional = true, markers = "extra == \"psutil\""} pytest = ">=6.2.0" [package.extras] psutil = ["psutil (>=3.0)"] setproctitle = ["setproctitle"] testing = ["filelock"] [[package]] name = "pywin32-ctypes" version = "0.2.2" description = "A (partial) reimplementation of pywin32 using ctypes/cffi" optional = false python-versions = ">=3.6" files = [ {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"}, {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"}, ] [[package]] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.6" files = [ {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] name = "rapidfuzz" version = "3.6.2" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.8" files = [ {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a5637e6bf11b15b5aff6ee818c76bdec99ad208511b78985e6209ba648a6e3ee"}, {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:380586664f2f63807050ddb95e7702888b4f0b425abf17655940c411f39287ad"}, {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3168ff565d4b8c239cf11fb604dd2507d30e9bcaac76a4077c0ac23cf2c866ed"}, {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be69f7fd46b5c6467fe5e2fd4cff3816b0c03048eed8a4becb9a73e6000960e7"}, {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cbd5894f23fdf5697499cf759523639838ac822bd1600e343fdce7313baa02ae"}, {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85a5b6e026393fe39fb61146b9c17c5af66fffbe1410e992c4bb06d9ec327bd3"}, {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab269adfc64480f209e99f253391a10735edd5c09046e04899adab5fb132f20e"}, {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35aeac852bca06023d6bbd50c1fc504ca5a9a3613d5e75a140f0be7601fa34ef"}, {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e706f302c6a3ae0d74edd0d6ace46aee1ae07c563b436ccf5ff04db2b3571e60"}, {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bec353f022011e6e5cd28ccb8700fbd2a33918197af0d4e0abb3c3f4845cc864"}, {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ef3925daaa93eed20401012e219f569ff0c039ed5bf4ce2d3737b4f75d441622"}, {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6ee98d88ae9ccc77ff61992ed33b2496478def5dc0da55c9a9aa06fcb725a352"}, {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:423c7c588b09d618601097b7a0017dfcb91132a2076bef29023c5f3cd2dc3de1"}, {file = "rapidfuzz-3.6.2-cp310-cp310-win32.whl", hash = "sha256:c17c5efee347a40a6f4c1eec59e3d7d1e22f7613a97f8b8a07733ef723483a04"}, {file = "rapidfuzz-3.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:4209816626d8d6ff8ae7dc248061c6059e618b70c6e6f6e4d7444ae3740b2b85"}, {file = "rapidfuzz-3.6.2-cp310-cp310-win_arm64.whl", hash = "sha256:1c54d3c85e522d3ac9ee39415f183c8fa184c4f87e7e5a37938f15a6d50e853a"}, {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e06f6d270112f5db001f1cba5a97e1a48aee3d3dbdcbea3ec027c230462dbf9b"}, {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:080cb71b50cb6aff11d1c6aeb157f273e2da0b2bdb3f9d7b01257e49e69a8576"}, {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7895e04a22d6515bc91a850e0831f2405547605aa311d1ffec51e4818abc3c1"}, {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82f9838519136b7083dd1e3149ee80344521f3dc37f744f227505ff0883efb"}, {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a945567c2b0b6e069454c9782d5234b0b6795718adf7a9f868bd3144afa6a023"}, {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:673ba2c343644805acdae1cb949c6a4de71aa2f62a998978551ebea59603af3f"}, {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d457c89bac1471442002e70551e8268e639b3870b4a4521eae363c07253be87"}, {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:495c0d8e14e6f12520eb7fc71b9ba9fcaafb47fc23a654e6e89b6c7985ec0020"}, {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6d67b649bf3e1b1722d04eca44d37919aef88305ce7ad05564502d013cf550fd"}, {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e48dde8ca83d11daa00900cf6a5d281a1297aef9b7bfa73801af6e8822be5019"}, {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:824cc381cf81cbf8d158f6935664ec2a69e6ac3b1d39fa201988bf81a257f775"}, {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1dfe4c24957474ce0ac75d886387e30e292b4be39228a6d71f76de414dc187db"}, {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d57b98013b802621bbc8b12a46bfc9d36ac552ab51ca207f7ce167ad46adabeb"}, {file = "rapidfuzz-3.6.2-cp311-cp311-win32.whl", hash = "sha256:9a07dffac439223b4f1025dbfc68f4445a3460a859309c9858c2a3fa29617cdc"}, {file = "rapidfuzz-3.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:95a49c6b8bf1229743ae585dd5b7d57f0d15a7eb6e826866d5c9965ba958503c"}, {file = "rapidfuzz-3.6.2-cp311-cp311-win_arm64.whl", hash = "sha256:af7c19ec86e11488539380d3db1755be5d561a3c0e7b04ff9d07abd7f9a8e9d8"}, {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:de8adc12161bf282c60f12dc9233bb31632f71d446a010fe7469a69b8153427f"}, {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:337e357f693130c4c6be740652542b260e36f622c59e01fa33d58f1d2750c930"}, {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6468f8bc8c3c50604f43631550ef9cfec873515dba5023ca34d461be94669fc8"}, {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74c6773b11445b5e5cf93ca383171cd0ac0cdeafea11a7b2a5688f8bf8d813e6"}, {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1507fc5769aa109dda4de3a15f822a0f6a03e18d627bd0ba3ddbb253cf70e07"}, {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:617949a70150e6fffdaed19253dd49f7a53528411dc8bf7663d499ba21e0f61e"}, {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8b77779174b1b40aa70827692571ab457061897846255ad7d5d559e2edb1932"}, {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80e51b22a7da83f9c87a97e92df07ed0612c74c35496590255f4b5d5b4212dfe"}, {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3ae7c86914cb6673e97e187ba431b9c4cf4177d9ae77f8a1e5b2ba9a5628839e"}, {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ddc380ffaa90f204cc9ddcb779114b9ab6f015246d549de9d47871a97ef9f18a"}, {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3c1dc078ef371fce09f9f3eec2ca4eaa2a8cd412ec53941015b4f39f14d34407"}, {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:9a74102fc5a2534fe91f7507838623e1f3a149d8e05648389c42bb42e14b1c3f"}, {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:48e1eaea8fcd522fca7f04f0480663f0f0cfb77957092cce60a93f4462864996"}, {file = "rapidfuzz-3.6.2-cp312-cp312-win32.whl", hash = "sha256:66b008bf2972740cd2dda5d382eb8bdb87265cd88198e71c7797bdc0d1f79d20"}, {file = "rapidfuzz-3.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:87ac3a87f2251ae2e95fc9478ca5c759de6d141d04c84d3fec9f9cdcfc167b33"}, {file = "rapidfuzz-3.6.2-cp312-cp312-win_arm64.whl", hash = "sha256:b593cc51aed887e93b78c2f94dfae9008be2b23d17afd3b1f1d3eb3913b58f26"}, {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d830bc7a9b586a374147ec60b08b1f9ae5996b43f75cc514f37faef3866b519"}, {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dbee7f5ff11872b76505cbd87c814abc823e8757f11c69062eb3b25130a283da"}, {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c011fb31f2c3f82f503aedd6097d3d3854e574e327a119a3b7eb2cf90b79ca"}, {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cda81d0e0ce0c13abfa46b24e10c1e85f9c6acb628f0a9a948f5779f9c2076a2"}, {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c279928651ce0e9e5220dcb25a00cc53b65e592a0861336a38299bcdca3a596"}, {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35bd4bc9c40e6994c5d6edea4b9319388b4d9711c13c66d543bb4c37624b4184"}, {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d07899506a5a8760448d9df036d528b55a554bf571714173635c79eef4a86e58"}, {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb2e51d01b9c6d6954a3e055c57a80d4685b4fc82719db5519fc153566bcd6bb"}, {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:153d065e353371cc0aeff32b99999a5758266a64e958d1364189367c1c9f6814"}, {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4edcceebb85ebfa49a3ddcde20ad891d36c08dc0fd592efdab0e7d313a4e36af"}, {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3549123fca5bb817341025f98e8e49ca99f84596c7c4f92b658f8e5836040d4a"}, {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:84c1032ae42628465b7a5cc35249906061e18a8193c9c27cbd2db54e9823a9a6"}, {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9bcc91ebd8fc69a6bd3b5711c8250f5f4e70606b4da75ef415f57ad209978205"}, {file = "rapidfuzz-3.6.2-cp38-cp38-win32.whl", hash = "sha256:f3a70f341c4c111bad910d2df69c78577a98af140319a996af24c9385939335d"}, {file = "rapidfuzz-3.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:354ad5fe655beb7b279390cb58334903931c5452ecbad1b1666ffb06786498e2"}, {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1b86b93d93020c2b3edc1665d75c8855784845fc0a739b312c26c3a4bf0c80d5"}, {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28243086ed0e50808bb56632e5442c457241646aeafafd501ac87901f40a3237"}, {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed52461ae5a9ea4c400d38e2649c74a413f1a6d8fb8308b66f1fbd122514732f"}, {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a46220f86a5f9cb016af31525e0d0865cad437d02239aa0d8aed2ab8bff1f1c"}, {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81a630ed2fc3ec5fc7400eb66bab1f87e282b4d47f0abe3e48c6634dfa13b5e4"}, {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8e5a437b9089df6242a718d9c31ab1742989e9400a0977af012ef483b63b4c2"}, {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16270b5529de83b7bae7457e952e4d9cf3fbf029a837dd32d415bb9e0eb8e599"}, {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5378c04102c7f084cde30a100154fa6d7e2baf0d51a6bdd2f912545559c1fb35"}, {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7f18397c8d6a65fc0b288d2fc29bc7baeea6ba91eeb95163a3cd98f23cd3bc85"}, {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2acd2514defce81e6ff4bbff50252d5e7df8e85a731442c4b83e44c86cf1c916"}, {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:1df2faf80201952e252413b6fac6f3e146080dcebb87bb1bb722508e67558ed8"}, {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6440ed0b3007c1c9286b0b88fe2ab2d9e83edd60cd62293b3dfabb732b4e8a30"}, {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4fcfa23b5553b27f4016df77c53172ea743454cf12c28cfa7c35a309a2be93b3"}, {file = "rapidfuzz-3.6.2-cp39-cp39-win32.whl", hash = "sha256:2d580d937146e803c8e5e1b87916cab8d6f84013b6392713e201efcda335c7d8"}, {file = "rapidfuzz-3.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:fe2a68be734e8e88af23385c68d6467e15818b6b1df1cbfebf7bff577226c957"}, {file = "rapidfuzz-3.6.2-cp39-cp39-win_arm64.whl", hash = "sha256:6478f7803efebf5f644d0b758439c5b25728550fdfbb19783d150004c46a75a9"}, {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:36ce7b68a7b90b787cdd73480a68d2f1ca63c31a3a9d5a79a8736f978e1e9344"}, {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53597fd72a9340bcdd80d3620f4957c2b92f9b569313b969a3abdaffd193aae6"}, {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4f6de745fe6ce46a422d353ee10599013631d7d714a36d025f164b2d4e8c000"}, {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62df2136068e2515ed8beb01756381ff62c29384d785e3bf46e3111d4ea3ba1e"}, {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7382c90170f60c846c81a07ddd80bb2e8c43c8383754486fa37f67391a571897"}, {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f31314fd2e2f3dc3e519e6f93669462ce7953df2def1c344aa8f5345976d0eb2"}, {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:012221629d54d3bee954148247f711eb86d4d390b589ebfe03172ea0b37a7531"}, {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d41dd59a70decfce6595315367a2fea2af660d92a9d144acc6479030501014d7"}, {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f9fa14136a5b0cba1ec42531f7c3e0b0d3edb7fd6bc5e5ae7b498541f3855ab"}, {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:259364199cbfeca33b1af369fc7951f71717aa285184a3fa5a7b1772da1b89db"}, {file = "rapidfuzz-3.6.2.tar.gz", hash = "sha256:cf911e792ab0c431694c9bf2648afabfd92099103f2e31492893e078ddca5e1a"}, ] [package.extras] full = ["numpy"] [[package]] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." optional = false python-versions = ">=3.7" files = [ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-toolbelt" version = "1.0.0" description = "A utility belt for advanced users of python-requests" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, ] [package.dependencies] requests = ">=2.0.1,<3.0.0" [[package]] name = "secretstorage" version = "3.3.3" description = "Python bindings to FreeDesktop.org Secret Service API" 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 = "setuptools" version = "69.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shellingham" version = "1.5.4" description = "Tool to Detect Surrounding Shell" optional = false python-versions = ">=3.7" files = [ {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, ] [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" 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"}, ] [[package]] name = "tomlkit" version = "0.12.4" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, ] [[package]] name = "trove-classifiers" version = "2024.3.3" description = "Canonical source for classifiers on PyPI (pypi.org)." optional = false python-versions = "*" files = [ {file = "trove-classifiers-2024.3.3.tar.gz", hash = "sha256:df7edff9c67ff86b733628998330b180e81d125b1e096536d83ac0fd79673fdc"}, {file = "trove_classifiers-2024.3.3-py3-none-any.whl", hash = "sha256:3a84096861b385ec422c79995d1f6435dde47a9b63adaa3c886e53232ba7e6e0"}, ] [[package]] name = "typing-extensions" version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] name = "urllib3" version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" version = "20.25.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ {file = "virtualenv-20.25.1-py3-none-any.whl", hash = "sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a"}, {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "xattr" version = "1.1.0" description = "Python wrapper for extended filesystem attributes" optional = false python-versions = ">=3.8" files = [ {file = "xattr-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ef2fa0f85458736178fd3dcfeb09c3cf423f0843313e25391db2cfd1acec8888"}, {file = "xattr-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ccab735d0632fe71f7d72e72adf886f45c18b7787430467ce0070207882cfe25"}, {file = "xattr-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9013f290387f1ac90bccbb1926555ca9aef75651271098d99217284d9e010f7c"}, {file = "xattr-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcd5dfbcee73c7be057676ecb900cabb46c691aff4397bf48c579ffb30bb963"}, {file = "xattr-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6480589c1dac7785d1f851347a32c4a97305937bf7b488b857fe8b28a25de9e9"}, {file = "xattr-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08f61cbed52dc6f7c181455826a9ff1e375ad86f67dd9d5eb7663574abb32451"}, {file = "xattr-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:918e1f83f2e8a072da2671eac710871ee5af337e9bf8554b5ce7f20cdb113186"}, {file = "xattr-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0f06e0c1e4d06b4e0e49aaa1184b6f0e81c3758c2e8365597918054890763b53"}, {file = "xattr-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46a641ac038a9f53d2f696716147ca4dbd6a01998dc9cd4bc628801bc0df7f4d"}, {file = "xattr-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7e4ca0956fd11679bb2e0c0d6b9cdc0f25470cc00d8da173bb7656cc9a9cf104"}, {file = "xattr-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6881b120f9a4b36ccd8a28d933bc0f6e1de67218b6ce6e66874e0280fc006844"}, {file = "xattr-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dab29d9288aa28e68a6f355ddfc3f0a7342b40c9012798829f3e7bd765e85c2c"}, {file = "xattr-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0c80bbf55339c93770fc294b4b6586b5bf8e85ec00a4c2d585c33dbd84b5006"}, {file = "xattr-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1418705f253b6b6a7224b69773842cac83fcbcd12870354b6e11dd1cd54630f"}, {file = "xattr-1.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:687e7d18611ef8d84a6ecd8f4d1ab6757500c1302f4c2046ce0aa3585e13da3f"}, {file = "xattr-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6ceb9efe0657a982ccb8b8a2efe96b690891779584c901d2f920784e5d20ae3"}, {file = "xattr-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b489b7916f239100956ea0b39c504f3c3a00258ba65677e4c8ba1bd0b5513446"}, {file = "xattr-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0a9c431b0e66516a078125e9a273251d4b8e5ba84fe644b619f2725050d688a0"}, {file = "xattr-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1a5921ea3313cc1c57f2f53b63ea8ca9a91e48f4cc7ebec057d2447ec82c7efe"}, {file = "xattr-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f6ad2a7bd5e6cf71d4a862413234a067cf158ca0ae94a40d4b87b98b62808498"}, {file = "xattr-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0683dae7609f7280b0c89774d00b5957e6ffcb181c6019c46632b389706b77e6"}, {file = "xattr-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54cb15cd94e5ef8a0ef02309f1bf973ba0e13c11e87686e983f371948cfee6af"}, {file = "xattr-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff6223a854229055e803c2ad0c0ea9a6da50c6be30d92c198cf5f9f28819a921"}, {file = "xattr-1.1.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d44e8f955218638c9ab222eed21e9bd9ab430d296caf2176fb37abe69a714e5c"}, {file = "xattr-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:caab2c2986c30f92301f12e9c50415d324412e8e6a739a52a603c3e6a54b3610"}, {file = "xattr-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d6eb7d5f281014cd44e2d847a9107491af1bf3087f5afeded75ed3e37ec87239"}, {file = "xattr-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:47a3bdfe034b4fdb70e5941d97037405e3904accc28e10dbef6d1c9061fb6fd7"}, {file = "xattr-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:00d2b415cf9d6a24112d019e721aa2a85652f7bbc9f3b9574b2d1cd8668eb491"}, {file = "xattr-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:78b377832dd0ee408f9f121a354082c6346960f7b6b1480483ed0618b1912120"}, {file = "xattr-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6461a43b585e5f2e049b39bcbfcb6391bfef3c5118231f1b15d10bdb89ef17fe"}, {file = "xattr-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24d97f0d28f63695e3344ffdabca9fcc30c33e5c8ccc198c7524361a98d526f2"}, {file = "xattr-1.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ad47d89968c9097900607457a0c89160b4771601d813e769f68263755516065"}, {file = "xattr-1.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc53cab265f6e8449bd683d5ee3bc5a191e6dd940736f3de1a188e6da66b0653"}, {file = "xattr-1.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cd11e917f5b89f2a0ad639d9875943806c6c9309a3dd02da5a3e8ef92db7bed9"}, {file = "xattr-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9c5a78c7558989492c4cb7242e490ffb03482437bf782967dfff114e44242343"}, {file = "xattr-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cebcf8a303a44fbc439b68321408af7267507c0d8643229dbb107f6c132d389c"}, {file = "xattr-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b0d73150f2f9655b4da01c2369eb33a294b7f9d56eccb089819eafdbeb99f896"}, {file = "xattr-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:793c01deaadac50926c0e1481702133260c7cb5e62116762f6fe1543d07b826f"}, {file = "xattr-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e189e440bcd04ccaad0474720abee6ee64890823ec0db361fb0a4fb5e843a1bf"}, {file = "xattr-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afacebbc1fa519f41728f8746a92da891c7755e6745164bd0d5739face318e86"}, {file = "xattr-1.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b1664edf003153ac8d1911e83a0fc60db1b1b374ee8ac943f215f93754a1102"}, {file = "xattr-1.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda2684228798e937a7c29b0e1c7ef3d70e2b85390a69b42a1c61b2039ba81de"}, {file = "xattr-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b735ac2625a4fc2c9343b19f806793db6494336338537d2911c8ee4c390dda46"}, {file = "xattr-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fa6a7af7a4ada43f15ccc58b6f9adcdbff4c36ba040013d2681e589e07ae280a"}, {file = "xattr-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1059b2f726e2702c8bbf9bbf369acfc042202a4cc576c2dec6791234ad5e948"}, {file = "xattr-1.1.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e2255f36ebf2cb2dbf772a7437ad870836b7396e60517211834cf66ce678b595"}, {file = "xattr-1.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba4f80b9855cc98513ddf22b7ad8551bc448c70d3147799ea4f6c0b758fb466"}, {file = "xattr-1.1.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb70c16e7c3ae6ba0ab6c6835c8448c61d8caf43ea63b813af1f4dbe83dd156"}, {file = "xattr-1.1.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83652910ef6a368b77b00825ad67815e5c92bfab551a848ca66e9981d14a7519"}, {file = "xattr-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7a92aff66c43fa3e44cbeab7cbeee66266c91178a0f595e044bf3ce51485743b"}, {file = "xattr-1.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d4f71b673339aeaae1f6ea9ef8ea6c9643c8cd0df5003b9a0eaa75403e2e06c"}, {file = "xattr-1.1.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a20de1c47b5cd7b47da61799a3b34e11e5815d716299351f82a88627a43f9a96"}, {file = "xattr-1.1.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23705c7079b05761ff2fa778ad17396e7599c8759401abc05b312dfb3bc99f69"}, {file = "xattr-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:27272afeba8422f2a9d27e1080a9a7b807394e88cce73db9ed8d2dde3afcfb87"}, {file = "xattr-1.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd43978966de3baf4aea367c99ffa102b289d6c2ea5f3d9ce34a203dc2f2ab73"}, {file = "xattr-1.1.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ded771eaf27bb4eb3c64c0d09866460ee8801d81dc21097269cf495b3cac8657"}, {file = "xattr-1.1.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96ca300c0acca4f0cddd2332bb860ef58e1465d376364f0e72a1823fdd58e90d"}, {file = "xattr-1.1.0.tar.gz", hash = "sha256:fecbf3b05043ed3487a28190dec3e4c4d879b2fcec0e30bafd8ec5d4b6043630"}, ] [package.dependencies] cffi = ">=1.16.0" [package.extras] test = ["pytest"] [[package]] name = "zipp" version = "3.18.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ {file = "zipp-3.18.0-py3-none-any.whl", hash = "sha256:c1bb803ed69d2cce2373152797064f7e79bc43f0a3748eb494096a867e0ebf79"}, {file = "zipp-3.18.0.tar.gz", hash = "sha256:df8d042b02765029a09b157efd8e820451045890acc30f8e37dd2f94a060221f"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = "^3.8" content-hash = "a307339f49db1e3c72043055981f0e715ae1892e9592fc74e3f11b64c3709303" poetry-plugin-export-1.8.0/pyproject.toml000066400000000000000000000052101461771375700206110ustar00rootroot00000000000000[tool.poetry] name = "poetry-plugin-export" version = "1.8.0" description = "Poetry plugin to export the dependencies to various formats" authors = ["Sébastien Eustace "] license = "MIT" readme = "README.md" homepage = "https://python-poetry.org/" repository = "https://github.com/python-poetry/poetry-plugin-export" packages = [ { include = "poetry_plugin_export", from = "src" } ] include = [ { path = "tests", format = "sdist" } ] [tool.poetry.dependencies] python = "^3.8" poetry = ">=1.8.0,<3.0.0" poetry-core = ">=1.7.0,<3.0.0" [tool.poetry.group.dev.dependencies] pre-commit = ">=2.18" pytest = "^8.0" pytest-cov = "^4.0" pytest-mock = "^3.9" pytest-randomly = "^3.12" pytest-xdist = { version = "^3.1", extras = ["psutil"] } mypy = ">=0.971" # only used in github actions [tool.poetry.group.github-actions] optional = true [tool.poetry.group.github-actions.dependencies] pytest-github-actions-annotate-failures = "^0.1.7" [tool.poetry.plugins."poetry.application.plugin"] export = "poetry_plugin_export.plugins:ExportApplicationPlugin" [tool.ruff] fix = true target-version = "py38" line-length = 88 extend-exclude = [ "docs/*", # External to the project's coding standards "tests/**/fixtures/*", ] [tool.ruff.lint] unfixable = [ "ERA", # do not autoremove commented out code ] extend-select = [ "B", # flake8-bugbear "C4", # flake8-comprehensions "ERA", # flake8-eradicate/eradicate "I", # isort "N", # pep8-naming "PIE", # flake8-pie "PGH", # pygrep "RUF", # ruff checks "SIM", # flake8-simplify "TCH", # flake8-type-checking "TID", # flake8-tidy-imports "UP", # pyupgrade ] [tool.ruff.lint.flake8-tidy-imports] ban-relative-imports = "all" [tool.ruff.lint.isort] force-single-line = true lines-between-types = 1 lines-after-imports = 2 known-first-party = ["poetry_plugin_export"] required-imports = ["from __future__ import annotations"] [tool.mypy] namespace_packages = true show_error_codes = true enable_error_code = [ "ignore-without-code", "redundant-expr", "truthy-bool", ] strict = true files = ["src", "tests"] exclude = ["^tests/fixtures/"] # use of importlib-metadata backport makes it impossible to satisfy mypy # without some ignores: but we get a different set of ignores at different # python versions. # # , meanwhile suppress that # warning. [[tool.mypy.overrides]] module = [ 'poetry_plugin_export', ] warn_unused_ignores = false [tool.pytest.ini_options] addopts = "-n auto" testpaths = [ "tests" ] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" poetry-plugin-export-1.8.0/src/000077500000000000000000000000001461771375700164665ustar00rootroot00000000000000poetry-plugin-export-1.8.0/src/poetry_plugin_export/000077500000000000000000000000001461771375700227675ustar00rootroot00000000000000poetry-plugin-export-1.8.0/src/poetry_plugin_export/__init__.py000066400000000000000000000002501461771375700250750ustar00rootroot00000000000000from __future__ import annotations from poetry.utils._compat import metadata __version__ = metadata.version("poetry-plugin-export") # type: ignore[no-untyped-call] poetry-plugin-export-1.8.0/src/poetry_plugin_export/command.py000066400000000000000000000104161461771375700247610ustar00rootroot00000000000000from __future__ import annotations from pathlib import Path from typing import TYPE_CHECKING from cleo.helpers import option from packaging.utils import NormalizedName from packaging.utils import canonicalize_name from poetry.console.commands.group_command import GroupCommand from poetry.core.packages.dependency_group import MAIN_GROUP from poetry_plugin_export.exporter import Exporter if TYPE_CHECKING: from collections.abc import Iterable class ExportCommand(GroupCommand): name = "export" description = "Exports the lock file to alternative formats." options = [ # noqa: RUF012 option( "format", "f", "Format to export to. Currently, only constraints.txt and" " requirements.txt are supported.", flag=False, default=Exporter.FORMAT_REQUIREMENTS_TXT, ), option("output", "o", "The name of the output file.", flag=False), option("without-hashes", None, "Exclude hashes from the exported file."), option( "without-urls", None, "Exclude source repository urls from the exported file.", ), option( "dev", None, "Include development dependencies. (Deprecated)", ), *GroupCommand._group_dependency_options(), option( "extras", "E", "Extra sets of dependencies to include.", flag=False, multiple=True, ), option("all-extras", None, "Include all sets of extra dependencies."), option("with-credentials", None, "Include credentials for extra indices."), ] @property def non_optional_groups(self) -> set[str]: # method only required for poetry <= 1.2.0-beta.2.dev0 return {MAIN_GROUP} @property def default_groups(self) -> set[str]: return {MAIN_GROUP} def handle(self) -> int: fmt = self.option("format") if not Exporter.is_format_supported(fmt): raise ValueError(f"Invalid export format: {fmt}") output = self.option("output") locker = self.poetry.locker if not locker.is_locked(): self.line_error("The lock file does not exist. Locking.") options = [] if self.io.is_debug(): options.append(("-vvv", None)) elif self.io.is_very_verbose(): options.append(("-vv", None)) elif self.io.is_verbose(): options.append(("-v", None)) self.call("lock", " ".join(options)) # type: ignore[arg-type] if not locker.is_fresh(): self.line_error( "" "Warning: poetry.lock is not consistent with pyproject.toml. " "You may be getting improper dependencies. " "Run `poetry lock [--no-update]` to fix it." "" ) # Checking extras if self.option("extras") and self.option("all-extras"): self.line_error( "You cannot specify explicit" " `--extras` while exporting" " using `--all-extras`." ) return 1 extras: Iterable[NormalizedName] if self.option("all-extras"): extras = self.poetry.package.extras.keys() else: extras = { canonicalize_name(extra) for extra_opt in self.option("extras") for extra in extra_opt.split() } invalid_extras = extras - self.poetry.package.extras.keys() if invalid_extras: raise ValueError( f"Extra [{', '.join(sorted(invalid_extras))}] is not specified." ) exporter = Exporter(self.poetry, self.io) exporter.only_groups(list(self.activated_groups)) exporter.with_extras(list(extras)) exporter.with_hashes(not self.option("without-hashes")) exporter.with_credentials(self.option("with-credentials")) exporter.with_urls(not self.option("without-urls")) exporter.export(fmt, Path.cwd(), output or self.io) return 0 poetry-plugin-export-1.8.0/src/poetry_plugin_export/exporter.py000066400000000000000000000163111461771375700252130ustar00rootroot00000000000000from __future__ import annotations import urllib.parse from functools import partialmethod from typing import TYPE_CHECKING from typing import Iterable from cleo.io.io import IO from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.repositories.http_repository import HTTPRepository from poetry_plugin_export.walker import get_project_dependency_packages if TYPE_CHECKING: from collections.abc import Collection from pathlib import Path from typing import ClassVar from packaging.utils import NormalizedName from poetry.poetry import Poetry class Exporter: """ Exporter class to export a lock file to alternative formats. """ FORMAT_CONSTRAINTS_TXT = "constraints.txt" FORMAT_REQUIREMENTS_TXT = "requirements.txt" ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512") EXPORT_METHODS: ClassVar[dict[str, str]] = { FORMAT_CONSTRAINTS_TXT: "_export_constraints_txt", FORMAT_REQUIREMENTS_TXT: "_export_requirements_txt", } def __init__(self, poetry: Poetry, io: IO) -> None: self._poetry = poetry self._io = io self._with_hashes = True self._with_credentials = False self._with_urls = True self._extras: Collection[NormalizedName] = () self._groups: Iterable[str] = [MAIN_GROUP] @classmethod def is_format_supported(cls, fmt: str) -> bool: return fmt in cls.EXPORT_METHODS def with_extras(self, extras: Collection[NormalizedName]) -> Exporter: self._extras = extras return self def only_groups(self, groups: Iterable[str]) -> Exporter: self._groups = groups return self def with_urls(self, with_urls: bool = True) -> Exporter: self._with_urls = with_urls return self def with_hashes(self, with_hashes: bool = True) -> Exporter: self._with_hashes = with_hashes return self def with_credentials(self, with_credentials: bool = True) -> Exporter: self._with_credentials = with_credentials return self def export(self, fmt: str, cwd: Path, output: IO | str) -> None: if not self.is_format_supported(fmt): raise ValueError(f"Invalid export format: {fmt}") getattr(self, self.EXPORT_METHODS[fmt])(cwd, output) def _export_generic_txt( self, cwd: Path, output: IO | str, with_extras: bool, allow_editable: bool ) -> None: from poetry.core.packages.utils.utils import path_to_url indexes = set() content = "" dependency_lines = set() root = self._poetry.package.with_dependency_groups( list(self._groups), only=True ) for dependency_package in get_project_dependency_packages( self._poetry.locker, project_requires=root.all_requires, root_package_name=root.name, project_python_marker=root.python_marker, extras=self._extras, ): line = "" if not with_extras: dependency_package = dependency_package.without_features() dependency = dependency_package.dependency package = dependency_package.package if package.develop and not allow_editable: self._io.write_error_line( f"Warning: {package.pretty_name} is locked in develop" " (editable) mode, which is incompatible with the" " constraints.txt format." ) continue requirement = dependency.to_pep_508(with_extras=False, resolved=True) is_direct_local_reference = ( dependency.is_file() or dependency.is_directory() ) is_direct_remote_reference = dependency.is_vcs() or dependency.is_url() if is_direct_remote_reference: line = requirement elif is_direct_local_reference: assert dependency.source_url is not None dependency_uri = path_to_url(dependency.source_url) if package.develop: line = f"-e {dependency_uri}" else: line = f"{package.complete_name} @ {dependency_uri}" else: line = f"{package.complete_name}=={package.version}" if not is_direct_remote_reference and ";" in requirement: markers = requirement.split(";", 1)[1].strip() if markers: line += f" ; {markers}" if ( not is_direct_remote_reference and not is_direct_local_reference and package.source_url ): indexes.add(package.source_url.rstrip("/")) if package.files and self._with_hashes: hashes = [] for f in package.files: h = f["hash"] algorithm = "sha256" if ":" in h: algorithm, h = h.split(":") if algorithm not in self.ALLOWED_HASH_ALGORITHMS: continue hashes.append(f"{algorithm}:{h}") hashes.sort() for h in hashes: line += f" \\\n --hash={h}" dependency_lines.add(line) content += "\n".join(sorted(dependency_lines)) content += "\n" if indexes and self._with_urls: # If we have extra indexes, we add them to the beginning of the output indexes_header = "" has_pypi_repository = any( r.name.lower() == "pypi" for r in self._poetry.pool.all_repositories ) # Iterate over repositories so that we get the repository with the highest # priority first so that --index-url comes before --extra-index-url for repository in self._poetry.pool.all_repositories: if ( not isinstance(repository, HTTPRepository) or repository.url not in indexes ): continue url = ( repository.authenticated_url if self._with_credentials else repository.url ) parsed_url = urllib.parse.urlsplit(url) if parsed_url.scheme == "http": indexes_header += f"--trusted-host {parsed_url.netloc}\n" if ( not has_pypi_repository and repository is self._poetry.pool.repositories[0] ): indexes_header += f"--index-url {url}\n" else: indexes_header += f"--extra-index-url {url}\n" content = indexes_header + "\n" + content if isinstance(output, IO): output.write(content) else: with (cwd / output).open("w", encoding="utf-8") as txt: txt.write(content) _export_constraints_txt = partialmethod( _export_generic_txt, with_extras=False, allow_editable=False ) _export_requirements_txt = partialmethod( _export_generic_txt, with_extras=True, allow_editable=True ) poetry-plugin-export-1.8.0/src/poetry_plugin_export/plugins.py000066400000000000000000000016751461771375700250330ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING from poetry.plugins.application_plugin import ApplicationPlugin from poetry_plugin_export.command import ExportCommand if TYPE_CHECKING: from poetry.console.application import Application from poetry.console.commands.command import Command class ExportApplicationPlugin(ApplicationPlugin): @property def commands(self) -> list[type[Command]]: return [ExportCommand] def activate(self, application: Application) -> None: # Removing the existing export command to avoid an error # until Poetry removes the export command # and uses this plugin instead. # If you're checking this code out to get inspiration # for your own plugins: DON'T DO THIS! if application.command_loader.has("export"): del application.command_loader._factories["export"] super().activate(application=application) poetry-plugin-export-1.8.0/src/poetry_plugin_export/walker.py000066400000000000000000000233151461771375700246320ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING from packaging.utils import canonicalize_name from poetry.core.constraints.version.util import constraint_regions from poetry.core.version.markers import AnyMarker from poetry.core.version.markers import SingleMarker from poetry.packages import DependencyPackage from poetry.utils.extras import get_extra_package_names if TYPE_CHECKING: from collections.abc import Collection from collections.abc import Iterable from collections.abc import Iterator from packaging.utils import NormalizedName from poetry.core.packages.dependency import Dependency from poetry.core.packages.package import Package from poetry.core.version.markers import BaseMarker from poetry.packages import Locker def get_python_version_region_markers(packages: list[Package]) -> list[BaseMarker]: markers = [] regions = constraint_regions([package.python_constraint for package in packages]) for region in regions: marker: BaseMarker = AnyMarker() if region.min is not None: min_operator = ">=" if region.include_min else ">" marker_name = ( "python_full_version" if region.min.precision > 2 else "python_version" ) lo = SingleMarker(marker_name, f"{min_operator} {region.min}") marker = marker.intersect(lo) if region.max is not None: max_operator = "<=" if region.include_max else "<" marker_name = ( "python_full_version" if region.max.precision > 2 else "python_version" ) hi = SingleMarker(marker_name, f"{max_operator} {region.max}") marker = marker.intersect(hi) markers.append(marker) return markers def get_project_dependency_packages( locker: Locker, project_requires: list[Dependency], root_package_name: NormalizedName, project_python_marker: BaseMarker | None = None, extras: Collection[NormalizedName] = (), ) -> Iterator[DependencyPackage]: # Apply the project python marker to all requirements. if project_python_marker is not None: marked_requires: list[Dependency] = [] for require in project_requires: require = require.clone() require.marker = require.marker.intersect(project_python_marker) marked_requires.append(require) project_requires = marked_requires repository = locker.locked_repository() # Build a set of all packages required by our selected extras locked_extras = { canonicalize_name(extra): [ canonicalize_name(dependency) for dependency in dependencies ] for extra, dependencies in locker.lock_data.get("extras", {}).items() } extra_package_names = get_extra_package_names( repository.packages, locked_extras, extras, ) # If a package is optional and we haven't opted in to it, do not select selected = [] for dependency in project_requires: try: package = repository.find_packages(dependency=dependency)[0] except IndexError: continue if package.optional and package.name not in extra_package_names: # a package is locked as optional, but is not activated via extras continue selected.append(dependency) for package, dependency in get_project_dependencies( project_requires=selected, locked_packages=repository.packages, root_package_name=root_package_name, ): yield DependencyPackage(dependency=dependency, package=package) def get_project_dependencies( project_requires: list[Dependency], locked_packages: list[Package], root_package_name: NormalizedName, ) -> Iterable[tuple[Package, Dependency]]: # group packages entries by name, this is required because requirement might use # different constraints. packages_by_name: dict[str, list[Package]] = {} for pkg in locked_packages: if pkg.name not in packages_by_name: packages_by_name[pkg.name] = [] packages_by_name[pkg.name].append(pkg) # Put higher versions first so that we prefer them. for packages in packages_by_name.values(): packages.sort( key=lambda package: package.version, reverse=True, ) nested_dependencies = walk_dependencies( dependencies=project_requires, packages_by_name=packages_by_name, root_package_name=root_package_name, ) return nested_dependencies.items() def walk_dependencies( dependencies: list[Dependency], packages_by_name: dict[str, list[Package]], root_package_name: NormalizedName, ) -> dict[Package, Dependency]: nested_dependencies: dict[Package, Dependency] = {} visited: set[tuple[Dependency, BaseMarker]] = set() while dependencies: requirement = dependencies.pop(0) if (requirement, requirement.marker) in visited: continue if requirement.name == root_package_name: continue visited.add((requirement, requirement.marker)) locked_package = get_locked_package( requirement, packages_by_name, nested_dependencies ) if not locked_package: raise RuntimeError(f"Dependency walk failed at {requirement}") if requirement.extras: locked_package = locked_package.with_features(requirement.extras) # create dependency from locked package to retain dependency metadata # if this is not done, we can end-up with incorrect nested dependencies constraint = requirement.constraint marker = requirement.marker requirement = locked_package.to_dependency() requirement.marker = requirement.marker.intersect(marker) requirement.constraint = constraint for require in locked_package.requires: if require.is_optional() and not any( require in locked_package.extras.get(feature, ()) for feature in locked_package.features ): continue base_marker = require.marker.intersect(requirement.marker).without_extras() if not base_marker.is_empty(): # So as to give ourselves enough flexibility in choosing a solution, # we need to split the world up into the python version ranges that # this package might care about. # # We create a marker for all of the possible regions, and add a # requirement for each separately. candidates = packages_by_name.get(require.name, []) region_markers = get_python_version_region_markers(candidates) for region_marker in region_markers: marker = region_marker.intersect(base_marker) if not marker.is_empty(): require2 = require.clone() require2.marker = marker dependencies.append(require2) key = locked_package if key not in nested_dependencies: nested_dependencies[key] = requirement else: nested_dependencies[key].marker = nested_dependencies[key].marker.union( requirement.marker ) return nested_dependencies def get_locked_package( dependency: Dependency, packages_by_name: dict[str, list[Package]], decided: dict[Package, Dependency] | None = None, ) -> Package | None: """ Internal helper to identify corresponding locked package using dependency version constraints. """ decided = decided or {} candidates = packages_by_name.get(dependency.name, []) # If we've previously chosen a version of this package that is compatible with # the current requirement, we are forced to stick with it. (Else we end up with # different versions of the same package at the same time.) overlapping_candidates = set() for package in candidates: old_decision = decided.get(package) if ( old_decision is not None and not old_decision.marker.intersect(dependency.marker).is_empty() ): overlapping_candidates.add(package) # If we have more than one overlapping candidate, we've run into trouble. if len(overlapping_candidates) > 1: return None # Get the packages that are consistent with this dependency. compatible_candidates = [ package for package in candidates if package.python_constraint.allows_all(dependency.python_constraint) and dependency.constraint.allows(package.version) and (dependency.source_type is None or dependency.is_same_source_as(package)) ] # If we have an overlapping candidate, we must use it. if overlapping_candidates: filtered_compatible_candidates = [ package for package in compatible_candidates if package in overlapping_candidates ] if not filtered_compatible_candidates: # TODO: Support this case: # https://github.com/python-poetry/poetry-plugin-export/issues/183 raise DependencyWalkerError( f"The `{dependency.name}` package has the following compatible" f" candidates `{compatible_candidates}`; but, the exporter dependency" f" walker previously elected `{overlapping_candidates.pop()}` which is" f" not compatible with the dependency `{dependency}`. Please contribute" " to `poetry-plugin-export` to solve this problem." ) compatible_candidates = filtered_compatible_candidates return next(iter(compatible_candidates), None) class DependencyWalkerError(Exception): pass poetry-plugin-export-1.8.0/tests/000077500000000000000000000000001461771375700170415ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/__init__.py000066400000000000000000000000001461771375700211400ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/command/000077500000000000000000000000001461771375700204575ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/command/__init__.py000066400000000000000000000000001461771375700225560ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/command/conftest.py000066400000000000000000000047651461771375700226720ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING import pytest from cleo.io.null_io import NullIO from cleo.testers.command_tester import CommandTester from poetry.console.commands.env_command import EnvCommand from poetry.console.commands.installer_command import InstallerCommand from poetry.installation import Installer from poetry.utils.env import MockEnv from tests.helpers import PoetryTestApplication from tests.helpers import TestExecutor if TYPE_CHECKING: from pathlib import Path from poetry.installation.executor import Executor from poetry.poetry import Poetry from poetry.utils.env import Env from tests.types import CommandTesterFactory @pytest.fixture def app(poetry: Poetry) -> PoetryTestApplication: app_ = PoetryTestApplication(poetry) return app_ @pytest.fixture def env(tmp_path: Path) -> MockEnv: path = tmp_path / ".venv" path.mkdir(parents=True) return MockEnv(path=path, is_venv=True) @pytest.fixture def command_tester_factory( app: PoetryTestApplication, env: MockEnv ) -> CommandTesterFactory: def _tester( command: str, poetry: Poetry | None = None, installer: Installer | None = None, executor: Executor | None = None, environment: Env | None = None, ) -> CommandTester: app._load_plugins(NullIO()) cmd = app.find(command) tester = CommandTester(cmd) # Setting the formatter from the application # TODO: Find a better way to do this in Cleo app_io = app.create_io() formatter = app_io.output.formatter tester.io.output.set_formatter(formatter) tester.io.error_output.set_formatter(formatter) if poetry: app._poetry = poetry poetry = app.poetry if isinstance(cmd, EnvCommand): cmd.set_env(environment or env) if isinstance(cmd, InstallerCommand): installer = installer or Installer( tester.io, env, poetry.package, poetry.locker, poetry.pool, poetry.config, executor=executor or TestExecutor(env, poetry.pool, poetry.config, tester.io), ) cmd.set_installer(installer) return tester return _tester @pytest.fixture def do_lock(command_tester_factory: CommandTesterFactory, poetry: Poetry) -> None: command_tester_factory("lock").execute() assert poetry.locker.lock.exists() poetry-plugin-export-1.8.0/tests/command/test_command_export.py000066400000000000000000000203321461771375700251070ustar00rootroot00000000000000from __future__ import annotations import shutil from typing import TYPE_CHECKING from unittest.mock import Mock import pytest from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.core.packages.package import Package from poetry_plugin_export.exporter import Exporter from tests.markers import MARKER_PY if TYPE_CHECKING: from pathlib import Path from _pytest.monkeypatch import MonkeyPatch from cleo.testers.command_tester import CommandTester from poetry.poetry import Poetry from poetry.repositories import Repository from tests.types import CommandTesterFactory from tests.types import ProjectFactory PYPROJECT_CONTENT = """\ [tool.poetry] name = "simple-project" version = "1.2.3" description = "Some description." authors = [ "Sébastien Eustace " ] license = "MIT" readme = "README.rst" homepage = "https://python-poetry.org" repository = "https://github.com/python-poetry/poetry" documentation = "https://python-poetry.org/docs" keywords = ["packaging", "dependency", "poetry"] classifiers = [ "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules" ] # Requirements [tool.poetry.dependencies] python = "~2.7 || ^3.6" foo = "^1.0" bar = { version = "^1.1", optional = true } qux = { version = "^1.2", optional = true } [tool.poetry.group.dev.dependencies] baz = "^2.0" [tool.poetry.group.opt] optional = true [tool.poetry.group.opt.dependencies] opt = "^2.2" [tool.poetry.extras] feature_bar = ["bar"] feature_qux = ["qux"] """ @pytest.fixture(autouse=True) def setup(repo: Repository) -> None: repo.add_package(Package("foo", "1.0.0")) repo.add_package(Package("bar", "1.1.0")) repo.add_package(Package("baz", "2.0.0")) repo.add_package(Package("opt", "2.2.0")) repo.add_package(Package("qux", "1.2.0")) @pytest.fixture def poetry(project_factory: ProjectFactory) -> Poetry: return project_factory(name="export", pyproject_content=PYPROJECT_CONTENT) @pytest.fixture def tester( command_tester_factory: CommandTesterFactory, poetry: Poetry ) -> CommandTester: return command_tester_factory("export", poetry=poetry) def _export_requirements(tester: CommandTester, poetry: Poetry, tmp_path: Path) -> None: from tests.helpers import as_cwd with as_cwd(tmp_path): tester.execute("--format requirements.txt --output requirements.txt") requirements = tmp_path / "requirements.txt" assert requirements.exists() with requirements.open(encoding="utf-8") as f: content = f.read() assert poetry.locker.lock.exists() expected = f"""\ foo==1.0.0 ; {MARKER_PY} """ assert content == expected def test_export_exports_requirements_txt_file_locks_if_no_lock_file( tester: CommandTester, poetry: Poetry, tmp_path: Path ) -> None: assert not poetry.locker.lock.exists() _export_requirements(tester, poetry, tmp_path) assert "The lock file does not exist. Locking." in tester.io.fetch_error() def test_export_exports_requirements_txt_uses_lock_file( tester: CommandTester, poetry: Poetry, tmp_path: Path, do_lock: None ) -> None: _export_requirements(tester, poetry, tmp_path) assert "The lock file does not exist. Locking." not in tester.io.fetch_error() def test_export_fails_on_invalid_format(tester: CommandTester, do_lock: None) -> None: with pytest.raises(ValueError): tester.execute("--format invalid") def test_export_prints_to_stdout_by_default( tester: CommandTester, do_lock: None ) -> None: tester.execute("--format requirements.txt") expected = f"""\ foo==1.0.0 ; {MARKER_PY} """ assert tester.io.fetch_output() == expected def test_export_uses_requirements_txt_format_by_default( tester: CommandTester, do_lock: None ) -> None: tester.execute() expected = f"""\ foo==1.0.0 ; {MARKER_PY} """ assert tester.io.fetch_output() == expected @pytest.mark.parametrize( "options, expected", [ ("", f"foo==1.0.0 ; {MARKER_PY}\n"), ("--with dev", f"baz==2.0.0 ; {MARKER_PY}\nfoo==1.0.0 ; {MARKER_PY}\n"), ("--with opt", f"foo==1.0.0 ; {MARKER_PY}\nopt==2.2.0 ; {MARKER_PY}\n"), ( "--with dev,opt", ( f"baz==2.0.0 ; {MARKER_PY}\nfoo==1.0.0 ; {MARKER_PY}\nopt==2.2.0 ;" f" {MARKER_PY}\n" ), ), (f"--without {MAIN_GROUP}", "\n"), ("--without dev", f"foo==1.0.0 ; {MARKER_PY}\n"), ("--without opt", f"foo==1.0.0 ; {MARKER_PY}\n"), (f"--without {MAIN_GROUP},dev,opt", "\n"), (f"--only {MAIN_GROUP}", f"foo==1.0.0 ; {MARKER_PY}\n"), ("--only dev", f"baz==2.0.0 ; {MARKER_PY}\n"), ( f"--only {MAIN_GROUP},dev", f"baz==2.0.0 ; {MARKER_PY}\nfoo==1.0.0 ; {MARKER_PY}\n", ), ], ) def test_export_groups( tester: CommandTester, do_lock: None, options: str, expected: str ) -> None: tester.execute(options) assert tester.io.fetch_output() == expected @pytest.mark.parametrize( "extras, expected", [ ( "feature_bar", f"""\ bar==1.1.0 ; {MARKER_PY} foo==1.0.0 ; {MARKER_PY} """, ), ( "feature_bar feature_qux", f"""\ bar==1.1.0 ; {MARKER_PY} foo==1.0.0 ; {MARKER_PY} qux==1.2.0 ; {MARKER_PY} """, ), ], ) def test_export_includes_extras_by_flag( tester: CommandTester, do_lock: None, extras: str, expected: str ) -> None: tester.execute(f"--format requirements.txt --extras '{extras}'") assert tester.io.fetch_output() == expected def test_export_reports_invalid_extras(tester: CommandTester, do_lock: None) -> None: with pytest.raises(ValueError) as error: tester.execute("--format requirements.txt --extras 'SUS AMONGUS'") expected = "Extra [amongus, sus] is not specified." assert str(error.value) == expected def test_export_with_all_extras(tester: CommandTester, do_lock: None) -> None: tester.execute("--format requirements.txt --all-extras") output = tester.io.fetch_output() assert f"bar==1.1.0 ; {MARKER_PY}" in output assert f"qux==1.2.0 ; {MARKER_PY}" in output def test_extras_conflicts_all_extras(tester: CommandTester, do_lock: None) -> None: tester.execute("--extras bar --all-extras") assert tester.status_code == 1 assert ( "You cannot specify explicit `--extras` while exporting using `--all-extras`.\n" in tester.io.fetch_error() ) def test_export_with_urls( monkeypatch: MonkeyPatch, tester: CommandTester, poetry: Poetry ) -> None: """ We are just validating that the option gets passed. The option itself is tested in the Exporter test. """ mock_export = Mock() monkeypatch.setattr(Exporter, "with_urls", mock_export) tester.execute("--without-urls") mock_export.assert_called_once_with(False) def test_export_exports_constraints_txt_with_warnings( tmp_path: Path, fixture_root: Path, project_factory: ProjectFactory, command_tester_factory: CommandTesterFactory, ) -> None: # On Windows we have to make sure that the path dependency and the pyproject.toml # are on the same drive, otherwise locking fails. # (in our CI fixture_root is on D:\ but temp_path is on C:\) editable_dep_path = tmp_path / "project_with_nested_local" shutil.copytree(fixture_root / "project_with_nested_local", editable_dep_path) pyproject_content = f"""\ [tool.poetry] name = "simple-project" version = "1.2.3" description = "Some description." authors = [ "Sébastien Eustace " ] [tool.poetry.dependencies] python = "^3.6" baz = ">1.0" project-with-nested-local = {{ path = "{editable_dep_path.as_posix()}", \ develop = true }} """ poetry = project_factory(name="export", pyproject_content=pyproject_content) tester = command_tester_factory("export", poetry=poetry) tester.execute("--format constraints.txt") develop_warning = ( "Warning: project-with-nested-local is locked in develop (editable) mode, which" " is incompatible with the constraints.txt format.\n" ) expected = 'baz==2.0.0 ; python_version >= "3.6" and python_version < "4.0"\n' assert develop_warning in tester.io.fetch_error() assert tester.io.fetch_output() == expected poetry-plugin-export-1.8.0/tests/conftest.py000066400000000000000000000130511461771375700212400ustar00rootroot00000000000000from __future__ import annotations import sys from pathlib import Path from typing import TYPE_CHECKING from typing import Any import pytest from poetry.config.config import Config as BaseConfig from poetry.config.dict_config_source import DictConfigSource from poetry.core.packages.package import Package from poetry.factory import Factory from poetry.layouts import layout from poetry.repositories import Repository from poetry.repositories.repository_pool import RepositoryPool from poetry.utils.env import SystemEnv from tests.helpers import TestLocker if TYPE_CHECKING: from poetry.poetry import Poetry from pytest_mock import MockerFixture from tests.types import ProjectFactory class Config(BaseConfig): def get(self, setting_name: str, default: Any = None) -> Any: self.merge(self._config_source.config) # type: ignore[attr-defined] self.merge(self._auth_config_source.config) # type: ignore[attr-defined] return super().get(setting_name, default=default) def raw(self) -> dict[str, Any]: self.merge(self._config_source.config) # type: ignore[attr-defined] self.merge(self._auth_config_source.config) # type: ignore[attr-defined] return super().raw() def all(self) -> dict[str, Any]: self.merge(self._config_source.config) # type: ignore[attr-defined] self.merge(self._auth_config_source.config) # type: ignore[attr-defined] return super().all() @pytest.fixture def config_cache_dir(tmp_path: Path) -> Path: path = tmp_path / ".cache" / "pypoetry" path.mkdir(parents=True) return path @pytest.fixture def config_source(config_cache_dir: Path) -> DictConfigSource: source = DictConfigSource() source.add_property("cache-dir", str(config_cache_dir)) return source @pytest.fixture def auth_config_source() -> DictConfigSource: source = DictConfigSource() return source @pytest.fixture def config( config_source: DictConfigSource, auth_config_source: DictConfigSource, mocker: MockerFixture, ) -> Config: import keyring from keyring.backends.fail import Keyring keyring.set_keyring(Keyring()) # type: ignore[no-untyped-call] c = Config() c.merge(config_source.config) c.set_config_source(config_source) c.set_auth_config_source(auth_config_source) mocker.patch("poetry.config.config.Config.create", return_value=c) mocker.patch("poetry.config.config.Config.set_config_source") return c @pytest.fixture def fixture_root() -> Path: return Path(__file__).parent / "fixtures" @pytest.fixture def fixture_root_uri(fixture_root: Path) -> str: return fixture_root.as_uri() @pytest.fixture() def repo() -> Repository: return Repository("repo") @pytest.fixture def installed() -> Repository: return Repository("installed") @pytest.fixture(scope="session") def current_env() -> SystemEnv: return SystemEnv(Path(sys.executable)) @pytest.fixture(scope="session") def current_python(current_env: SystemEnv) -> tuple[Any, ...]: return current_env.version_info[:3] @pytest.fixture(scope="session") def default_python(current_python: tuple[int, int, int]) -> str: return "^" + ".".join(str(v) for v in current_python[:2]) @pytest.fixture def project_factory( tmp_path: Path, config: Config, repo: Repository, installed: Repository, default_python: str, ) -> ProjectFactory: def _factory( name: str, dependencies: dict[str, str] | None = None, dev_dependencies: dict[str, str] | None = None, pyproject_content: str | None = None, poetry_lock_content: str | None = None, install_deps: bool = True, ) -> Poetry: project_dir = tmp_path / f"poetry-fixture-{name}" dependencies = dependencies or {} dev_dependencies = dev_dependencies or {} if pyproject_content: project_dir.mkdir(parents=True, exist_ok=True) with project_dir.joinpath("pyproject.toml").open( "w", encoding="utf-8" ) as f: f.write(pyproject_content) else: layout("src")( name, "0.1.0", author="PyTest Tester ", readme_format="md", python=default_python, dependencies=dict(dependencies), dev_dependencies=dict(dev_dependencies), ).create(project_dir, with_tests=False) if poetry_lock_content: lock_file = project_dir / "poetry.lock" lock_file.write_text(data=poetry_lock_content, encoding="utf-8") poetry = Factory().create_poetry(project_dir) try: # with https://github.com/python-poetry/poetry/pull/9133 locker = TestLocker( poetry.locker.lock, poetry.locker._pyproject_data, # type: ignore[attr-defined] ) except AttributeError: # before https://github.com/python-poetry/poetry/pull/9133 locker = TestLocker(poetry.locker.lock, poetry.locker._local_config) locker.write() poetry.set_locker(locker) poetry.set_config(config) pool = RepositoryPool() pool.add_repository(repo) poetry.set_pool(pool) if install_deps: for deps in [dependencies, dev_dependencies]: for name, version in deps.items(): pkg = Package(name, version) repo.add_package(pkg) installed.add_package(pkg) return poetry return _factory poetry-plugin-export-1.8.0/tests/fixtures/000077500000000000000000000000001461771375700207125ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/distributions/000077500000000000000000000000001461771375700236145ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/distributions/demo-0.1.0-py2.py3-none-any.whl000066400000000000000000000021341461771375700306520ustar00rootroot00000000000000PK! qdemo/__init__.py__version__ = '0.1.0' PK!H@ WXdemo-0.1.0.dist-info/WHEEL A н#f DI޾p}pfCSmֻ.,"檸m - |PK!H&pdemo-0.1.0.dist-info/METADATAJ@)^i1KF +)k,zLb6[G#[JW;󝙁'%:X)OX4cͼRhحV SqW<l"ؖqݫ6f_sNRco.hEP,K\jH^tp(Oy+HbFkRRX>52l*`Sp3Nݨ+χ<:7:7;7,P O:hyKzލN&}!ϡ!Wp<pZoҵ=PK!Hs demo-0.1.0.dist-info/RECORDm̻v0oI0p@MD.9J Di%}~]ܼp뛞 ai;N4{ϪλPp8KN po l YRMs<.{ǤG{UIѪ/ke\  IX?Xt̓ @҈&75KSk-ͮ]f`vPK! qdemo/__init__.pyPK!H@ WXDdemo-0.1.0.dist-info/WHEELPK!H&pdemo-0.1.0.dist-info/METADATAPK!Hs (demo-0.1.0.dist-info/RECORDPK,poetry-plugin-export-1.8.0/tests/fixtures/distributions/demo-0.1.0.tar.gz000066400000000000000000000017011461771375700263200ustar00rootroot00000000000000A[demo-0.1.0.tarWn65.#ѲhsСa[@o2O`m"Ee1}{~v!R<7&?|4'ONsf\> A|S6|C×5S0Co?z - >t&CzH4J3^ $ Mq?D)tjOɆIpe\BYط7wh@\wq0!9q|8p.qjQ)3je?*Gt3Á2'Z-&dggn! ЌS%*ݱbI*ޫ?xj-xSry; o)"7Ahu^2/g ^OP1S2o$i0-GĆ\q־]#ˡUCJ }KLJK3!l Sڍ{ǖ.[Yہ溩OGt:ੜrFAgJx&jhd*Ǣ*6=gsn:E't6c٦+O' -Qqy/Pםdmiu F:=0-giejnƿBkv{-9?>bsmI粜gmDz]kk&k1/M]mT>][ߴjyIuqrFѫGcp=܍B,ea@AJgz~ɷ_bl$s͌O[/L1%:L蚷jEsYiM }a-ŷݯk .C/;' Nv欮ř0sŊևS7%de$޺p=F.$){{CM&x ]6c󏺜x3 e(poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/000077500000000000000000000000001461771375700261275ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/bar/000077500000000000000000000000001461771375700266735ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/bar/pyproject.toml000066400000000000000000000004101461771375700316020ustar00rootroot00000000000000[tool.poetry] name = "bar" version = "1.2.3" description = "Some description." authors = ["Poetry Maintainer "] license = "MIT" # Requirements [tool.poetry.dependencies] python = "~2.7 || ^3.4" quix = { path = "../quix", develop = true } poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/foo/000077500000000000000000000000001461771375700267125ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/foo/pyproject.toml000066400000000000000000000004061461771375700316260ustar00rootroot00000000000000[tool.poetry] name = "foo" version = "1.2.3" description = "Some description." authors = ["Poetry Maintainer "] license = "MIT" # Requirements [tool.poetry.dependencies] python = "~2.7 || ^3.4" bar = { path = "../bar", develop = true } poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/pyproject.toml000066400000000000000000000005041461771375700310420ustar00rootroot00000000000000[tool.poetry] name = "project-with-nested-local" version = "1.2.3" description = "Some description." authors = ["Poetry Maintainer "] license = "MIT" # Requirements [tool.poetry.dependencies] python = "~2.7 || ^3.4" foo = { path = "./foo", develop = true } bar = { path = "./bar", develop = true } poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/quix/000077500000000000000000000000001461771375700271155ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_nested_local/quix/pyproject.toml000066400000000000000000000003351461771375700320320ustar00rootroot00000000000000[tool.poetry] name = "quix" version = "1.2.3" description = "Some description." authors = ["Poetry Maintainer "] license = "MIT" # Requirements [tool.poetry.dependencies] python = "~2.7 || ^3.4" poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/000077500000000000000000000000001461771375700246335ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/my_package/000077500000000000000000000000001461771375700267335ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/my_package/__init__.py000066400000000000000000000000001461771375700310320ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/project_with_setup.egg-info/000077500000000000000000000000001461771375700322465ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/project_with_setup.egg-info/PKG-INFO000066400000000000000000000003571461771375700333500ustar00rootroot00000000000000Metadata-Version: 1.0 Name: project-with-setup Version: 0.1.2 Summary: Demo project. Home-page: https://github.com/demo/demo Author: Sébastien Eustace Author-email: sebastien@eustace.io License: MIT Description: UNKNOWN Platform: UNKNOWN poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/project_with_setup.egg-info/SOURCES.txt000066400000000000000000000003111461771375700341250ustar00rootroot00000000000000setup.py my_package/__init__.py my_package.egg-info/PKG-INFO my_package.egg-info/SOURCES.txt my_package.egg-info/dependency_links.txt my_package.egg-info/requires.txt my_package.egg-info/top_level.txt dependency_links.txt000066400000000000000000000000001461771375700362340ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/project_with_setup.egg-inforequires.txt000066400000000000000000000000461461771375700345670ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/project_with_setup.egg-infopendulum>=1.4.4 cachy[msgpack]>=0.2.0 top_level.txt000066400000000000000000000000131461771375700347130ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/project_with_setup.egg-infomy_package poetry-plugin-export-1.8.0/tests/fixtures/project_with_setup/setup.py000066400000000000000000000006401461771375700263450ustar00rootroot00000000000000from __future__ import annotations from setuptools import setup kwargs = dict( name="project-with-setup", license="MIT", version="0.1.2", description="Demo project.", author="Sébastien Eustace", author_email="sebastien@eustace.io", url="https://github.com/demo/demo", packages=["my_package"], install_requires=["pendulum>=1.4.4", "cachy[msgpack]>=0.2.0"], ) setup(**kwargs) poetry-plugin-export-1.8.0/tests/fixtures/sample_project/000077500000000000000000000000001461771375700237215ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/sample_project/README.rst000066400000000000000000000000261461771375700254060ustar00rootroot00000000000000My Package ========== poetry-plugin-export-1.8.0/tests/fixtures/sample_project/pyproject.toml000066400000000000000000000027271461771375700266450ustar00rootroot00000000000000[tool.poetry] name = "sample-project" version = "1.2.3" description = "Some description." authors = [ "Sébastien Eustace " ] license = "MIT" readme = "README.rst" homepage = "https://python-poetry.org" repository = "https://github.com/python-poetry/poetry" documentation = "https://python-poetry.org/docs" keywords = ["packaging", "dependency", "poetry"] classifiers = [ "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules" ] # Requirements [tool.poetry.dependencies] python = "~2.7 || ^3.6" cleo = "^0.6" pendulum = { git = "https://github.com/sdispater/pendulum.git", branch = "2.0" } requests = { version = "^2.18", optional = true, extras=[ "security" ] } pathlib2 = { version = "^2.2", python = "~2.7" } orator = { version = "^0.9", optional = true } # File dependency demo = { path = "../distributions/demo-0.1.0-py2.py3-none-any.whl" } # Dir dependency with setup.py my-package = { path = "../project_with_setup/" } # Dir dependency with pyproject.toml simple-project = { path = "../simple_project/" } # Dependency with markers functools32 = { version = "^3.2.3", markers = "python_version ~= '2.7' and sys_platform == 'win32' or python_version in '3.4 3.5'" } [tool.poetry.extras] db = [ "orator" ] [tool.poetry.dev-dependencies] pytest = "~3.4" [tool.poetry.scripts] my-script = "sample_project:main" [tool.poetry.plugins."blogtool.parsers"] ".rst" = "some_module::SomeClass" poetry-plugin-export-1.8.0/tests/fixtures/simple_project/000077500000000000000000000000001461771375700237315ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/simple_project/README.rst000066400000000000000000000000261461771375700254160ustar00rootroot00000000000000My Package ========== poetry-plugin-export-1.8.0/tests/fixtures/simple_project/dist/000077500000000000000000000000001461771375700246745ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/simple_project/dist/simple-project-1.2.3.tar.gz000066400000000000000000000021221461771375700314140ustar00rootroot00000000000000}]\simple-project-1.2.3.tarYr63ejDQpLi<V94 ˨I@'~G/9TiNl.΋Q"DR6]޲@r.&?'A<\[v޾m}ȣN,Fo8ltNGq|ڽ42QS sin&uLMdnO& <ͪ:4:[e׵&B1(l6i`8-fT5'D!#c*tHA.)@)..NZ9T/pB>$)/3<>`2A[S$zQ Bdt٠E('ٲᔈ4,Ur4;Ҕ˱;ʢbZV*N6"4i8S 8\Ng4#!<8W]0<ķ88gr>'`*ܚiǘ)=' +^O@V:F}#A= kc\n'J_);OR"|eVo?ywS]3h H"UWph%& 1YBJyT(8+z՘O~0<[^UDR/Q^=CAqPkCyv1MH EZϘ;U'US0uqXEkQ- ѫ. 𛁃L* V]SuE-9"_}j-ow Fx'˷;7&BX*rՃ6=z6ܢ8$`'IfrX 8)ժ(')x]q-u髽`Y@ipd<< qN(:<ÃL.-T}x|V7 IHINsZ-YG-=mQok1mCfmxFU8ăD^O㭺iÅ=a iHF(simple_project-1.2.3-py2.py3-none-any.whl000066400000000000000000000024501461771375700337540ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/simple_project/distPK!simple_project/__init__.pyPK!H|n-WY$simple_project-1.2.3.dist-info/WHEEL A н#Z;/" bFF]xzwK;<*mTֻ0*Ri.4Vm0[H, JPK!HCӷ^'simple_project-1.2.3.dist-info/METADATASn0+k`Q6y@ڭaFf+rYrD菕< FܙYbZn!D䅘Bɣc* 1cZڒoU0A$J=D>y(HR0ȖFٱ/>`б^2h48Nz5l!M{/#pSXJS'p__ uiy!&|&NI(0|'캖1;q^_tcP~%Y6ɗUM[P1/F*fchkO;Fu-у p5z :ѰK2/ P75D},K@t"%uv r vהϔjFD +pR>=$,8aQ}@_hHj-W3cw]Ƈ>FWN\}ʗn7X3:<Qyk$ɎscIW0/rH y`PK!simple_project/__init__.pyPK!H|n-WY$:simple_project-1.2.3.dist-info/WHEELPK!HCӷ^'simple_project-1.2.3.dist-info/METADATAPK!H 0<62%simple_project-1.2.3.dist-info/RECORDPKBpoetry-plugin-export-1.8.0/tests/fixtures/simple_project/pyproject.toml000066400000000000000000000014031461771375700266430ustar00rootroot00000000000000[tool.poetry] name = "simple-project" version = "1.2.3" description = "Some description." authors = [ "Sébastien Eustace " ] license = "MIT" readme = "README.rst" homepage = "https://python-poetry.org" repository = "https://github.com/python-poetry/poetry" documentation = "https://python-poetry.org/docs" keywords = ["packaging", "dependency", "poetry"] classifiers = [ "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules" ] # Requirements [tool.poetry.dependencies] python = "~2.7 || ^3.4" [tool.poetry.scripts] foo = "foo:bar" baz = "bar:baz.boom.bim" fox = "fuz.foo:bar.baz" [build-system] requires = ["poetry-core>=1.0.2"] build-backend = "poetry.core.masonry.api" poetry-plugin-export-1.8.0/tests/fixtures/simple_project/simple_project/000077500000000000000000000000001461771375700267505ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/fixtures/simple_project/simple_project/__init__.py000066400000000000000000000000001461771375700310470ustar00rootroot00000000000000poetry-plugin-export-1.8.0/tests/helpers.py000066400000000000000000000061461461771375700210640ustar00rootroot00000000000000from __future__ import annotations import os from contextlib import contextmanager from typing import TYPE_CHECKING from typing import Any from typing import Iterator from poetry.console.application import Application from poetry.factory import Factory from poetry.installation.executor import Executor from poetry.packages import Locker if TYPE_CHECKING: from pathlib import Path from poetry.core.packages.package import Package from poetry.installation.operations.operation import Operation from poetry.poetry import Poetry from tomlkit.toml_document import TOMLDocument class PoetryTestApplication(Application): def __init__(self, poetry: Poetry) -> None: super().__init__() self._poetry = poetry def reset_poetry(self) -> None: poetry = self._poetry assert poetry self._poetry = Factory().create_poetry(poetry.file.path.parent) self._poetry.set_pool(poetry.pool) self._poetry.set_config(poetry.config) self._poetry.set_locker( TestLocker(poetry.locker.lock, self._poetry.local_config) ) class TestLocker(Locker): def __init__(self, lock: Path, local_config: dict[str, Any]) -> None: super().__init__(lock, local_config) self._locked = False self._write = False self._contains_credential = False def write(self, write: bool = True) -> None: self._write = write def is_locked(self) -> bool: return self._locked def locked(self, is_locked: bool = True) -> TestLocker: self._locked = is_locked return self def mock_lock_data(self, data: dict[str, Any]) -> None: self.locked() self._lock_data = data def is_fresh(self) -> bool: return True def _write_lock_data(self, data: TOMLDocument) -> None: if self._write: super()._write_lock_data(data) self._locked = True return self._lock_data = data class TestExecutor(Executor): def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) self._installs: list[Package] = [] self._updates: list[Package] = [] self._uninstalls: list[Package] = [] @property def installations(self) -> list[Package]: return self._installs @property def updates(self) -> list[Package]: return self._updates @property def removals(self) -> list[Package]: return self._uninstalls def _do_execute_operation(self, operation: Operation) -> int: super()._do_execute_operation(operation) if not operation.skipped: getattr(self, f"_{operation.job_type}s").append(operation.package) return 0 def _execute_install(self, operation: Operation) -> int: return 0 def _execute_update(self, operation: Operation) -> int: return 0 def _execute_remove(self, operation: Operation) -> int: return 0 @contextmanager def as_cwd(path: Path) -> Iterator[Path]: old_cwd = os.getcwd() os.chdir(path) try: yield path finally: os.chdir(old_cwd) poetry-plugin-export-1.8.0/tests/markers.py000066400000000000000000000023561461771375700210650ustar00rootroot00000000000000from __future__ import annotations from poetry.core.version.markers import parse_marker MARKER_WIN32 = parse_marker('sys_platform == "win32"') MARKER_WINDOWS = parse_marker('platform_system == "Windows"') MARKER_LINUX = parse_marker('sys_platform == "linux"') MARKER_DARWIN = parse_marker('sys_platform == "darwin"') MARKER_CPYTHON = parse_marker('implementation_name == "cpython"') MARKER_PY27 = parse_marker('python_version >= "2.7" and python_version < "2.8"') MARKER_PY36 = parse_marker('python_version >= "3.6" and python_version < "4.0"') MARKER_PY36_38 = parse_marker('python_version >= "3.6" and python_version < "3.8"') MARKER_PY36_PY362 = parse_marker( 'python_version >= "3.6" and python_full_version < "3.6.2"' ) MARKER_PY362_PY40 = parse_marker( 'python_full_version >= "3.6.2" and python_version < "4.0"' ) MARKER_PY36_ONLY = parse_marker('python_version >= "3.6" and python_version < "3.7"') MARKER_PY37 = parse_marker('python_version >= "3.7" and python_version < "4.0"') MARKER_PY = MARKER_PY27.union(MARKER_PY36) MARKER_PY_WIN32 = MARKER_PY.intersect(MARKER_WIN32) MARKER_PY_WINDOWS = MARKER_PY.intersect(MARKER_WINDOWS) MARKER_PY_LINUX = MARKER_PY.intersect(MARKER_LINUX) MARKER_PY_DARWIN = MARKER_PY.intersect(MARKER_DARWIN) poetry-plugin-export-1.8.0/tests/test_exporter.py000066400000000000000000002662061461771375700223360ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING from typing import Any import pytest from cleo.io.buffered_io import BufferedIO from cleo.io.null_io import NullIO from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.core.version.markers import parse_marker from poetry.factory import Factory from poetry.packages import Locker as BaseLocker from poetry.repositories.legacy_repository import LegacyRepository from poetry.repositories.repository_pool import Priority from poetry_plugin_export.exporter import Exporter from tests.markers import MARKER_CPYTHON from tests.markers import MARKER_DARWIN from tests.markers import MARKER_LINUX from tests.markers import MARKER_PY from tests.markers import MARKER_PY27 from tests.markers import MARKER_PY36 from tests.markers import MARKER_PY36_38 from tests.markers import MARKER_PY36_ONLY from tests.markers import MARKER_PY36_PY362 from tests.markers import MARKER_PY37 from tests.markers import MARKER_PY362_PY40 from tests.markers import MARKER_PY_DARWIN from tests.markers import MARKER_PY_LINUX from tests.markers import MARKER_PY_WIN32 from tests.markers import MARKER_PY_WINDOWS from tests.markers import MARKER_WIN32 from tests.markers import MARKER_WINDOWS if TYPE_CHECKING: from collections.abc import Collection from pathlib import Path from packaging.utils import NormalizedName from poetry.poetry import Poetry from tests.conftest import Config class Locker(BaseLocker): def __init__(self, fixture_root: Path) -> None: super().__init__(fixture_root / "poetry.lock", {}) self._locked = True def locked(self, is_locked: bool = True) -> Locker: self._locked = is_locked return self def mock_lock_data(self, data: dict[str, Any]) -> None: self._lock_data = data def is_locked(self) -> bool: return self._locked def is_fresh(self) -> bool: return True def _get_content_hash(self) -> str: return "123456789" @pytest.fixture def locker(fixture_root: Path) -> Locker: return Locker(fixture_root) @pytest.fixture def poetry(fixture_root: Path, locker: Locker) -> Poetry: p = Factory().create_poetry(fixture_root / "sample_project") p._locker = locker return p def set_package_requires( poetry: Poetry, skip: set[str] | None = None, dev: set[str] | None = None, markers: dict[str, str] | None = None, ) -> None: skip = skip or set() dev = dev or set() packages = poetry.locker.locked_repository().packages package = poetry.package.with_dependency_groups([], only=True) for pkg in packages: if pkg.name not in skip: dep = pkg.to_dependency() if pkg.name in dev: dep._groups = frozenset(["dev"]) if markers and pkg.name in markers: dep._marker = parse_marker(markers[pkg.name]) package.add_dependency(dep) poetry._package = package def test_exporter_can_export_requirements_txt_with_standard_packages( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} foo==1.2.3 ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_standard_packages_and_markers( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, { "name": "baz", "version": "7.8.9", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": [], "baz": []}, }, } ) markers = { "foo": "python_version < '3.7'", "bar": "extra =='foo'", "baz": "sys_platform == 'win32'", } set_package_requires(poetry, markers=markers) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} baz==7.8.9 ; {MARKER_PY_WIN32} foo==1.2.3 ; {MARKER_PY27.union(MARKER_PY36_ONLY)} """ assert content == expected def test_exporter_can_export_requirements_txt_poetry( tmp_path: Path, poetry: Poetry ) -> None: """Regression test for #3254""" poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "poetry", "version": "1.1.4", "optional": False, "python-versions": "*", "dependencies": {"keyring": "*"}, }, { "name": "junit-xml", "version": "1.9", "optional": False, "python-versions": "*", "dependencies": {"six": "*"}, }, { "name": "keyring", "version": "21.8.0", "optional": False, "python-versions": "*", "dependencies": { "SecretStorage": { "version": "*", "markers": "sys_platform == 'linux'", } }, }, { "name": "secretstorage", "version": "3.3.0", "optional": False, "python-versions": "*", "dependencies": {"cryptography": "*"}, }, { "name": "cryptography", "version": "3.2", "optional": False, "python-versions": "*", "dependencies": {"six": "*"}, }, { "name": "six", "version": "1.15.0", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "poetry": [], "keyring": [], "secretstorage": [], "cryptography": [], "six": [], "junit-xml": [], }, }, } ) set_package_requires( poetry, skip={"keyring", "secretstorage", "cryptography", "six"} ) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() # The dependency graph: # junit-xml 1.9 Creates JUnit XML test result documents that can be read by tools # └── six * such as Jenkins # poetry 1.1.4 Python dependency management and packaging made easy. # ├── keyring >=21.2.0,<22.0.0 # │ ├── importlib-metadata >=1 # │ │ └── zipp >=0.5 # │ ├── jeepney >=0.4.2 # │ ├── pywin32-ctypes <0.1.0 || >0.1.0,<0.1.1 || >0.1.1 # │ └── secretstorage >=3.2 -- On linux only # │ ├── cryptography >=2.0 # │ │ └── six >=1.4.1 # │ └── jeepney >=0.6 (circular dependency aborted here) expected = { "poetry": Dependency.create_from_pep_508(f"poetry==1.1.4; {MARKER_PY}"), "junit-xml": Dependency.create_from_pep_508(f"junit-xml==1.9 ; {MARKER_PY}"), "keyring": Dependency.create_from_pep_508(f"keyring==21.8.0 ; {MARKER_PY}"), "secretstorage": Dependency.create_from_pep_508( f"secretstorage==3.3.0 ; {MARKER_PY_LINUX}" ), "cryptography": Dependency.create_from_pep_508( f"cryptography==3.2 ; {MARKER_PY_LINUX}" ), "six": Dependency.create_from_pep_508( f"six==1.15.0 ; {MARKER_PY.union(MARKER_PY_LINUX)}" ), } for line in content.strip().split("\n"): dependency = Dependency.create_from_pep_508(line) assert dependency.name in expected expected_dependency = expected.pop(dependency.name) assert dependency == expected_dependency assert dependency.marker == expected_dependency.marker def test_exporter_can_export_requirements_txt_pyinstaller( tmp_path: Path, poetry: Poetry ) -> None: """Regression test for #3254""" poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "pyinstaller", "version": "4.0", "optional": False, "python-versions": "*", "dependencies": { "altgraph": "*", "macholib": { "version": "*", "markers": "sys_platform == 'darwin'", }, }, }, { "name": "altgraph", "version": "0.17", "optional": False, "python-versions": "*", }, { "name": "macholib", "version": "1.8", "optional": False, "python-versions": "*", "dependencies": {"altgraph": ">=0.15"}, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"pyinstaller": [], "altgraph": [], "macholib": []}, }, } ) set_package_requires(poetry, skip={"altgraph", "macholib"}) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() # Rationale for the results: # * PyInstaller has an explicit dependency on altgraph, so it must always be # installed. # * PyInstaller requires macholib on Darwin, which in turn requires altgraph. # The dependency graph: # pyinstaller 4.0 PyInstaller bundles a Python application and all its # ├── altgraph * dependencies into a single package. # ├── macholib >=1.8 -- only on Darwin # │ └── altgraph >=0.15 expected = { "pyinstaller": Dependency.create_from_pep_508( f"pyinstaller==4.0 ; {MARKER_PY}" ), "altgraph": Dependency.create_from_pep_508( f"altgraph==0.17 ; {MARKER_PY.union(MARKER_PY_DARWIN)}" ), "macholib": Dependency.create_from_pep_508( f"macholib==1.8 ; {MARKER_PY_DARWIN}" ), } for line in content.strip().split("\n"): dependency = Dependency.create_from_pep_508(line) assert dependency.name in expected expected_dependency = expected.pop(dependency.name) assert dependency == expected_dependency assert dependency.marker == expected_dependency.marker def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "a", "version": "1.2.3", "optional": False, "python-versions": "*", "dependencies": { "b": { "version": ">=0.0.0", "markers": "platform_system == 'Windows'", }, "c": { "version": ">=0.0.0", "markers": "sys_platform == 'win32'", }, }, }, { "name": "b", "version": "4.5.6", "optional": False, "python-versions": "*", "dependencies": {"d": ">=0.0.0"}, }, { "name": "c", "version": "7.8.9", "optional": False, "python-versions": "*", "dependencies": {"d": ">=0.0.0"}, }, { "name": "d", "version": "0.0.1", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"a": [], "b": [], "c": [], "d": []}, }, } ) set_package_requires( poetry, skip={"b", "c", "d"}, markers={"a": "python_version < '3.7'"} ) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() marker_py = MARKER_PY27.union(MARKER_PY36_ONLY) marker_py_win32 = marker_py.intersect(MARKER_WIN32) marker_py_windows = marker_py.intersect(MARKER_WINDOWS) expected = { "a": Dependency.create_from_pep_508(f"a==1.2.3 ; {marker_py}"), "b": Dependency.create_from_pep_508(f"b==4.5.6 ; {marker_py_windows}"), "c": Dependency.create_from_pep_508(f"c==7.8.9 ; {marker_py_win32}"), "d": Dependency.create_from_pep_508( f"d==0.0.1 ; {marker_py_windows.union(marker_py_win32)}" ), } for line in content.strip().split("\n"): dependency = Dependency.create_from_pep_508(line) assert dependency.name in expected expected_dependency = expected.pop(dependency.name) assert dependency == expected_dependency assert dependency.marker == expected_dependency.marker assert expected == {} @pytest.mark.parametrize( ["dev", "lines"], [ ( False, [f"a==1.2.3 ; {MARKER_PY27.union(MARKER_PY36_38)}"], ), ( True, [ f"a==1.2.3 ; {MARKER_PY27.union(MARKER_PY36_38).union(MARKER_PY36)}", f"b==4.5.6 ; {MARKER_PY}", ], ), ], ) def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_any( tmp_path: Path, poetry: Poetry, dev: bool, lines: list[str] ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "a", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "b", "version": "4.5.6", "optional": False, "python-versions": "*", "dependencies": {"a": ">=1.2.3"}, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"a": [], "b": []}, }, } ) root = poetry.package.with_dependency_groups([], only=True) root.add_dependency( Factory.create_dependency( name="a", constraint={"version": "^1.2.3", "python": "<3.8"} ) ) root.add_dependency( Factory.create_dependency( name="b", constraint={"version": "^4.5.6"}, groups=["dev"] ) ) poetry._package = root exporter = Exporter(poetry, NullIO()) if dev: exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() assert content.strip() == "\n".join(lines) def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_can_export_requirements_txt_with_standard_packages_and_sorted_hashes( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [ {"name": "foo1.whl", "hash": "67890"}, {"name": "foo2.whl", "hash": "12345"}, ], "bar": [ {"name": "bar1.whl", "hash": "67890"}, {"name": "bar2.whl", "hash": "12345"}, ], }, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:12345 \\ --hash=sha256:67890 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 \\ --hash=sha256:67890 """ assert content == expected def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes_disabled( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.with_hashes(False) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} foo==1.2.3 ; {MARKER_PY} """ assert content == expected def test_exporter_exports_requirements_txt_without_dev_packages_by_default( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_exports_requirements_txt_with_dev_packages_if_opted_in( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_exports_requirements_txt_without_groups_if_set_explicitly( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() assert content == "\n" def test_exporter_exports_requirements_txt_without_optional_packages( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": True, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected @pytest.mark.parametrize( ["extras", "lines"], [ ( ["feature-bar"], [ f"bar==4.5.6 ; {MARKER_PY}", f"foo==1.2.3 ; {MARKER_PY}", f"spam==0.1.0 ; {MARKER_PY}", ], ), ], ) def test_exporter_exports_requirements_txt_with_optional_packages( tmp_path: Path, poetry: Poetry, extras: Collection[NormalizedName], lines: list[str], ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": True, "python-versions": "*", "dependencies": {"spam": ">=0.1"}, }, { "name": "spam", "version": "0.1.0", "optional": True, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], "spam": [{"name": "spam.whl", "hash": "abcde"}], }, }, "extras": {"feature_bar": ["bar"]}, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.with_hashes(False) exporter.with_extras(extras) exporter.export( "requirements.txt", tmp_path, "requirements.txt", ) with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = "\n".join(lines) assert content.strip() == expected def test_exporter_can_export_requirements_txt_with_git_packages( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "git", "url": "https://github.com/foo/foo.git", "reference": "123456", "resolved_reference": "abcdef", }, } ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo @ git+https://github.com/foo/foo.git@abcdef ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_nested_packages( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "git", "url": "https://github.com/foo/foo.git", "reference": "123456", "resolved_reference": "abcdef", }, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "dependencies": { "foo": { "git": "https://github.com/foo/foo.git", "rev": "123456", } }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": []}, }, } ) set_package_requires(poetry, skip={"foo"}) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} foo @ git+https://github.com/foo/foo.git@abcdef ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_nested_packages_cyclic( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "dependencies": {"bar": {"version": "4.5.6"}}, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "dependencies": {"baz": {"version": "7.8.9"}}, }, { "name": "baz", "version": "7.8.9", "optional": False, "python-versions": "*", "dependencies": {"foo": {"version": "1.2.3"}}, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": [], "baz": []}, }, } ) set_package_requires(poetry, skip={"bar", "baz"}) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} baz==7.8.9 ; {MARKER_PY} foo==1.2.3 ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_circular_root_dependency( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "dependencies": {poetry.package.pretty_name: {"version": "1.2.3"}}, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo==1.2.3 ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_nested_packages_and_multiple_markers( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "dependencies": { "bar": [ { "version": ">=1.2.3,<7.8.10", "markers": 'platform_system != "Windows"', }, { "version": ">=4.5.6,<7.8.10", "markers": 'platform_system == "Windows"', }, ] }, }, { "name": "bar", "version": "7.8.9", "optional": True, "python-versions": "*", "dependencies": { "baz": { "version": "!=10.11.12", "markers": 'platform_system == "Windows"', } }, }, { "name": "baz", "version": "10.11.13", "optional": True, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": [], "baz": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.with_hashes(False) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() marker_py_not_windows = MARKER_PY.intersect( parse_marker('platform_system != "Windows"') ) expected = f"""\ bar==7.8.9 ; {marker_py_not_windows.union(MARKER_PY_WINDOWS)} baz==10.11.13 ; {MARKER_PY_WINDOWS} foo==1.2.3 ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_git_packages_and_markers( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "git", "url": "https://github.com/foo/foo.git", "reference": "123456", "resolved_reference": "abcdef", }, } ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry, markers={"foo": "python_version < '3.7'"}) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo @ git+https://github.com/foo/foo.git@abcdef ; {MARKER_PY27.union(MARKER_PY36_ONLY)} """ assert content == expected def test_exporter_can_export_requirements_txt_with_directory_packages( tmp_path: Path, poetry: Poetry, fixture_root_uri: str ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "directory", "url": "sample_project", "reference": "", }, } ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo @ {fixture_root_uri}/sample_project ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_directory_packages_editable( tmp_path: Path, poetry: Poetry, fixture_root_uri: str ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "develop": True, "source": { "type": "directory", "url": "sample_project", "reference": "", }, } ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ -e {fixture_root_uri}/sample_project ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_nested_directory_packages( tmp_path: Path, poetry: Poetry, fixture_root_uri: str ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "directory", "url": "sample_project", "reference": "", }, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "directory", "url": "sample_project/../project_with_nested_local/bar", "reference": "", }, }, { "name": "baz", "version": "7.8.9", "optional": False, "python-versions": "*", "source": { "type": "directory", "url": "sample_project/../project_with_nested_local/bar/..", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": [], "baz": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar @ {fixture_root_uri}/project_with_nested_local/bar ; {MARKER_PY} baz @ {fixture_root_uri}/project_with_nested_local ; {MARKER_PY} foo @ {fixture_root_uri}/sample_project ; {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_directory_packages_and_markers( tmp_path: Path, poetry: Poetry, fixture_root_uri: str ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "directory", "url": "sample_project", "reference": "", }, } ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry, markers={"foo": "python_version < '3.7'"}) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo @ {fixture_root_uri}/sample_project ;\ {MARKER_PY27.union(MARKER_PY36_ONLY)} """ assert content == expected def test_exporter_can_export_requirements_txt_with_file_packages( tmp_path: Path, poetry: Poetry, fixture_root_uri: str ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "file", "url": "distributions/demo-0.1.0.tar.gz", "reference": "", }, } ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo @ {fixture_root_uri}/distributions/demo-0.1.0.tar.gz ;\ {MARKER_PY} """ assert content == expected def test_exporter_can_export_requirements_txt_with_file_packages_and_markers( tmp_path: Path, poetry: Poetry, fixture_root_uri: str ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "file", "url": "distributions/demo-0.1.0.tar.gz", "reference": "", }, } ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": []}, }, } ) set_package_requires(poetry, markers={"foo": "python_version < '3.7'"}) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() uri = f"{fixture_root_uri}/distributions/demo-0.1.0.tar.gz" expected = f"""\ foo @ {uri} ; {MARKER_PY27.union(MARKER_PY36_ONLY)} """ assert content == expected def test_exporter_exports_requirements_txt_with_legacy_packages( tmp_path: Path, poetry: Poetry ) -> None: poetry.pool.add_repository( LegacyRepository( "custom", "https://example.com/simple", ) ) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://example.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ --extra-index-url https://example.com/simple bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_exports_requirements_txt_with_url_false( tmp_path: Path, poetry: Poetry ) -> None: poetry.pool.add_repository( LegacyRepository( "custom", "https://example.com/simple", ) ) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://example.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.with_urls(False) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_exports_requirements_txt_with_legacy_packages_trusted_host( tmp_path: Path, poetry: Poetry ) -> None: poetry.pool.add_repository( LegacyRepository( "custom", "http://example.com/simple", ) ) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "http://example.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ --trusted-host example.com --extra-index-url http://example.com/simple bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 """ assert content == expected @pytest.mark.parametrize( ["dev", "expected"], [ ( True, [ f"bar==1.2.2 ; {MARKER_PY}", f"baz==1.2.3 ; {MARKER_PY}", f"foo==1.2.1 ; {MARKER_PY}", ], ), ( False, [ f"bar==1.2.2 ; {MARKER_PY}", f"foo==1.2.1 ; {MARKER_PY}", ], ), ], ) def test_exporter_exports_requirements_txt_with_dev_extras( tmp_path: Path, poetry: Poetry, dev: bool, expected: list[str] ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.1", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "1.2.2", "optional": False, "python-versions": "*", "dependencies": { "baz": { "version": ">=0.1.0", "optional": True, "markers": "extra == 'baz'", } }, "extras": {"baz": ["baz (>=0.1.0)"]}, }, { "name": "baz", "version": "1.2.3", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": [], "baz": []}, }, } ) set_package_requires(poetry, dev={"baz"}) exporter = Exporter(poetry, NullIO()) if dev: exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() assert content == "\n".join(expected) + "\n" def test_exporter_exports_requirements_txt_with_legacy_packages_and_duplicate_sources( tmp_path: Path, poetry: Poetry ) -> None: poetry.pool.add_repository( LegacyRepository( "custom-example", "https://example.com/simple", ) ) poetry.pool.add_repository( LegacyRepository( "custom-foobaz", "https://foobaz.com/simple", ) ) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://example.com/simple", "reference": "", }, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://example.com/simple", "reference": "", }, }, { "name": "baz", "version": "7.8.9", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://foobaz.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], "baz": [{"name": "baz.whl", "hash": "24680"}], }, }, } ) set_package_requires(poetry, dev={"bar", "baz"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ --extra-index-url https://example.com/simple --extra-index-url https://foobaz.com/simple bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 baz==7.8.9 ; {MARKER_PY} \\ --hash=sha256:24680 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_exports_requirements_txt_with_two_primary_sources( tmp_path: Path, poetry: Poetry ) -> None: poetry.pool.remove_repository("PyPI") poetry.config.merge( { "repositories": { "custom-a": {"url": "https://a.example.com/simple"}, "custom-b": {"url": "https://b.example.com/simple"}, }, "http-basic": { "custom-a": {"username": "foo", "password": "bar"}, "custom-b": {"username": "baz", "password": "qux"}, }, } ) poetry.pool.add_repository( LegacyRepository( "custom-b", "https://b.example.com/simple", config=poetry.config, ), ) poetry.pool.add_repository( LegacyRepository( "custom-a", "https://a.example.com/simple", config=poetry.config, ), ) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://a.example.com/simple", "reference": "", }, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://b.example.com/simple", "reference": "", }, }, { "name": "baz", "version": "7.8.9", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://b.example.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], "baz": [{"name": "baz.whl", "hash": "24680"}], }, }, } ) set_package_requires(poetry, dev={"bar", "baz"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.with_credentials() exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ --index-url https://baz:qux@b.example.com/simple --extra-index-url https://foo:bar@a.example.com/simple bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 baz==7.8.9 ; {MARKER_PY} \\ --hash=sha256:24680 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_exports_requirements_txt_with_legacy_packages_and_credentials( tmp_path: Path, poetry: Poetry, config: Config ) -> None: poetry.config.merge( { "repositories": {"custom": {"url": "https://example.com/simple"}}, "http-basic": {"custom": {"username": "foo", "password": "bar"}}, } ) poetry.pool.add_repository( LegacyRepository("custom", "https://example.com/simple", config=poetry.config) ) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://example.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.with_credentials() exporter.export( "requirements.txt", tmp_path, "requirements.txt", ) with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ --extra-index-url https://foo:bar@example.com/simple bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected def test_exporter_exports_requirements_txt_to_standard_output( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) io = BufferedIO() exporter.export("requirements.txt", tmp_path, io) expected = f"""\ bar==4.5.6 ; {MARKER_PY} foo==1.2.3 ; {MARKER_PY} """ assert io.fetch_output() == expected def test_exporter_doesnt_confuse_repeated_packages( tmp_path: Path, poetry: Poetry ) -> None: # Testcase derived from . poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "celery", "version": "5.1.2", "optional": False, "python-versions": "<3.7", "dependencies": { "click": ">=7.0,<8.0", "click-didyoumean": ">=0.0.3", "click-plugins": ">=1.1.1", }, }, { "name": "celery", "version": "5.2.3", "optional": False, "python-versions": ">=3.7", "dependencies": { "click": ">=8.0.3,<9.0", "click-didyoumean": ">=0.0.3", "click-plugins": ">=1.1.1", }, }, { "name": "click", "version": "7.1.2", "optional": False, "python-versions": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*", }, { "name": "click", "version": "8.0.3", "optional": False, "python-versions": ">=3.6", "dependencies": {}, }, { "name": "click-didyoumean", "version": "0.0.3", "optional": False, "python-versions": "*", "dependencies": {"click": "*"}, }, { "name": "click-didyoumean", "version": "0.3.0", "optional": False, "python-versions": ">=3.6.2,<4.0.0", "dependencies": {"click": ">=7"}, }, { "name": "click-plugins", "version": "1.1.1", "optional": False, "python-versions": "*", "dependencies": {"click": ">=4.0"}, }, ], "metadata": { "lock-version": "1.1", "python-versions": "^3.6", "content-hash": ( "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6" ), "files": { "celery": [], "click-didyoumean": [], "click-plugins": [], "click": [], }, }, } ) root = poetry.package.with_dependency_groups([], only=True) root.python_versions = "^3.6" root.add_dependency( Factory.create_dependency( name="celery", constraint={"version": "5.1.2", "python": "<3.7"} ) ) root.add_dependency( Factory.create_dependency( name="celery", constraint={"version": "5.2.3", "python": ">=3.7"} ) ) poetry._package = root exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) io = BufferedIO() exporter.export("requirements.txt", tmp_path, io) expected = f"""\ celery==5.1.2 ; {MARKER_PY36_ONLY} celery==5.2.3 ; {MARKER_PY37} click-didyoumean==0.0.3 ; {MARKER_PY36_PY362} click-didyoumean==0.3.0 ; {MARKER_PY362_PY40} click-plugins==1.1.1 ; {MARKER_PY36} click==7.1.2 ; {MARKER_PY36_ONLY} click==8.0.3 ; {MARKER_PY37} """ assert io.fetch_output() == expected def test_exporter_handles_extras_next_to_non_extras( tmp_path: Path, poetry: Poetry ) -> None: # Testcase similar to the solver testcase added at #5305. poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "localstack", "python-versions": "*", "version": "1.0.0", "optional": False, "dependencies": { "localstack-ext": [ {"version": ">=1.0.0"}, { "version": ">=1.0.0", "extras": ["bar"], "markers": 'extra == "foo"', }, ] }, "extras": {"foo": ["localstack-ext[bar] (>=1.0.0)"]}, }, { "name": "localstack-ext", "python-versions": "*", "version": "1.0.0", "optional": False, "dependencies": { "something": "*", "something-else": { "version": ">=1.0.0", "markers": 'extra == "bar"', }, "another-thing": { "version": ">=1.0.0", "markers": 'extra == "baz"', }, }, "extras": { "bar": ["something-else (>=1.0.0)"], "baz": ["another-thing (>=1.0.0)"], }, }, { "name": "something", "python-versions": "*", "version": "1.0.0", "optional": False, "dependencies": {}, }, { "name": "something-else", "python-versions": "*", "version": "1.0.0", "optional": False, "dependencies": {}, }, { "name": "another-thing", "python-versions": "*", "version": "1.0.0", "optional": False, "dependencies": {}, }, ], "metadata": { "lock-version": "1.1", "python-versions": "^3.6", "content-hash": ( "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6" ), "files": { "localstack": [], "localstack-ext": [], "something": [], "something-else": [], "another-thing": [], }, }, } ) root = poetry.package.with_dependency_groups([], only=True) root.python_versions = "^3.6" root.add_dependency( Factory.create_dependency( name="localstack", constraint={"version": "^1.0.0", "extras": ["foo"]} ) ) poetry._package = root exporter = Exporter(poetry, NullIO()) io = BufferedIO() exporter.export("requirements.txt", tmp_path, io) expected = f"""\ localstack-ext==1.0.0 ; {MARKER_PY36} localstack-ext[bar]==1.0.0 ; {MARKER_PY36} localstack[foo]==1.0.0 ; {MARKER_PY36} something-else==1.0.0 ; {MARKER_PY36} something==1.0.0 ; {MARKER_PY36} """ assert io.fetch_output() == expected def test_exporter_handles_overlapping_python_versions( tmp_path: Path, poetry: Poetry ) -> None: # Testcase derived from # https://github.com/python-poetry/poetry-plugin-export/issues/32. poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "ipython", "python-versions": ">=3.6", "version": "7.16.3", "optional": False, "dependencies": {}, }, { "name": "ipython", "python-versions": ">=3.7", "version": "7.34.0", "optional": False, "dependencies": {}, }, { "name": "slash", "python-versions": ">=3.6.*", "version": "1.13.0", "optional": False, "dependencies": { "ipython": [ { "version": "*", "markers": ( 'python_version >= "3.6" and implementation_name !=' ' "pypy"' ), }, { "version": "<7.17.0", "markers": ( 'python_version < "3.6" and implementation_name !=' ' "pypy"' ), }, ], }, }, ], "metadata": { "lock-version": "1.1", "python-versions": "^3.6", "content-hash": ( "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6" ), "files": { "ipython": [], "slash": [], }, }, } ) root = poetry.package.with_dependency_groups([], only=True) root.python_versions = "^3.6" root.add_dependency( Factory.create_dependency( name="ipython", constraint={"version": "*", "python": "~3.6"}, ) ) root.add_dependency( Factory.create_dependency( name="ipython", constraint={"version": "^7.17", "python": "^3.7"}, ) ) root.add_dependency( Factory.create_dependency( name="slash", constraint={ "version": "^1.12", "markers": "implementation_name == 'cpython'", }, ) ) poetry._package = root exporter = Exporter(poetry, NullIO()) io = BufferedIO() exporter.export("requirements.txt", tmp_path, io) expected = f"""\ ipython==7.16.3 ; {MARKER_PY36_ONLY} ipython==7.34.0 ; {MARKER_PY37} slash==1.13.0 ; {MARKER_PY36} and {MARKER_CPYTHON} """ assert io.fetch_output() == expected @pytest.mark.parametrize( ["with_extras", "expected"], [ ( True, [f"foo[test]==1.0.0 ; {MARKER_PY36}", f"pytest==6.24.0 ; {MARKER_PY36}"], ), ( False, [f"foo==1.0.0 ; {MARKER_PY36}"], ), ], ) def test_exporter_omits_unwanted_extras( tmp_path: Path, poetry: Poetry, with_extras: bool, expected: list[str] ) -> None: # Testcase derived from # https://github.com/python-poetry/poetry/issues/5779 poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "python-versions": ">=3.6", "version": "1.0.0", "optional": False, "dependencies": {"pytest": {"version": "^6.2.4", "optional": True}}, "extras": {"test": ["pytest (>=6.2.4,<7.0.0)"]}, }, { "name": "pytest", "python-versions": ">=3.6", "version": "6.24.0", "optional": False, "dependencies": {}, }, ], "metadata": { "lock-version": "1.1", "python-versions": "^3.6", "content-hash": ( "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6" ), "files": { "foo": [], "pytest": [], }, }, } ) root = poetry.package.with_dependency_groups([], only=True) root.python_versions = "^3.6" root.add_dependency( Factory.create_dependency( name="foo", constraint={"version": "*"}, ) ) root.add_dependency( Factory.create_dependency( name="foo", constraint={"version": "*", "extras": ["test"]}, groups=["with-extras"], ) ) poetry._package = root io = BufferedIO() exporter = Exporter(poetry, NullIO()) if with_extras: exporter.only_groups(["with-extras"]) exporter.export("requirements.txt", tmp_path, io) assert io.fetch_output() == "\n".join(expected) + "\n" @pytest.mark.parametrize( ["fmt", "expected"], [ ( "constraints.txt", [ f"bar==4.5.6 ; {MARKER_PY}", f"baz==7.8.9 ; {MARKER_PY}", f"foo==1.2.3 ; {MARKER_PY}", ], ), ( "requirements.txt", [ f"bar==4.5.6 ; {MARKER_PY}", f"bar[baz]==4.5.6 ; {MARKER_PY}", f"baz==7.8.9 ; {MARKER_PY}", f"foo==1.2.3 ; {MARKER_PY}", ], ), ], ) def test_exporter_omits_and_includes_extras_for_txt_formats( tmp_path: Path, poetry: Poetry, fmt: str, expected: list[str] ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "dependencies": { "bar": { "extras": ["baz"], "version": ">=0.1.0", } }, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "dependencies": { "baz": { "version": ">=0.1.0", "optional": True, "markers": "extra == 'baz'", } }, "extras": {"baz": ["baz (>=0.1.0)"]}, }, { "name": "baz", "version": "7.8.9", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": [], "baz": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export(fmt, tmp_path, "exported.txt") with (tmp_path / "exported.txt").open(encoding="utf-8") as f: content = f.read() assert content == "\n".join(expected) + "\n" def test_exporter_prints_warning_for_constraints_txt_with_editable_packages( tmp_path: Path, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "git", "url": "https://github.com/foo/foo.git", "reference": "123456", }, "develop": True, }, { "name": "bar", "version": "7.8.9", "optional": False, "python-versions": "*", }, { "name": "baz", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "directory", "url": "sample_project", "reference": "", }, "develop": True, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": [], "baz": []}, }, } ) set_package_requires(poetry) io = BufferedIO() exporter = Exporter(poetry, io) exporter.export("constraints.txt", tmp_path, "constraints.txt") expected_error_out = ( "Warning: foo is locked in develop (editable) mode, which is " "incompatible with the constraints.txt format.\n" "Warning: baz is locked in develop (editable) mode, which is " "incompatible with the constraints.txt format.\n" ) assert io.fetch_error() == expected_error_out with (tmp_path / "constraints.txt").open(encoding="utf-8") as f: content = f.read() assert content == f"bar==7.8.9 ; {MARKER_PY}\n" def test_exporter_respects_package_sources(tmp_path: Path, poetry: Poetry) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "python-versions": ">=3.6", "version": "1.0.0", "optional": False, "dependencies": {}, "source": { "type": "url", "url": "https://example.com/foo-darwin.whl", }, }, { "name": "foo", "python-versions": ">=3.6", "version": "1.0.0", "optional": False, "dependencies": {}, "source": { "type": "url", "url": "https://example.com/foo-linux.whl", }, }, ], "metadata": { "lock-version": "1.1", "python-versions": "^3.6", "content-hash": ( "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6" ), "files": { "foo": [], }, }, } ) root = poetry.package.with_dependency_groups([], only=True) root.python_versions = "^3.6" root.add_dependency( Factory.create_dependency( name="foo", constraint={ "url": "https://example.com/foo-linux.whl", "platform": "linux", }, ) ) root.add_dependency( Factory.create_dependency( name="foo", constraint={ "url": "https://example.com/foo-darwin.whl", "platform": "darwin", }, ) ) poetry._package = root io = BufferedIO() exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, io) expected = f"""\ foo @ https://example.com/foo-darwin.whl ; {MARKER_PY36} and {MARKER_DARWIN} foo @ https://example.com/foo-linux.whl ; {MARKER_PY36} and {MARKER_LINUX} """ assert io.fetch_output() == expected def test_exporter_tolerates_non_existent_extra(tmp_path: Path, poetry: Poetry) -> None: # foo actually has a 'bar' extra, but pyproject.toml mistakenly references a 'baz' # extra. poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "dependencies": { "bar": { "version": ">=0.1.0", "optional": True, "markers": "extra == 'bar'", } }, "extras": {"bar": ["bar (>=0.1.0)"]}, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": []}, }, } ) root = poetry.package.with_dependency_groups([], only=True) root.add_dependency( Factory.create_dependency( name="foo", constraint={"version": "^1.2", "extras": ["baz"]} ) ) poetry._package = root exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ foo[baz]==1.2.3 ; {MARKER_PY27} or {MARKER_PY36} """ assert content == expected def test_exporter_exports_extra_index_url_and_trusted_host( tmp_path: Path, poetry: Poetry ) -> None: poetry.pool.add_repository( LegacyRepository( "custom", "http://example.com/simple", ), priority=Priority.EXPLICIT, ) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "dependencies": {"bar": "*"}, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "http://example.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": {"foo": [], "bar": []}, }, } ) set_package_requires(poetry) exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected = f"""\ --trusted-host example.com --extra-index-url http://example.com/simple bar==4.5.6 ; {MARKER_PY} foo==1.2.3 ; {MARKER_PY} """ assert content == expected def test_exporter_not_confused_by_extras_in_sub_dependencies( tmp_path: Path, poetry: Poetry ) -> None: # Testcase derived from # https://github.com/python-poetry/poetry-plugin-export/issues/208 poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "typer", "python-versions": ">=3.6", "version": "0.9.0", "optional": False, "files": [], "dependencies": { "click": ">=7.1.1,<9.0.0", "colorama": { "version": ">=0.4.3,<0.5.0", "optional": True, "markers": 'extra == "all"', }, }, "extras": {"all": ["colorama (>=0.4.3,<0.5.0)"]}, }, { "name": "click", "python-versions": ">=3.7", "version": "8.1.3", "optional": False, "files": [], "dependencies": { "colorama": { "version": "*", "markers": 'platform_system == "Windows"', } }, }, { "name": "colorama", "python-versions": ">=3.7", "version": "0.4.6", "optional": False, "files": [], }, ], "metadata": { "lock-version": "2.0", "python-versions": "^3.11", "content-hash": ( "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6" ), }, } ) root = poetry.package.with_dependency_groups([], only=True) root.python_versions = "^3.11" root.add_dependency( Factory.create_dependency( name="typer", constraint={"version": "^0.9.0", "extras": ["all"]}, ) ) poetry._package = root io = BufferedIO() exporter = Exporter(poetry, NullIO()) exporter.export("requirements.txt", tmp_path, io) expected = """\ click==8.1.3 ; python_version >= "3.11" and python_version < "4.0" colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" typer[all]==0.9.0 ; python_version >= "3.11" and python_version < "4.0" """ assert io.fetch_output() == expected @pytest.mark.parametrize( ("priorities", "expected"), [ ([("custom-a", Priority.PRIMARY), ("custom-b", Priority.PRIMARY)], ("a", "b")), ([("custom-b", Priority.PRIMARY), ("custom-a", Priority.PRIMARY)], ("b", "a")), ( [("custom-b", Priority.SUPPLEMENTAL), ("custom-a", Priority.PRIMARY)], ("a", "b"), ), ([("custom-b", Priority.EXPLICIT), ("custom-a", Priority.PRIMARY)], ("a", "b")), ( [ ("PyPI", Priority.PRIMARY), ("custom-a", Priority.PRIMARY), ("custom-b", Priority.PRIMARY), ], ("", "a", "b"), ), ( [ ("PyPI", Priority.EXPLICIT), ("custom-a", Priority.PRIMARY), ("custom-b", Priority.PRIMARY), ], ("", "a", "b"), ), ( [ ("custom-a", Priority.PRIMARY), ("custom-b", Priority.PRIMARY), ("PyPI", Priority.SUPPLEMENTAL), ], ("", "a", "b"), ), ], ) def test_exporter_index_urls( tmp_path: Path, poetry: Poetry, priorities: list[tuple[str, Priority]], expected: tuple[str, ...], ) -> None: pypi = poetry.pool.repository("PyPI") poetry.pool.remove_repository("PyPI") for name, prio in priorities: if name.lower() == "pypi": repo = pypi else: repo = LegacyRepository(name, f"https://{name[-1]}.example.com/simple") poetry.pool.add_repository(repo, priority=prio) poetry.locker.mock_lock_data( # type: ignore[attr-defined] { "package": [ { "name": "foo", "version": "1.2.3", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://a.example.com/simple", "reference": "", }, }, { "name": "bar", "version": "4.5.6", "optional": False, "python-versions": "*", "source": { "type": "legacy", "url": "https://b.example.com/simple", "reference": "", }, }, ], "metadata": { "python-versions": "*", "content-hash": "123456789", "files": { "foo": [{"name": "foo.whl", "hash": "12345"}], "bar": [{"name": "bar.whl", "hash": "67890"}], }, }, } ) set_package_requires(poetry, dev={"bar"}) exporter = Exporter(poetry, NullIO()) exporter.only_groups([MAIN_GROUP, "dev"]) exporter.export("requirements.txt", tmp_path, "requirements.txt") with (tmp_path / "requirements.txt").open(encoding="utf-8") as f: content = f.read() expected_urls = [ f"--extra-index-url https://{name[-1]}.example.com/simple" for name in expected[1:] ] if expected[0]: expected_urls = [ f"--index-url https://{expected[0]}.example.com/simple", *expected_urls, ] url_string = "\n".join(expected_urls) expected_content = f"""\ {url_string} bar==4.5.6 ; {MARKER_PY} \\ --hash=sha256:67890 foo==1.2.3 ; {MARKER_PY} \\ --hash=sha256:12345 """ assert content == expected_content poetry-plugin-export-1.8.0/tests/test_walker.py000066400000000000000000000017431461771375700217440ustar00rootroot00000000000000from __future__ import annotations import pytest from packaging.utils import NormalizedName from poetry.core.packages.dependency import Dependency from poetry.core.packages.package import Package from poetry_plugin_export.walker import DependencyWalkerError from poetry_plugin_export.walker import walk_dependencies def test_walk_dependencies_multiple_versions_when_latest_is_not_compatible() -> None: # TODO: Support this case: # https://github.com/python-poetry/poetry-plugin-export/issues/183 with pytest.raises(DependencyWalkerError): walk_dependencies( dependencies=[ Dependency("grpcio", ">=1.42.0"), Dependency("grpcio", ">=1.42.0,<=1.49.1"), Dependency("grpcio", ">=1.47.0,<2.0dev"), ], packages_by_name={ "grpcio": [Package("grpcio", "1.51.3"), Package("grpcio", "1.49.1")] }, root_package_name=NormalizedName("package-name"), ) poetry-plugin-export-1.8.0/tests/types.py000066400000000000000000000017221461771375700205610ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING from typing import Protocol if TYPE_CHECKING: from cleo.testers.command_tester import CommandTester from poetry.installation import Installer from poetry.installation.executor import Executor from poetry.poetry import Poetry from poetry.utils.env import Env class CommandTesterFactory(Protocol): def __call__( self, command: str, poetry: Poetry | None = None, installer: Installer | None = None, executor: Executor | None = None, environment: Env | None = None, ) -> CommandTester: ... class ProjectFactory(Protocol): def __call__( self, name: str, dependencies: dict[str, str] | None = None, dev_dependencies: dict[str, str] | None = None, pyproject_content: str | None = None, poetry_lock_content: str | None = None, install_deps: bool = True, ) -> Poetry: ...