From 5ff7eb5da08fcc4b392c846b3c5efb47ca02ee39 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Sun, 31 Dec 2023 18:03:37 -0700 Subject: [PATCH 01/12] Convert to PDM --- .github/workflows/checks.yml | 53 +-- .gitignore | 1 + CONTRIBUTING.md | 9 +- poetry.lock => pdm.lock | 840 ++++++++++++++++------------------- pyproject.toml | 132 +++--- tests/test_config.py | 4 +- 6 files changed, 476 insertions(+), 563 deletions(-) rename poetry.lock => pdm.lock (68%) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index deb4f4af9..0a7ba217d 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -30,42 +30,36 @@ jobs: uses: actions/cache@v3 with: path: .venv - key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies-${{ hashFiles('**/poetry.lock') }} + key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies-${{ hashFiles('**/pdm.lock') }} restore-keys: | ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies - - name: Install Poetry - run: pip install poetry - - - name: Create Virtual Environment - run: python -m venv .venv - - - name: Upgrade pip - run: poetry run python -m pip install --upgrade pip + - name: Install PDM + run: pip install pdm - name: Install Dependencies - run: poetry install + run: pdm install - name: Check formatting - run: poetry run ruff format . --check + run: pdm run ruff format . --check - name: Run safety - run: poetry export -f requirements.txt | poetry run safety check --bare --stdin + run: pdm safety_check - name: Run mypy - run: poetry run mypy --show-error-codes openapi_python_client + run: pdm mypy --show-error-codes - name: Lint - run: poetry run ruff check . + run: pdm run ruff check . - name: Run pytest without coverage if: matrix.os != 'ubuntu-latest' - run: poetry run pytest tests end_to_end_tests/test_end_to_end.py --basetemp=tests/tmp + run: pdm unit_tests env: TASKIPY: true - name: Run pytest with coverage if: matrix.os == 'ubuntu-latest' - run: poetry run pytest --cov=openapi_python_client --cov-report=term-missing tests end_to_end_tests/test_end_to_end.py --basetemp=tests/tmp + run: pdm unit_tests_with_coverage env: TASKIPY: true @@ -147,42 +141,39 @@ jobs: uses: actions/cache@v3 with: path: .venv - key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies-${{ hashFiles('**/poetry.lock') }} + key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies-${{ hashFiles('**/pdm.lock') }} restore-keys: | ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies - name: Install dependencies run: | - pip install poetry + pip install pdm python -m venv .venv - poetry run python -m pip install --upgrade pip - poetry install + pdm install - name: Regenerate Integration Client run: | - poetry run openapi-python-client update --url http://localhost:3000/openapi.json --config integration-tests-config.yaml + pdm run openapi-python-client update --url http://localhost:3000/openapi.json --config integration-tests-config.yaml - name: Check for any file changes run: python .github/check_for_changes.py - name: Cache Generated Client Dependencies uses: actions/cache@v3 with: path: integration-tests/.venv - key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-integration-dependencies-${{ hashFiles('**/poetry.lock') }} + key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-integration-dependencies-${{ hashFiles('**/pdm.lock') }} restore-keys: | ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-integration-dependencies - - name: Install Integration Dependencies - run: | - cd integration-tests - python -m venv .venv - poetry run python -m pip install --upgrade pip - poetry install - name: Set httpx version if: matrix.httpx_version != '' run: | cd integration-tests - poetry run pip install httpx==${{ matrix.httpx_version }} + pdm add httpx==${{ matrix.httpx_version }} + - name: Install Integration Dependencies + run: | + cd integration-tests + pdm install - name: Run Tests run: | cd integration-tests - poetry run pytest - poetry run mypy . --strict + pdm run pytest + pdm run mypy . --strict diff --git a/.gitignore b/.gitignore index eb6f53cd4..af75116d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.pdm-python __pycache__/ build/ dist/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e4cdf17f..52b67100a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,10 +40,9 @@ To request a feature: ### Setting up a Dev Environment -1. Make sure you have [Poetry](https://python-poetry.org/) installed and up to date. -2. Make sure you have a supported Python version (e.g. 3.8) installed and accessible to Poetry (e.g. with [pyenv](https://github.com/pyenv/pyenv)). -3. Use `poetry install` in the project directory to create a virtual environment with the relevant dependencies. -4. Enter a `poetry shell` to make running commands easier. +1. Make sure you have [PDM](https://pdm-project.org) installed and up to date. +2. Make sure you have a supported Python version (e.g. 3.8) installed. +3. Use `pdm install` in the project directory to create a virtual environment with the relevant dependencies. ### Writing tests @@ -57,7 +56,7 @@ If you think that some of the added code is not testable (or testing it would ad #### End-to-end tests -This project aims to have all "happy paths" (types of code which _can_ be generated) covered by end to end tests (snapshot tests). In order to check code changes against the previous set of snapshots (called a "golden record" here), you can run `poetry run task e2e`. To regenerate the snapshots, run `poetry run task regen`. +This project aims to have all "happy paths" (types of code which _can_ be generated) covered by end to end tests (snapshot tests). In order to check code changes against the previous set of snapshots (called a "golden record" here), you can run `pdm e2e`. To regenerate the snapshots, run `pdm regen`. There are 4 types of snapshots generated right now, you may have to update only some or all of these depending on the changes you're making. Within the `end_to_end_tets` directory: diff --git a/poetry.lock b/pdm.lock similarity index 68% rename from poetry.lock rename to pdm.lock index 715175c50..d652aa102 100644 --- a/poetry.lock +++ b/pdm.lock @@ -1,65 +1,59 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default", "dev"] +strategy = ["cross_platform", "inherit_metadata"] +lock_version = "4.4.1" +content_hash = "sha256:ff6eaafd9ff6cd5a3a9881deb8812fa7d2125e20dbd14ce2c2921a182a30c54a" [[package]] name = "annotated-types" version = "0.6.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "Reusable constraint types to use with typing.Annotated" +groups = ["default"] +dependencies = [ + "typing-extensions>=4.0.0; python_version < \"3.9\"", +] files = [ {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} - [[package]] name = "anyio" -version = "4.2.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" +version = "3.7.1" +requires_python = ">=3.7" +summary = "High level compatibility layer for multiple asynchronous event loop implementations" +groups = ["default"] +dependencies = [ + "exceptiongroup; python_version < \"3.11\"", + "idna>=2.8", + "sniffio>=1.1", +] files = [ - {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, - {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, + {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, + {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, ] -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] - [[package]] name = "attrs" -version = "23.1.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" +version = "23.2.0" +requires_python = ">=3.7" +summary = "Classes Without Boilerplate" +groups = ["default"] files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] -[package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] - [[package]] name = "certifi" version = "2023.11.17" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." +groups = ["default", "dev"] files = [ {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, @@ -68,9 +62,9 @@ files = [ [[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" +requires_python = ">=3.7.0" +summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +groups = ["dev"] 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"}, @@ -118,19 +112,6 @@ files = [ {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"}, @@ -167,23 +148,23 @@ files = [ [[package]] name = "click" version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Composable command line interface toolkit" +groups = ["default", "dev"] +dependencies = [ + "colorama; platform_system == \"Windows\"", +] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - [[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" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Cross-platform colored terminal text." +groups = ["default", "dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -191,110 +172,164 @@ files = [ [[package]] name = "coverage" -version = "7.3.4" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.8" +version = "7.4.0" +requires_python = ">=3.8" +summary = "Code coverage measurement for Python" +groups = ["dev"] files = [ - {file = "coverage-7.3.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aff2bd3d585969cc4486bfc69655e862028b689404563e6b549e6a8244f226df"}, - {file = "coverage-7.3.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4353923f38d752ecfbd3f1f20bf7a3546993ae5ecd7c07fd2f25d40b4e54571"}, - {file = "coverage-7.3.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea473c37872f0159294f7073f3fa72f68b03a129799f3533b2bb44d5e9fa4f82"}, - {file = "coverage-7.3.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5214362abf26e254d749fc0c18af4c57b532a4bfde1a057565616dd3b8d7cc94"}, - {file = "coverage-7.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f99b7d3f7a7adfa3d11e3a48d1a91bb65739555dd6a0d3fa68aa5852d962e5b1"}, - {file = "coverage-7.3.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:74397a1263275bea9d736572d4cf338efaade2de9ff759f9c26bcdceb383bb49"}, - {file = "coverage-7.3.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f154bd866318185ef5865ace5be3ac047b6d1cc0aeecf53bf83fe846f4384d5d"}, - {file = "coverage-7.3.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e0d84099ea7cba9ff467f9c6f747e3fc3906e2aadac1ce7b41add72e8d0a3712"}, - {file = "coverage-7.3.4-cp310-cp310-win32.whl", hash = "sha256:3f477fb8a56e0c603587b8278d9dbd32e54bcc2922d62405f65574bd76eba78a"}, - {file = "coverage-7.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:c75738ce13d257efbb6633a049fb2ed8e87e2e6c2e906c52d1093a4d08d67c6b"}, - {file = "coverage-7.3.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:997aa14b3e014339d8101b9886063c5d06238848905d9ad6c6eabe533440a9a7"}, - {file = "coverage-7.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a9c5bc5db3eb4cd55ecb8397d8e9b70247904f8eca718cc53c12dcc98e59fc8"}, - {file = "coverage-7.3.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27ee94f088397d1feea3cb524e4313ff0410ead7d968029ecc4bc5a7e1d34fbf"}, - {file = "coverage-7.3.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ce03e25e18dd9bf44723e83bc202114817f3367789052dc9e5b5c79f40cf59d"}, - {file = "coverage-7.3.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85072e99474d894e5df582faec04abe137b28972d5e466999bc64fc37f564a03"}, - {file = "coverage-7.3.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a877810ef918d0d345b783fc569608804f3ed2507bf32f14f652e4eaf5d8f8d0"}, - {file = "coverage-7.3.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9ac17b94ab4ca66cf803f2b22d47e392f0977f9da838bf71d1f0db6c32893cb9"}, - {file = "coverage-7.3.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:36d75ef2acab74dc948d0b537ef021306796da551e8ac8b467810911000af66a"}, - {file = "coverage-7.3.4-cp311-cp311-win32.whl", hash = "sha256:47ee56c2cd445ea35a8cc3ad5c8134cb9bece3a5cb50bb8265514208d0a65928"}, - {file = "coverage-7.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:11ab62d0ce5d9324915726f611f511a761efcca970bd49d876cf831b4de65be5"}, - {file = "coverage-7.3.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:33e63c578f4acce1b6cd292a66bc30164495010f1091d4b7529d014845cd9bee"}, - {file = "coverage-7.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:782693b817218169bfeb9b9ba7f4a9f242764e180ac9589b45112571f32a0ba6"}, - {file = "coverage-7.3.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c4277ddaad9293454da19121c59f2d850f16bcb27f71f89a5c4836906eb35ef"}, - {file = "coverage-7.3.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d892a19ae24b9801771a5a989fb3e850bd1ad2e2b6e83e949c65e8f37bc67a1"}, - {file = "coverage-7.3.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3024ec1b3a221bd10b5d87337d0373c2bcaf7afd86d42081afe39b3e1820323b"}, - {file = "coverage-7.3.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1c3e9d2bbd6f3f79cfecd6f20854f4dc0c6e0ec317df2b265266d0dc06535f1"}, - {file = "coverage-7.3.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e91029d7f151d8bf5ab7d8bfe2c3dbefd239759d642b211a677bc0709c9fdb96"}, - {file = "coverage-7.3.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6879fe41c60080aa4bb59703a526c54e0412b77e649a0d06a61782ecf0853ee1"}, - {file = "coverage-7.3.4-cp312-cp312-win32.whl", hash = "sha256:fd2f8a641f8f193968afdc8fd1697e602e199931012b574194052d132a79be13"}, - {file = "coverage-7.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:d1d0ce6c6947a3a4aa5479bebceff2c807b9f3b529b637e2b33dea4468d75fc7"}, - {file = "coverage-7.3.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:36797b3625d1da885b369bdaaa3b0d9fb8865caed3c2b8230afaa6005434aa2f"}, - {file = "coverage-7.3.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfed0ec4b419fbc807dec417c401499ea869436910e1ca524cfb4f81cf3f60e7"}, - {file = "coverage-7.3.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f97ff5a9fc2ca47f3383482858dd2cb8ddbf7514427eecf5aa5f7992d0571429"}, - {file = "coverage-7.3.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:607b6c6b35aa49defaebf4526729bd5238bc36fe3ef1a417d9839e1d96ee1e4c"}, - {file = "coverage-7.3.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8e258dcc335055ab59fe79f1dec217d9fb0cdace103d6b5c6df6b75915e7959"}, - {file = "coverage-7.3.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a02ac7c51819702b384fea5ee033a7c202f732a2a2f1fe6c41e3d4019828c8d3"}, - {file = "coverage-7.3.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b710869a15b8caf02e31d16487a931dbe78335462a122c8603bb9bd401ff6fb2"}, - {file = "coverage-7.3.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c6a23ae9348a7a92e7f750f9b7e828448e428e99c24616dec93a0720342f241d"}, - {file = "coverage-7.3.4-cp38-cp38-win32.whl", hash = "sha256:758ebaf74578b73f727acc4e8ab4b16ab6f22a5ffd7dd254e5946aba42a4ce76"}, - {file = "coverage-7.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:309ed6a559bc942b7cc721f2976326efbfe81fc2b8f601c722bff927328507dc"}, - {file = "coverage-7.3.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:aefbb29dc56317a4fcb2f3857d5bce9b881038ed7e5aa5d3bcab25bd23f57328"}, - {file = "coverage-7.3.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:183c16173a70caf92e2dfcfe7c7a576de6fa9edc4119b8e13f91db7ca33a7923"}, - {file = "coverage-7.3.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a4184dcbe4f98d86470273e758f1d24191ca095412e4335ff27b417291f5964"}, - {file = "coverage-7.3.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93698ac0995516ccdca55342599a1463ed2e2d8942316da31686d4d614597ef9"}, - {file = "coverage-7.3.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb220b3596358a86361139edce40d97da7458412d412e1e10c8e1970ee8c09ab"}, - {file = "coverage-7.3.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d5b14abde6f8d969e6b9dd8c7a013d9a2b52af1235fe7bebef25ad5c8f47fa18"}, - {file = "coverage-7.3.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:610afaf929dc0e09a5eef6981edb6a57a46b7eceff151947b836d869d6d567c1"}, - {file = "coverage-7.3.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d6ed790728fb71e6b8247bd28e77e99d0c276dff952389b5388169b8ca7b1c28"}, - {file = "coverage-7.3.4-cp39-cp39-win32.whl", hash = "sha256:c15fdfb141fcf6a900e68bfa35689e1256a670db32b96e7a931cab4a0e1600e5"}, - {file = "coverage-7.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:38d0b307c4d99a7aca4e00cad4311b7c51b7ac38fb7dea2abe0d182dd4008e05"}, - {file = "coverage-7.3.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:b1e0f25ae99cf247abfb3f0fac7ae25739e4cd96bf1afa3537827c576b4847e5"}, - {file = "coverage-7.3.4.tar.gz", hash = "sha256:020d56d2da5bc22a0e00a5b0d54597ee91ad72446fa4cf1b97c35022f6b6dbf0"}, + {file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"}, + {file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"}, + {file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"}, + {file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"}, + {file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"}, + {file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"}, + {file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"}, + {file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"}, + {file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"}, + {file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"}, + {file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"}, + {file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"}, + {file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"}, + {file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"}, ] -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] +[[package]] +name = "coverage" +version = "7.4.0" +extras = ["toml"] +requires_python = ">=3.8" +summary = "Code coverage measurement for Python" +groups = ["dev"] +dependencies = [ + "coverage==7.4.0", + "tomli; python_full_version <= \"3.11.0a6\"", +] +files = [ + {file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"}, + {file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"}, + {file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"}, + {file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"}, + {file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"}, + {file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"}, + {file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"}, + {file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"}, + {file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"}, + {file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"}, + {file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"}, + {file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"}, + {file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"}, + {file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"}, +] [[package]] name = "dparse" version = "0.6.3" -description = "A parser for Python dependency files" -optional = false -python-versions = ">=3.6" +requires_python = ">=3.6" +summary = "A parser for Python dependency files" +groups = ["dev"] +dependencies = [ + "packaging", + "tomli; python_version < \"3.11\"", +] files = [ {file = "dparse-0.6.3-py3-none-any.whl", hash = "sha256:0d8fe18714056ca632d98b24fbfc4e9791d4e47065285ab486182288813a5318"}, {file = "dparse-0.6.3.tar.gz", hash = "sha256:27bb8b4bcaefec3997697ba3f6e06b2447200ba273c0b085c3d012a04571b528"}, ] -[package.dependencies] -packaging = "*" -tomli = {version = "*", markers = "python_version < \"3.11\""} - -[package.extras] -conda = ["pyyaml"] -pipenv = ["pipenv (<=2022.12.19)"] - [[package]] name = "exceptiongroup" version = "1.2.0" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Backport of PEP 654 (exception groups)" +groups = ["default", "dev"] +marker = "python_version < \"3.11\"" 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 = "h11" version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +groups = ["default"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -303,54 +338,42 @@ files = [ [[package]] name = "httpcore" version = "1.0.2" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "A minimal low-level HTTP client." +groups = ["default"] +dependencies = [ + "certifi", + "h11<0.15,>=0.13", +] files = [ {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, ] -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.23.0)"] - [[package]] name = "httpx" version = "0.26.0" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "The next generation HTTP client." +groups = ["default"] +dependencies = [ + "anyio", + "certifi", + "httpcore==1.*", + "idna", + "sniffio", +] files = [ {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - [[package]] name = "idna" version = "3.6" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" +requires_python = ">=3.5" +summary = "Internationalized Domain Names in Applications (IDNA)" +groups = ["default", "dev"] files = [ {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, @@ -359,9 +382,9 @@ files = [ [[package]] name = "iniconfig" version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "brain-dead simple config-ini parsing" +groups = ["dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -370,26 +393,23 @@ files = [ [[package]] name = "jinja2" version = "3.1.2" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "A very fast and expressive template engine." +groups = ["default"] +dependencies = [ + "MarkupSafe>=2.0", +] files = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - [[package]] name = "markupsafe" version = "2.1.3" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Safely add untrusted strings to HTML/XML markup." +groups = ["default"] files = [ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, @@ -421,15 +441,6 @@ files = [ {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, @@ -456,9 +467,10 @@ files = [ [[package]] name = "mslex" version = "1.1.0" -description = "shlex for windows" -optional = false -python-versions = ">=3.5" +requires_python = ">=3.5" +summary = "shlex for windows" +groups = ["dev"] +marker = "sys_platform == \"win32\"" files = [ {file = "mslex-1.1.0-py2.py3-none-any.whl", hash = "sha256:8826f4bb8d8c63402203d921dc8c2df0c7fec0d9c91d020ddf02fc9d0dce81bd"}, {file = "mslex-1.1.0.tar.gz", hash = "sha256:7fe305fbdc9721283875e0b737fdb344374b761338a7f41af91875de278568e4"}, @@ -467,9 +479,14 @@ files = [ [[package]] name = "mypy" version = "1.8.0" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "Optional static typing for Python" +groups = ["dev"] +dependencies = [ + "mypy-extensions>=1.0.0", + "tomli>=1.1.0; python_version < \"3.11\"", + "typing-extensions>=4.1.0", +] files = [ {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, @@ -500,23 +517,12 @@ files = [ {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, ] -[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" +requires_python = ">=3.5" +summary = "Type system extensions for programs checked with the mypy type checker." +groups = ["dev"] 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"}, @@ -525,85 +531,69 @@ files = [ [[package]] name = "packaging" version = "21.3" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.6" +requires_python = ">=3.6" +summary = "Core utilities for Python packages" +groups = ["dev"] +dependencies = [ + "pyparsing!=3.0.5,>=2.0.2", +] files = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" - [[package]] name = "pluggy" version = "1.3.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "plugin and hook calling mechanisms for python" +groups = ["dev"] files = [ {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - [[package]] name = "psutil" version = "5.9.7" -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.*" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "Cross-platform lib for process and system monitoring in Python." +groups = ["dev"] files = [ - {file = "psutil-5.9.7-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0bd41bf2d1463dfa535942b2a8f0e958acf6607ac0be52265ab31f7923bcd5e6"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5794944462509e49d4d458f4dbfb92c47539e7d8d15c796f141f474010084056"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:fe361f743cb3389b8efda21980d93eb55c1f1e3898269bc9a2a1d0bb7b1f6508"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:e469990e28f1ad738f65a42dcfc17adaed9d0f325d55047593cb9033a0ab63df"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:3c4747a3e2ead1589e647e64aad601981f01b68f9398ddf94d01e3dc0d1e57c7"}, - {file = "psutil-5.9.7-cp27-none-win32.whl", hash = "sha256:1d4bc4a0148fdd7fd8f38e0498639ae128e64538faa507df25a20f8f7fb2341c"}, - {file = "psutil-5.9.7-cp27-none-win_amd64.whl", hash = "sha256:4c03362e280d06bbbfcd52f29acd79c733e0af33d707c54255d21029b8b32ba6"}, {file = "psutil-5.9.7-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ea36cc62e69a13ec52b2f625c27527f6e4479bca2b340b7a452af55b34fcbe2e"}, {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1132704b876e58d277168cd729d64750633d5ff0183acf5b3c986b8466cd0284"}, {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8b7f07948f1304497ce4f4684881250cd859b16d06a1dc4d7941eeb6233bfe"}, - {file = "psutil-5.9.7-cp36-cp36m-win32.whl", hash = "sha256:b27f8fdb190c8c03914f908a4555159327d7481dac2f01008d483137ef3311a9"}, - {file = "psutil-5.9.7-cp36-cp36m-win_amd64.whl", hash = "sha256:44969859757f4d8f2a9bd5b76eba8c3099a2c8cf3992ff62144061e39ba8568e"}, {file = "psutil-5.9.7-cp37-abi3-win32.whl", hash = "sha256:c727ca5a9b2dd5193b8644b9f0c883d54f1248310023b5ad3e92036c5e2ada68"}, {file = "psutil-5.9.7-cp37-abi3-win_amd64.whl", hash = "sha256:f37f87e4d73b79e6c5e749440c3113b81d1ee7d26f21c19c47371ddea834f414"}, {file = "psutil-5.9.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:032f4f2c909818c86cea4fe2cc407f1c0f0cde8e6c6d702b28b8ce0c0d143340"}, {file = "psutil-5.9.7.tar.gz", hash = "sha256:3f02134e82cfb5d089fddf20bb2e03fd5cd52395321d1c8458a9e58500ff417c"}, ] -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - [[package]] name = "pydantic" version = "2.5.3" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Data validation using Python type hints" +groups = ["default"] +dependencies = [ + "annotated-types>=0.4.0", + "pydantic-core==2.14.6", + "typing-extensions>=4.6.1", +] files = [ {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, ] -[package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.14.6" -typing-extensions = ">=4.6.1" - -[package.extras] -email = ["email-validator (>=2.0.0)"] - [[package]] name = "pydantic-core" version = "2.14.6" -description = "" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "" +groups = ["default"] +dependencies = [ + "typing-extensions!=4.7.0,>=4.6.0", +] files = [ {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, @@ -643,18 +633,6 @@ files = [ {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, - {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, - {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, @@ -712,114 +690,96 @@ files = [ {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, ] -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - [[package]] name = "pyparsing" version = "3.1.1" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.6.8" +requires_python = ">=3.6.8" +summary = "pyparsing module - Classes and methods to define and execute parsing grammars" +groups = ["dev"] files = [ {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, ] -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pytest" -version = "7.4.3" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" +version = "7.4.4" +requires_python = ">=3.7" +summary = "pytest: simple powerful testing with Python" +groups = ["dev"] +dependencies = [ + "colorama; sys_platform == \"win32\"", + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", + "pluggy<2.0,>=0.12", + "tomli>=1.0.0; python_version < \"3.11\"", +] files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "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" +requires_python = ">=3.7" +summary = "Pytest plugin for measuring coverage." +groups = ["dev"] +dependencies = [ + "coverage[toml]>=5.2.1", + "pytest>=4.6", +] 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-mock" version = "3.12.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "Thin-wrapper around the mock package for easier use with pytest" +groups = ["dev"] +dependencies = [ + "pytest>=5.0", +] 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 = "python-dateutil" version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +summary = "Extensions to the standard Python datetime module" +groups = ["default"] +dependencies = [ + "six>=1.5", +] files = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] -[package.dependencies] -six = ">=1.5" - [[package]] name = "python-multipart" version = "0.0.6" -description = "A streaming multipart parser for Python" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "A streaming multipart parser for Python" +groups = ["dev"] files = [ {file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"}, {file = "python_multipart-0.0.6.tar.gz", hash = "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132"}, ] -[package.extras] -dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==1.7.3)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"] - [[package]] name = "pyyaml" version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" +requires_python = ">=3.6" +summary = "YAML parser and emitter for Python" +groups = ["default"] 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"}, @@ -843,18 +803,6 @@ files = [ {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"}, @@ -876,48 +824,41 @@ files = [ [[package]] name = "requests" version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Python HTTP for Humans." +groups = ["dev"] +dependencies = [ + "certifi>=2017.4.17", + "charset-normalizer<4,>=2", + "idna<4,>=2.5", + "urllib3<3,>=1.21.1", +] 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 = "ruamel-yaml" version = "0.18.5" -description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +groups = ["dev"] +dependencies = [ + "ruamel-yaml-clib>=0.2.7; platform_python_implementation == \"CPython\" and python_version < \"3.13\"", +] files = [ {file = "ruamel.yaml-0.18.5-py3-none-any.whl", hash = "sha256:a013ac02f99a69cdd6277d9664689eb1acba07069f912823177c5eced21a6ada"}, {file = "ruamel.yaml-0.18.5.tar.gz", hash = "sha256:61917e3a35a569c1133a8f772e1226961bf5a1198bea7e23f06a0841dea1ab0e"}, ] -[package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} - -[package.extras] -docs = ["mercurial (>5.7)", "ryd"] -jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] - [[package]] name = "ruamel-yaml-clib" version = "0.2.8" -description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -optional = false -python-versions = ">=3.6" +requires_python = ">=3.6" +summary = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +groups = ["dev"] +marker = "platform_python_implementation == \"CPython\" and python_version < \"3.13\"" files = [ {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, @@ -943,15 +884,6 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, - {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, @@ -974,9 +906,9 @@ files = [ [[package]] name = "ruff" version = "0.1.9" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "An extremely fast Python linter and code formatter, written in Rust." +groups = ["default"] files = [ {file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e6a212f436122ac73df851f0cf006e0c6612fe6f9c864ed17ebefce0eff6a5fd"}, {file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:28d920e319783d5303333630dae46ecc80b7ba294aeffedf946a02ac0b7cc3db"}, @@ -1000,48 +932,38 @@ files = [ [[package]] name = "safety" version = "2.3.5" -description = "Checks installed dependencies for known vulnerabilities and licenses." -optional = false -python-versions = "*" +summary = "Checks installed dependencies for known vulnerabilities and licenses." +groups = ["dev"] +dependencies = [ + "Click>=8.0.2", + "dparse>=0.6.2", + "packaging<22.0,>=21.0", + "requests", + "ruamel-yaml>=0.17.21", + "setuptools>=19.3", +] files = [ {file = "safety-2.3.5-py3-none-any.whl", hash = "sha256:2227fcac1b22b53c1615af78872b48348661691450aa25d6704a5504dbd1f7e2"}, {file = "safety-2.3.5.tar.gz", hash = "sha256:a60c11f8952f412cbb165d70cb1f673a3b43a2ba9a93ce11f97e6a4de834aa3a"}, ] -[package.dependencies] -Click = ">=8.0.2" -dparse = ">=0.6.2" -packaging = ">=21.0,<22.0" -requests = "*" -"ruamel.yaml" = ">=0.17.21" -setuptools = ">=19.3" - -[package.extras] -github = ["jinja2 (>=3.1.0)", "pygithub (>=1.43.3)"] -gitlab = ["python-gitlab (>=1.3.0)"] - [[package]] name = "setuptools" version = "69.0.3" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "Easily download, build, install, upgrade, and uninstall Python packages" +groups = ["dev"] files = [ {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, ] -[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)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "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.1)", "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" +requires_python = ">=3.7" +summary = "Tool to Detect Surrounding Shell" +groups = ["default"] files = [ {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, @@ -1050,9 +972,9 @@ files = [ [[package]] name = "six" version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "Python 2 and 3 compatibility utilities" +groups = ["default"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1061,9 +983,9 @@ files = [ [[package]] name = "sniffio" version = "1.3.0" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Sniff out which async library your code is running under" +groups = ["default"] files = [ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, @@ -1072,26 +994,27 @@ files = [ [[package]] name = "taskipy" version = "1.12.2" -description = "tasks runner for python projects" -optional = false -python-versions = ">=3.6,<4.0" +requires_python = ">=3.6,<4.0" +summary = "tasks runner for python projects" +groups = ["dev"] +dependencies = [ + "colorama<0.5.0,>=0.4.4", + "mslex<2.0.0,>=1.1.0; sys_platform == \"win32\"", + "psutil<6.0.0,>=5.7.2", + "tomli<3.0.0,>=2.0.1; python_version ~= \"3.7\"", +] files = [ {file = "taskipy-1.12.2-py3-none-any.whl", hash = "sha256:ffdbb0bb0db54c0ec5c424610a3a087eea22706d4d1f6e3e8b4f12ebba05f98f"}, {file = "taskipy-1.12.2.tar.gz", hash = "sha256:eadfdc20d6bb94d8018eda32f1dbf584cf4aa6cffb71ba5cc2de20d344f8c4fb"}, ] -[package.dependencies] -colorama = ">=0.4.4,<0.5.0" -mslex = {version = ">=1.1.0,<2.0.0", markers = "sys_platform == \"win32\""} -psutil = ">=5.7.2,<6.0.0" -tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} - [[package]] name = "tomli" version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "A lil' TOML parser" +groups = ["dev"] +marker = "python_version < \"4.0\"" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, @@ -1100,30 +1023,23 @@ files = [ [[package]] name = "typer" version = "0.9.0" -description = "Typer, build great CLIs. Easy to code. Based on Python type hints." -optional = false -python-versions = ">=3.6" +requires_python = ">=3.6" +summary = "Typer, build great CLIs. Easy to code. Based on Python type hints." +groups = ["default"] +dependencies = [ + "click<9.0.0,>=7.1.1", + "typing-extensions>=3.7.4.3", +] files = [ {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"}, {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"}, ] -[package.dependencies] -click = ">=7.1.1,<9.0.0" -typing-extensions = ">=3.7.4.3" - -[package.extras] -all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] -dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] -doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] -test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] - [[package]] name = "types-certifi" version = "2020.4.0" -description = "Typing stubs for certifi" -optional = false -python-versions = "*" +summary = "Typing stubs for certifi" +groups = ["dev"] files = [ {file = "types-certifi-2020.4.0.tar.gz", hash = "sha256:787d1a0c7897a1c658f8f7958ae57141b3fff13acb866e5bcd31cfb45037546f"}, {file = "types_certifi-2020.4.0-py3-none-any.whl", hash = "sha256:0ffdbe451d3b02f6d2cfd87bcfb2f086a4ff1fa76a35d51cfc3771e261d7a8fd"}, @@ -1132,9 +1048,8 @@ files = [ [[package]] name = "types-python-dateutil" version = "2.8.19.14" -description = "Typing stubs for python-dateutil" -optional = false -python-versions = "*" +summary = "Typing stubs for python-dateutil" +groups = ["dev"] files = [ {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"}, {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"}, @@ -1143,9 +1058,8 @@ files = [ [[package]] name = "types-pyyaml" version = "6.0.12.12" -description = "Typing stubs for PyYAML" -optional = false -python-versions = "*" +summary = "Typing stubs for PyYAML" +groups = ["dev"] files = [ {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"}, {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"}, @@ -1154,9 +1068,9 @@ files = [ [[package]] name = "typing-extensions" version = "4.9.0" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "Backported and Experimental Type Hints for Python 3.8+" +groups = ["default", "dev"] files = [ {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, @@ -1165,20 +1079,10 @@ files = [ [[package]] name = "urllib3" version = "2.1.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["dev"] files = [ {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, ] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.8" -content-hash = "b2ee2614edde33c99843d87af4c8ceaf41c37d33f94372224fb40638665fb460" diff --git a/pyproject.toml b/pyproject.toml index 7a783873b..9dfd5d92d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,30 @@ -[tool.poetry] +[project] +authors = [ + { name = "Dylan Anthony", email = "contact@dylananthony.com" }, +] +license = { text = "MIT" } +requires-python = ">=3.8,<4.0" +dependencies = [ + "jinja2<4.0.0,>=3.0.0", + "typer<0.10,>0.6", + "colorama<1.0.0,>=0.4.3; sys_platform == \"win32\"", + "shellingham<2.0.0,>=1.3.2", + "pydantic<3.0.0,>=2.1.1", + "attrs>=21.3.0", + "python-dateutil<3.0.0,>=2.8.1", + "httpx>=0.20.0,<0.27.0", + "PyYAML<7.0,>=6.0", + "ruff<1.0.0,>=0.1.2", + "typing-extensions<5.0.0,>=4.8.0", +] name = "openapi-python-client" version = "0.17.0" description = "Generate modern Python clients from OpenAPI" -repository = "https://github.com/triaxtec/openapi-python-client" -license = "MIT" -keywords=["OpenAPI", "Client", "Generator"] -authors = ["Dylan Anthony "] +keywords = [ + "OpenAPI", + "Client", + "Generator", +] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", @@ -13,60 +32,59 @@ classifiers = [ "Typing :: Typed", ] readme = "README.md" -packages = [ - {include = "openapi_python_client"}, -] -include = ["CHANGELOG.md", "openapi_python_client/py.typed"] - -[tool.poetry.dependencies] -python = "^3.8" -jinja2 = "^3.0.0" -typer = ">0.6, <0.10" -colorama = {version = "^0.4.3", markers = "sys_platform == 'win32'"} -shellingham = "^1.3.2" -pydantic = "^2.1.1" -attrs = ">=21.3.0" -python-dateutil = "^2.8.1" -httpx = ">=0.20.0,<0.27.0" -PyYAML = "^6.0" -ruff = "^0.1.2" -typing-extensions = "^4.8.0" - -[tool.poetry.scripts] + +[project.urls] +repository = "https://github.com/openapi-generators/openapi-python-client" + +[project.scripts] openapi-python-client = "openapi_python_client.cli:app" -[tool.poetry.dev-dependencies] -pytest = "*" -pytest-mock = "*" -mypy = "*" -taskipy = "*" -safety = "*" -pytest-cov = "*" -python-multipart = "*" -types-PyYAML = "^6.0.3" -types-certifi = "^2020.0.0" -types-python-dateutil = "^2.0.0" - -[tool.taskipy.tasks] -check = """ -ruff check --fix . \ - && ruff format .\ - && poetry export -f requirements.txt | poetry run safety check --bare --stdin\ - && mypy openapi_python_client\ - && TASKIPY=true pytest --cov openapi_python_client tests --cov-report=term-missing --basetemp=tests/tmp\ - && rm -r tests/tmp\ -""" -regen = """ -task regen_e2e\ -&& task regen_integration\ -""" +[tool.pdm] +[tool.pdm.dev-dependencies] +dev = [ + "pytest", + "pytest-mock", + "mypy", + "taskipy", + "safety", + "pytest-cov", + "python-multipart", + "types-PyYAML<7.0.0,>=6.0.3", + "types-certifi<2021.0.0,>=2020.0.0", + "types-python-dateutil<3.0.0,>=2.0.0", +] + +[tool.pdm.build] +includes = [ + "openapi_python_client", + "CHANGELOG.md", + "openapi_python_client/py.typed", +] + +[tool.pdm.scripts] +lint = "ruff check --fix ." +format = "ruff format ." +safety_check = { shell = "pdm export -o requirements.txt && safety check -r requirements.txt --bare && rm requirements.txt" } +mypy = "mypy openapi_python_client" +check = { composite = ["lint", "format", "safety_check", "mypy", "unit_tests_with_coverage"] } +regen = {composite = ["regen_e2e", "regen_integration"]} e2e = "pytest openapi_python_client end_to_end_tests/test_end_to_end.py" -re = """ -task regen\ -&& task e2e\ -""" +re = {composite = ["regen_e2e", "e2e"]} regen_e2e = "python -m end_to_end_tests.regen_golden_record" -regen_integration = """ + +[tool.pdm.scripts.unit_tests] +cmd = "pytest --basetemp=tests/tmp" +[tool.pdm.scripts.unit_tests.env] +"TEST_RELATIVE" = "true" + +[tool.pdm.scripts.post_unit_tests] +cmd = "rm -r tests/tmp" + +[tool.pdm.scripts.unit_tests_with_coverage] +composite = ["unit_tests --cov openapi_python_client tests --cov-report=term-missing"] + +[tool.pdm.scripts.regen_integration] +shell = """ openapi-python-client update --url https://raw.githubusercontent.com/openapi-generators/openapi-test-server/main/openapi.json --config integration-tests-config.yaml\ && mypy integration-tests --strict """ @@ -108,5 +126,5 @@ ignore_missing_imports = true junit_family = "xunit2" [build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +requires = ["pdm-backend"] +build-backend = "pdm.backend" diff --git a/tests/test_config.py b/tests/test_config.py index b41905a52..d4bf39a10 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -25,8 +25,8 @@ def json_with_tabs(d): def test_load_from_path(tmp_path: Path, filename, dump, relative): yml_file = tmp_path.joinpath(filename) if relative: - if not os.getenv("TASKIPY"): - pytest.skip("Only test relative paths when running with `task check`") + if not os.getenv("TEST_RELATIVE"): + pytest.skip("Skipping relative path checks") return yml_file = yml_file.relative_to(Path.cwd()) override1 = {"class_name": "ExampleClass", "module_name": "example_module"} From 11aeb8c8f01a30e720eee222378d225adda3e30e Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Mon, 1 Jan 2024 11:58:54 -0700 Subject: [PATCH 02/12] Convert integration tests to PDM --- .github/workflows/checks.yml | 4 +- .gitignore | 3 + end_to_end_tests/golden-record/pyproject.toml | 2 - .../test-3-1-golden-record/pyproject.toml | 2 - integration-tests/README.md | 70 +++-- integration-tests/{poetry.lock => pdm.lock} | 271 +++++++----------- integration-tests/pyproject.toml | 36 ++- openapi_python_client/__init__.py | 7 +- .../templates/pyproject.toml.jinja | 34 ++- ...y.toml.jinja => pyproject_ruff.toml.jinja} | 0 pyproject.toml | 2 +- 11 files changed, 210 insertions(+), 221 deletions(-) rename integration-tests/{poetry.lock => pdm.lock} (61%) rename openapi_python_client/templates/{pyproject_no_poetry.toml.jinja => pyproject_ruff.toml.jinja} (100%) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 0a7ba217d..46c53429a 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -151,7 +151,7 @@ jobs: pdm install - name: Regenerate Integration Client run: | - pdm run openapi-python-client update --url http://localhost:3000/openapi.json --config integration-tests-config.yaml + pdm run openapi-python-client update --url http://localhost:3000/openapi.json --config integration-tests-config.yaml --meta pdm - name: Check for any file changes run: python .github/check_for_changes.py - name: Cache Generated Client Dependencies @@ -175,5 +175,3 @@ jobs: cd integration-tests pdm run pytest pdm run mypy . --strict - - diff --git a/.gitignore b/.gitignore index af75116d4..3c0fc0a41 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ dist/ *.egg-info/ .pytest_cache/ +# macOS +.DS_Store + # pyenv .python-version diff --git a/end_to_end_tests/golden-record/pyproject.toml b/end_to_end_tests/golden-record/pyproject.toml index 75e076d66..6c57de7f0 100644 --- a/end_to_end_tests/golden-record/pyproject.toml +++ b/end_to_end_tests/golden-record/pyproject.toml @@ -2,9 +2,7 @@ name = "my-test-api-client" version = "0.1.0" description = "A client library for accessing My Test API" - authors = [] - readme = "README.md" packages = [ {include = "my_test_api_client"}, diff --git a/end_to_end_tests/test-3-1-golden-record/pyproject.toml b/end_to_end_tests/test-3-1-golden-record/pyproject.toml index 2f9d177f0..db26ff221 100644 --- a/end_to_end_tests/test-3-1-golden-record/pyproject.toml +++ b/end_to_end_tests/test-3-1-golden-record/pyproject.toml @@ -2,9 +2,7 @@ name = "test-3-1-features-client" version = "0.1.0" description = "A client library for accessing Test 3.1 Features" - authors = [] - readme = "README.md" packages = [ {include = "test_3_1_features_client"}, diff --git a/integration-tests/README.md b/integration-tests/README.md index f7e1cdfc6..f92972290 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -1,4 +1,4 @@ -# open-api-test-server-client +# integration-tests A client library for accessing OpenAPI Test Server ## Usage @@ -25,9 +25,10 @@ from integration_tests.models import MyDataModel from integration_tests.api.my_tag import get_my_data_model from integration_tests.types import Response -my_data: MyDataModel = get_my_data_model.sync(client=client) -# or if you need more info (e.g. status_code) -response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client) +with client as client: + my_data: MyDataModel = get_my_data_model.sync(client=client) + # or if you need more info (e.g. status_code) + response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client) ``` Or do the same thing with an async version: @@ -37,8 +38,9 @@ from integration_tests.models import MyDataModel from integration_tests.api.my_tag import get_my_data_model from integration_tests.types import Response -my_data: MyDataModel = await get_my_data_model.asyncio(client=client) -response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client) +async with client as client: + my_data: MyDataModel = await get_my_data_model.asyncio(client=client) + response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client) ``` By default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle. @@ -65,23 +67,45 @@ Things to know: 1. Every path/method combo becomes a Python module with four functions: 1. `sync`: Blocking request that returns parsed data (if successful) or `None` 1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful. - 1. `asyncio`: Like `sync` but the async instead of blocking - 1. `asyncio_detailed`: Like `sync_detailed` by async instead of blocking + 1. `asyncio`: Like `sync` but async instead of blocking + 1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking 1. All path/query params, and bodies become method arguments. 1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above) -1. Any endpoint which did not have a tag will be in `open_api_test_server_client.api.default` - -## Building / publishing this Client -This project uses [Poetry](https://python-poetry.org/) to manage dependencies and packaging. Here are the basics: -1. Update the metadata in pyproject.toml (e.g. authors, version) -1. If you're using a private repository, configure it with Poetry - 1. `poetry config repositories. ` - 1. `poetry config http-basic. ` -1. Publish the client with `poetry publish --build -r ` or, if for public PyPI, just `poetry publish --build` - -If you want to install this client into another project without publishing it (e.g. for development) then: -1. If that project **is using Poetry**, you can simply do `poetry add ` from that project -1. If that project is not using Poetry: - 1. Build a wheel with `poetry build -f wheel` - 1. Install that wheel from the other project `pip install ` \ No newline at end of file +1. Any endpoint which did not have a tag will be in `integration_tests.api.default` + +## Advanced customizations + +There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case): + +```python +from integration_tests import Client + +def log_request(request): + print(f"Request event hook: {request.method} {request.url} - Waiting for response") + +def log_response(response): + request = response.request + print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}") + +client = Client( + base_url="https://api.example.com", + httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}}, +) + +# Or get the underlying httpx client to modify directly with client.get_httpx_client() or client.get_async_httpx_client() +``` + +You can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url): + +```python +import httpx +from integration_tests import Client + +client = Client( + base_url="https://api.example.com", +) +# Note that base_url needs to be re-set, as would any shared cookies, headers, etc. +client.set_httpx_client(httpx.Client(base_url="https://api.example.com", proxies="http://localhost:8030")) +``` + diff --git a/integration-tests/poetry.lock b/integration-tests/pdm.lock similarity index 61% rename from integration-tests/poetry.lock rename to integration-tests/pdm.lock index fda428ded..868bfd960 100644 --- a/integration-tests/poetry.lock +++ b/integration-tests/pdm.lock @@ -1,51 +1,46 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default", "dev"] +strategy = ["cross_platform", "inherit_metadata"] +lock_version = "4.4.1" +content_hash = "sha256:3bdac2ab85ad57e456464153a1222cc108ec7a838cd4d062aabe571501c05e5b" [[package]] name = "anyio" version = "4.2.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "High level compatibility layer for multiple asynchronous event loop implementations" +groups = ["default"] +dependencies = [ + "exceptiongroup>=1.0.2; python_version < \"3.11\"", + "idna>=2.8", + "sniffio>=1.1", + "typing-extensions>=4.1; python_version < \"3.11\"", +] files = [ {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, ] -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] - [[package]] name = "attrs" -version = "23.1.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" +version = "23.2.0" +requires_python = ">=3.7" +summary = "Classes Without Boilerplate" +groups = ["default"] files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] -[package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] - [[package]] name = "certifi" version = "2023.11.17" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." +groups = ["default"] files = [ {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, @@ -54,9 +49,10 @@ files = [ [[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" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Cross-platform colored terminal text." +groups = ["dev"] +marker = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -65,23 +61,21 @@ files = [ [[package]] name = "exceptiongroup" version = "1.2.0" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Backport of PEP 654 (exception groups)" +groups = ["default", "dev"] +marker = "python_version < \"3.11\"" 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 = "h11" version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +groups = ["default"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -90,54 +84,42 @@ files = [ [[package]] name = "httpcore" version = "1.0.2" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "A minimal low-level HTTP client." +groups = ["default"] +dependencies = [ + "certifi", + "h11<0.15,>=0.13", +] files = [ {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, ] -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.23.0)"] - [[package]] name = "httpx" version = "0.26.0" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "The next generation HTTP client." +groups = ["default"] +dependencies = [ + "anyio", + "certifi", + "httpcore==1.*", + "idna", + "sniffio", +] files = [ {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - [[package]] name = "idna" version = "3.6" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" +requires_python = ">=3.5" +summary = "Internationalized Domain Names in Applications (IDNA)" +groups = ["default"] files = [ {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, @@ -146,9 +128,9 @@ files = [ [[package]] name = "iniconfig" version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "brain-dead simple config-ini parsing" +groups = ["dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -157,9 +139,14 @@ files = [ [[package]] name = "mypy" version = "1.8.0" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "Optional static typing for Python" +groups = ["dev"] +dependencies = [ + "mypy-extensions>=1.0.0", + "tomli>=1.1.0; python_version < \"3.11\"", + "typing-extensions>=4.1.0", +] files = [ {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, @@ -190,23 +177,12 @@ files = [ {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, ] -[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" +requires_python = ">=3.5" +summary = "Type system extensions for programs checked with the mypy type checker." +groups = ["dev"] 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"}, @@ -215,9 +191,9 @@ files = [ [[package]] name = "packaging" version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Core utilities for Python packages" +groups = ["dev"] files = [ {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, @@ -226,78 +202,53 @@ files = [ [[package]] name = "pluggy" version = "1.3.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "plugin and hook calling mechanisms for python" +groups = ["dev"] files = [ {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - [[package]] name = "pytest" -version = "7.4.3" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, +version = "7.4.4" +requires_python = ">=3.7" +summary = "pytest: simple powerful testing with Python" +groups = ["dev"] +dependencies = [ + "colorama; sys_platform == \"win32\"", + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", + "pluggy<2.0,>=0.12", + "tomli>=1.0.0; python_version < \"3.11\"", ] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.23.2" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.8" files = [ - {file = "pytest-asyncio-0.23.2.tar.gz", hash = "sha256:c16052382554c7b22d48782ab3438d5b10f8cf7a4bdcae7f0f67f097d95beecc"}, - {file = "pytest_asyncio-0.23.2-py3-none-any.whl", hash = "sha256:ea9021364e32d58f0be43b91c6233fb8d2224ccef2398d6837559e587682808f"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] -[package.dependencies] -pytest = ">=7.0.0" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] - [[package]] name = "python-dateutil" version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +summary = "Extensions to the standard Python datetime module" +groups = ["default"] +dependencies = [ + "six>=1.5", +] files = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] -[package.dependencies] -six = ">=1.5" - [[package]] name = "six" version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "Python 2 and 3 compatibility utilities" +groups = ["default"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -306,9 +257,9 @@ files = [ [[package]] name = "sniffio" version = "1.3.0" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "Sniff out which async library your code is running under" +groups = ["default"] files = [ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, @@ -317,9 +268,10 @@ files = [ [[package]] name = "tomli" version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" +requires_python = ">=3.7" +summary = "A lil' TOML parser" +groups = ["dev"] +marker = "python_version < \"3.11\"" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, @@ -328,15 +280,10 @@ files = [ [[package]] name = "typing-extensions" version = "4.9.0" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" +requires_python = ">=3.8" +summary = "Backported and Experimental Type Hints for Python 3.8+" +groups = ["default", "dev"] files = [ {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] - -[metadata] -lock-version = "2.0" -python-versions = "^3.8" -content-hash = "2eba76108ad68413b2167fa0c019e14ab5da12a332be158c0f00dd699f456cf9" diff --git a/integration-tests/pyproject.toml b/integration-tests/pyproject.toml index e6bb01bb2..b91778fac 100644 --- a/integration-tests/pyproject.toml +++ b/integration-tests/pyproject.toml @@ -1,31 +1,29 @@ -[tool.poetry] +[project] name = "integration-tests" version = "0.0.1" description = "A client library for accessing OpenAPI Test Server" authors = [] readme = "README.md" -packages = [ - {include = "integration_tests"}, +dependencies = [ + "httpx>=0.20.0,<0.27.0", + "attrs>=21.3.0", + "python-dateutil>=2.8.0", ] -include = ["CHANGELOG.md", "open_api_test_server_client/py.typed"] +requires-python = ">=3.8,<4.0" -[tool.poetry.dependencies] -python = "^3.8" -httpx = ">=0.15.4,<0.27.0" -attrs = ">=21.3.0" -python-dateutil = "^2.8.0" - -[tool.poetry.dev-dependencies] -pytest = "^7.0.0" -mypy = "*" - -[tool.poetry.group.dev.dependencies] -pytest-asyncio = "*" +[tool.pdm] +package-type = "library" [build-system] -requires = ["poetry>=1.0"] -build-backend = "poetry.masonry.api" - +requires = ["pdm-backend"] +build-backend = "pdm.backend" + [tool.ruff] select = ["F", "I"] line-length = 120 + +[tool.pdm.dev-dependencies] +dev = [ + "pytest", + "mypy", +] diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index e380b9b32..cc4290692 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -30,6 +30,7 @@ class MetaType(str, Enum): NONE = "none" POETRY = "poetry" SETUP = "setup" + PDM = "pdm" TEMPLATE_FILTERS = { @@ -189,7 +190,7 @@ def _build_metadata(self) -> None: if self.meta == MetaType.NONE: return - self._build_pyproject_toml(use_poetry=self.meta == MetaType.POETRY) + self._build_pyproject_toml() if self.meta == MetaType.SETUP: self._build_setup_py() @@ -206,12 +207,12 @@ def _build_metadata(self) -> None: git_ignore_template = self.env.get_template(".gitignore.jinja") git_ignore_path.write_text(git_ignore_template.render(), encoding=self.file_encoding) - def _build_pyproject_toml(self, *, use_poetry: bool) -> None: + def _build_pyproject_toml(self) -> None: template = "pyproject.toml.jinja" pyproject_template = self.env.get_template(template) pyproject_path = self.project_dir / "pyproject.toml" pyproject_path.write_text( - pyproject_template.render(use_poetry=use_poetry), + pyproject_template.render(meta=self.meta), encoding=self.file_encoding, ) diff --git a/openapi_python_client/templates/pyproject.toml.jinja b/openapi_python_client/templates/pyproject.toml.jinja index 2bba5d9b7..0ff9e133e 100644 --- a/openapi_python_client/templates/pyproject.toml.jinja +++ b/openapi_python_client/templates/pyproject.toml.jinja @@ -1,26 +1,48 @@ -{% if use_poetry %} -[tool.poetry] +{% set poetry = meta == "poetry" %} +{% set pdm = meta == "pdm" %} +{% if poetry or pdm %} +{% if poetry %}[tool.poetry] +{% elif pdm %}[project] +{% endif %} name = "{{ project_name }}" version = "{{ package_version }}" description = "{{ package_description }}" - authors = [] - readme = "README.md" +{% if pdm %}requires-python = ">=3.8,<4.0"{% endif %} +{% if poetry %} packages = [ {include = "{{ package_name }}"}, ] include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] +{% endif %} +{% if pdm %} +dependencies = [ + "httpx>=0.20.0,<0.27.0", + "attrs>=21.3.0", + "python-dateutil>=2.8.0", +] + +[tool.pdm] +package-type = "library" +{% endif %} +{% if poetry %} [tool.poetry.dependencies] python = "^3.8" httpx = ">=0.20.0,<0.27.0" attrs = ">=21.3.0" python-dateutil = "^2.8.0" +{% endif %} [build-system] +{% if poetry %} requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" - +{% elif pdm %} +requires = ["pdm-backend"] +build-backend = "pdm.backend" {% endif %} -{% include "pyproject_no_poetry.toml.jinja" %} +{% endif %}{# poetry or pdm #} + +{% include "pyproject_ruff.toml.jinja" %} diff --git a/openapi_python_client/templates/pyproject_no_poetry.toml.jinja b/openapi_python_client/templates/pyproject_ruff.toml.jinja similarity index 100% rename from openapi_python_client/templates/pyproject_no_poetry.toml.jinja rename to openapi_python_client/templates/pyproject_ruff.toml.jinja diff --git a/pyproject.toml b/pyproject.toml index 9dfd5d92d..3a859aff5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,7 @@ composite = ["unit_tests --cov openapi_python_client tests --cov-report=term-mis [tool.pdm.scripts.regen_integration] shell = """ -openapi-python-client update --url https://raw.githubusercontent.com/openapi-generators/openapi-test-server/main/openapi.json --config integration-tests-config.yaml\ +openapi-python-client update --url https://raw.githubusercontent.com/openapi-generators/openapi-test-server/main/openapi.json --config integration-tests-config.yaml --meta pdm \ && mypy integration-tests --strict """ From ee20bbd6d3d22e77ce114b690561f856b8cce02f Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Mon, 1 Jan 2024 12:01:11 -0700 Subject: [PATCH 03/12] Delete some mock tests for metadata --- tests/test___init__.py | 122 ----------------------------------------- 1 file changed, 122 deletions(-) diff --git a/tests/test___init__.py b/tests/test___init__.py index 0fa243611..e1e701127 100644 --- a/tests/test___init__.py +++ b/tests/test___init__.py @@ -429,128 +429,6 @@ def test_update_missing_dir(self, mocker: MockFixture): project.package_dir.is_dir.assert_called_once() project._build_models.assert_not_called() - def test__build_metadata_poetry(self, mocker): - project = make_project() - project._build_pyproject_toml = mocker.MagicMock() - project.project_dir = mocker.MagicMock() - readme_path = mocker.MagicMock(autospec=pathlib.Path) - git_ignore_path = mocker.MagicMock(autospec=pathlib.Path) - paths = { - "README.md": readme_path, - ".gitignore": git_ignore_path, - } - project.project_dir.__truediv__.side_effect = lambda x: paths[x] - - readme_template = mocker.MagicMock(autospec=jinja2.Template) - git_ignore_template = mocker.MagicMock(autospec=jinja2.Template) - project.env = mocker.MagicMock(autospec=jinja2.Environment) - templates = { - "README.md.jinja": readme_template, - ".gitignore.jinja": git_ignore_template, - } - project.env.get_template.side_effect = lambda x: templates[x] - - project._build_metadata() - - project.env.get_template.assert_has_calls([mocker.call("README.md.jinja"), mocker.call(".gitignore.jinja")]) - readme_template.render.assert_called_once_with(poetry=True) - readme_path.write_text.assert_called_once_with(readme_template.render(), encoding="utf-8") - git_ignore_template.render.assert_called_once() - git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding="utf-8") - project._build_pyproject_toml.assert_called_once_with(use_poetry=True) - - def test__build_metadata_setup(self, mocker): - from openapi_python_client import MetaType - - project = make_project(meta=MetaType.SETUP) - project._build_pyproject_toml = mocker.MagicMock() - project._build_setup_py = mocker.MagicMock() - project.project_dir = mocker.MagicMock() - readme_path = mocker.MagicMock(autospec=pathlib.Path) - git_ignore_path = mocker.MagicMock(autospec=pathlib.Path) - paths = { - "README.md": readme_path, - ".gitignore": git_ignore_path, - } - project.project_dir.__truediv__.side_effect = lambda x: paths[x] - - readme_template = mocker.MagicMock(autospec=jinja2.Template) - git_ignore_template = mocker.MagicMock(autospec=jinja2.Template) - project.env = mocker.MagicMock(autospec=jinja2.Environment) - templates = { - "README.md.jinja": readme_template, - ".gitignore.jinja": git_ignore_template, - } - project.env.get_template.side_effect = lambda x: templates[x] - - project._build_metadata() - - project.env.get_template.assert_has_calls([mocker.call("README.md.jinja"), mocker.call(".gitignore.jinja")]) - readme_template.render.assert_called_once_with(poetry=False) - readme_path.write_text.assert_called_once_with(readme_template.render(), encoding="utf-8") - git_ignore_template.render.assert_called_once() - git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding="utf-8") - project._build_pyproject_toml.assert_called_once_with(use_poetry=False) - project._build_setup_py.assert_called_once() - - def test__build_metadata_none(self, mocker): - from openapi_python_client import MetaType - - project = make_project(meta=MetaType.NONE) - project._build_pyproject_toml = mocker.MagicMock() - - project._build_metadata() - - project._build_pyproject_toml.assert_not_called() - - @pytest.mark.parametrize("use_poetry", [(True,), (False,)]) - def test__build_pyproject_toml(self, mocker, use_poetry): - project = make_project() - project.project_dir = mocker.MagicMock() - pyproject_path = mocker.MagicMock(autospec=pathlib.Path) - paths = { - "pyproject.toml": pyproject_path, - } - project.project_dir.__truediv__.side_effect = lambda x: paths[x] - - pyproject_template = mocker.MagicMock(autospec=jinja2.Template) - project.env = mocker.MagicMock(autospec=jinja2.Environment) - template_path = "pyproject.toml.jinja" - templates = { - template_path: pyproject_template, - } - project.env.get_template.side_effect = lambda x: templates[x] - - project._build_pyproject_toml(use_poetry=use_poetry) - - project.env.get_template.assert_called_once_with(template_path) - - pyproject_template.render.assert_called_once_with(use_poetry=use_poetry) - pyproject_path.write_text.assert_called_once_with(pyproject_template.render(), encoding="utf-8") - - def test__build_setup_py(self, mocker): - project = make_project() - project.project_dir = mocker.MagicMock() - setup_path = mocker.MagicMock(autospec=pathlib.Path) - paths = { - "setup.py": setup_path, - } - project.project_dir.__truediv__.side_effect = lambda x: paths[x] - - setup_template = mocker.MagicMock(autospec=jinja2.Template) - project.env = mocker.MagicMock(autospec=jinja2.Environment) - templates = { - "setup.py.jinja": setup_template, - } - project.env.get_template.side_effect = lambda x: templates[x] - - project._build_setup_py() - - project.env.get_template.assert_called_once_with("setup.py.jinja") - - setup_template.render.assert_called_once_with() - setup_path.write_text.assert_called_once_with(setup_template.render(), encoding="utf-8") - def test__run_post_hooks_reports_missing_commands(self, project_with_dir): fake_command_name = "blahblahdoesntexist" project_with_dir.config.post_hooks = [fake_command_name] From 6ee35fe3fdc904aeb7337c8445409981dd833c1a Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Mon, 1 Jan 2024 12:13:35 -0700 Subject: [PATCH 04/12] ci: fix tests --- .github/workflows/checks.yml | 4 ++-- pyproject.toml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 46c53429a..d4d50c8be 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -53,13 +53,13 @@ jobs: - name: Run pytest without coverage if: matrix.os != 'ubuntu-latest' - run: pdm unit_tests + run: pdm test env: TASKIPY: true - name: Run pytest with coverage if: matrix.os == 'ubuntu-latest' - run: pdm unit_tests_with_coverage + run: pdm test_with_coverage env: TASKIPY: true diff --git a/pyproject.toml b/pyproject.toml index 3a859aff5..cfbe682de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,21 +66,21 @@ lint = "ruff check --fix ." format = "ruff format ." safety_check = { shell = "pdm export -o requirements.txt && safety check -r requirements.txt --bare && rm requirements.txt" } mypy = "mypy openapi_python_client" -check = { composite = ["lint", "format", "safety_check", "mypy", "unit_tests_with_coverage"] } +check = { composite = ["lint", "format", "safety_check", "mypy", "test_with_coverage"] } regen = {composite = ["regen_e2e", "regen_integration"]} e2e = "pytest openapi_python_client end_to_end_tests/test_end_to_end.py" re = {composite = ["regen_e2e", "e2e"]} regen_e2e = "python -m end_to_end_tests.regen_golden_record" -[tool.pdm.scripts.unit_tests] -cmd = "pytest --basetemp=tests/tmp" -[tool.pdm.scripts.unit_tests.env] +[tool.pdm.scripts.test] +cmd = "pytest tests --basetemp=tests/tmp" +[tool.pdm.scripts.test.env] "TEST_RELATIVE" = "true" -[tool.pdm.scripts.post_unit_tests] +[tool.pdm.scripts.post_test] cmd = "rm -r tests/tmp" -[tool.pdm.scripts.unit_tests_with_coverage] +[tool.pdm.scripts.test_with_coverage] composite = ["unit_tests --cov openapi_python_client tests --cov-report=term-missing"] [tool.pdm.scripts.regen_integration] From 23df552b707cd1aebe31d3014efa963a125038ae Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Mon, 1 Jan 2024 12:18:01 -0700 Subject: [PATCH 05/12] ci: fix tests --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cfbe682de..4ccffa2f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,7 +81,7 @@ cmd = "pytest tests --basetemp=tests/tmp" cmd = "rm -r tests/tmp" [tool.pdm.scripts.test_with_coverage] -composite = ["unit_tests --cov openapi_python_client tests --cov-report=term-missing"] +composite = ["test --cov openapi_python_client tests --cov-report=term-missing"] [tool.pdm.scripts.regen_integration] shell = """ From 522212be1e36f9a7d045ac663e3c86b3c2efaa8f Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Mon, 1 Jan 2024 12:18:11 -0700 Subject: [PATCH 06/12] ci: update Release workflow --- .github/workflows/release.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e30d82bf8..b9b9919a8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,8 @@ jobs: release: if: github.head_ref == 'release' && github.event.pull_request.merged == true runs-on: ubuntu-latest + permissions: + id-token: write steps: - uses: actions/checkout@v4.1.1 with: @@ -18,10 +20,10 @@ jobs: uses: knope-dev/action@v2.0.0 with: version: 0.13.3 - - name: Install Poetry - run: pip install --upgrade poetry + - name: Install PDM + run: pip install --upgrade pdm - name: Push to PyPI - run: poetry publish --build -u __token__ -p ${{ secrets.PYPI_TOKEN }} + run: pdm publish - name: Create GitHub Release run: knope release env: From e49ed352745ef42b01051c6cf0b12430bb9ef3a8 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Mon, 1 Jan 2024 12:32:52 -0700 Subject: [PATCH 07/12] docs: Update README with new `--meta` option --- README.md | 11 ++++--- openapi_python_client/cli.py | 2 +- usage.md | 63 ------------------------------------ 3 files changed, 7 insertions(+), 69 deletions(-) delete mode 100644 usage.md diff --git a/README.md b/README.md index fd3dda92a..2c5d0b0b4 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ This tool focuses on creating the best developer experience for Python developer I recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don't conflict with any other packages you might have: `pipx install openapi-python-client --include-deps`. -> Note the `--include-deps` option which will also make `black` and `ruff` available in your path so that `openapi-python-client` can use them to clean up the generated code. +> Note the `--include-deps` option makes `ruff` available in your path so that `openapi-python-client` can use it to clean up the generated code. **If you use `pipx run` then the post-generation hooks will not be available unless you install them manually.** @@ -52,8 +52,6 @@ If you have an `openapi.json` file available on disk, in any CLI invocation you `openapi-python-client update --url https://my.api.com/openapi.json` -> For more usage details run `openapi-python-client --help` or read [usage](usage.md) - ### Using custom templates This feature leverages Jinja2's [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance, @@ -68,7 +66,7 @@ _Be forewarned, this is a beta-level feature in the sense that the API exposed i ## What You Get -1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry]. +1. A `pyproject.toml` file, optionally with [Poetry] metadata (default), [PDM] (with `--meta=pdm`), or only [Ruff] config. 2. A `README.md` you'll most definitely need to update with your project's details 3. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains: 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You'll need these @@ -76,6 +74,7 @@ _Be forewarned, this is a beta-level feature in the sense that the API exposed i 2. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint. 3. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec +4. A `setup.py` file _if_ you use `--meta=setup` (default is `--meta=poetry`) For a full example you can look at the `end_to_end_tests` directory which has `baseline_openapi_3.0.json` and `baseline_openapi_3.1.yaml` files. The "golden-record" in that same directory is the generated client from either of those OpenAPI documents. @@ -137,7 +136,7 @@ package_version_override: 1.2.3 ### post_hooks -In the config file, there's an easy way to tell `openapi-python-client` to run additional commands after generation. Here's an example showing the default commands that will run if you don't override them in config: +In the config file, there's an easy way to tell `openapi-python-client` to run additional commands after generation. Here's an example showing the default commands (using [Ruff]) that will run if you don't override them in config: ```yaml post_hooks: @@ -159,3 +158,5 @@ By default, the timeout for retrieving the schema file via HTTP is 5 seconds. In [changelog.md]: CHANGELOG.md [poetry]: https://python-poetry.org/ +[PDM]: https://pdm-project.org/latest/ +[Ruff]: https://docs.astral.sh/ruff/ diff --git a/openapi_python_client/cli.py b/openapi_python_client/cli.py index 92d3ae3df..94c8e0bab 100644 --- a/openapi_python_client/cli.py +++ b/openapi_python_client/cli.py @@ -37,7 +37,7 @@ def _process_config(path: Optional[pathlib.Path]) -> Config: def cli( version: bool = typer.Option(False, "--version", callback=_version_callback, help="Print the version and exit"), ) -> None: - """Generate a Python client from an OpenAPI JSON document""" + """Generate a Python client from an OpenAPI document""" def _print_parser_error(err: GeneratorError, color: str) -> None: diff --git a/usage.md b/usage.md deleted file mode 100644 index 61803ce0a..000000000 --- a/usage.md +++ /dev/null @@ -1,63 +0,0 @@ -# `openapi-python-client` - -Generate a Python client from an OpenAPI JSON document - -**Usage**: - -```console -$ openapi-python-client [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -- `--version`: Print the version and exit [default: False] -- `--install-completion`: Install completion for the current shell. -- `--show-completion`: Show completion for the current shell, to copy it or customize the installation. -- `--help`: Show this message and exit. - -**Commands**: - -- `generate`: Generate a new OpenAPI Client library -- `update`: Update an existing OpenAPI Client library - -## `openapi-python-client generate` - -Generate a new OpenAPI Client library - -**Usage**: - -```console -$ openapi-python-client generate [OPTIONS] -``` - -**Options**: - -- `--url TEXT`: A URL to read the JSON from -- `--path PATH`: A path to the JSON file -- `--custom-template-path DIRECTORY`: A path to a directory containing custom template(s) -- `--meta [none|poetry|setup]`: The type of metadata you want to generate. [default: poetry] -- `--file-encoding TEXT`: Encoding used when writing generated [default: utf-8] -- `--config PATH`: Path to the config file to use -- `--help`: Show this message and exit. - -## `openapi-python-client update` - -Update an existing OpenAPI Client library - -> **Note:** The `update` command performs the same operations as `generate` except it does not overwrite specific metadata for the generated client such as the `README.md`, `.gitignore`, and `pyproject.toml`. - -**Usage**: - -```console -$ openapi-python-client update [OPTIONS] -``` - -**Options**: - -- `--url TEXT`: A URL to read the JSON from -- `--path PATH`: A path to the JSON file -- `--custom-template-path DIRECTORY`: A path to a directory containing custom template(s) -- `--meta [none|poetry|setup]`: The type of metadata you want to generate. [default: poetry] -- `--file-encoding TEXT`: Encoding used when writing generated [default: utf-8] -- `--config PATH`: Path to the config file to use -- `--help`: Show this message and exit. From a476bfbc2bd5e11afff576bd8fec237e0d7cf99a Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Thu, 4 Jan 2024 16:55:27 -0700 Subject: [PATCH 08/12] Always run e2e tests --- end_to_end_tests/test_end_to_end.py | 2 +- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/end_to_end_tests/test_end_to_end.py b/end_to_end_tests/test_end_to_end.py index 084a10068..334ddd95b 100644 --- a/end_to_end_tests/test_end_to_end.py +++ b/end_to_end_tests/test_end_to_end.py @@ -26,7 +26,7 @@ def _compare_directories( """ first_printable = record.relative_to(Path.cwd()) second_printable = test_subject.relative_to(Path.cwd()) - dc = dircmp(record, test_subject, ignore=[".ruff_cache"]) + dc = dircmp(record, test_subject, ignore=[".ruff_cache", "__pycache__"]) missing_files = dc.left_only + dc.right_only if missing_files: pytest.fail( diff --git a/pyproject.toml b/pyproject.toml index b12f25756..e566804b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,14 +66,14 @@ lint = "ruff check --fix ." format = "ruff format ." safety_check = { shell = "pdm export -o requirements.txt && safety check -r requirements.txt --bare && rm requirements.txt" } mypy = "mypy openapi_python_client" -check = { composite = ["lint", "format", "safety_check", "mypy", "test_with_coverage"] } +check = { composite = ["lint", "format", "safety_check", "mypy", "test"] } regen = {composite = ["regen_e2e", "regen_integration"]} e2e = "pytest openapi_python_client end_to_end_tests/test_end_to_end.py" re = {composite = ["regen_e2e", "e2e"]} regen_e2e = "python -m end_to_end_tests.regen_golden_record" [tool.pdm.scripts.test] -cmd = "pytest tests --basetemp=tests/tmp" +cmd = "pytest tests end_to_end_tests/test_end_to_end.py --basetemp=tests/tmp" [tool.pdm.scripts.test.env] "TEST_RELATIVE" = "true" From 2680f1160f268c684a1e3e5092bde7877ce04d9f Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Thu, 4 Jan 2024 17:06:22 -0700 Subject: [PATCH 09/12] Add back trove classifiers --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index e566804b4..fc79e4ed3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,14 @@ keywords = [ ] classifiers = [ "Development Status :: 4 - Beta", + "License :: OSI Approved :: MIT License", "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Software Development :: Code Generators", "Typing :: Typed", ] From a3673317d72db99349b71b5f009ed84b30244126 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Thu, 4 Jan 2024 17:38:19 -0700 Subject: [PATCH 10/12] Use hatchling to build (excludes folders properly) --- .github/workflows/release.yml | 8 ++- pdm.lock | 2 +- pyproject.toml | 100 ++++++++++++++++++---------------- 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b9b9919a8..0207a50d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,10 +20,12 @@ jobs: uses: knope-dev/action@v2.0.0 with: version: 0.13.3 - - name: Install PDM - run: pip install --upgrade pdm + - name: Install Hatchling + run: pip install --upgrade hatchling + - name: Build + run: hatchling build - name: Push to PyPI - run: pdm publish + uses: pypa/gh-action-pypi-publish@v1.8.11 - name: Create GitHub Release run: knope release env: diff --git a/pdm.lock b/pdm.lock index d652aa102..722bef1cf 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:ff6eaafd9ff6cd5a3a9881deb8812fa7d2125e20dbd14ce2c2921a182a30c54a" +content_hash = "sha256:60ab2ae5a39b0ce8036a10b02c9edd020a4319fc3223d7c4d4983621076c3858" [[package]] name = "annotated-types" diff --git a/pyproject.toml b/pyproject.toml index fc79e4ed3..c681b38a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,17 +5,17 @@ authors = [ license = { text = "MIT" } requires-python = ">=3.8,<4.0" dependencies = [ - "jinja2<4.0.0,>=3.0.0", - "typer<0.10,>0.6", - "colorama<1.0.0,>=0.4.3; sys_platform == \"win32\"", - "shellingham<2.0.0,>=1.3.2", - "pydantic<3.0.0,>=2.1.1", + "jinja2>=3.0.0,<4.0.0", + "typer>0.6,<0.10", + "colorama>=0.4.3; sys_platform == \"win32\"", + "shellingham>=1.3.2,<2.0.0", + "pydantic>=2.1.1,<3.0.0", "attrs>=21.3.0", - "python-dateutil<3.0.0,>=2.8.1", + "python-dateutil>=2.8.1,<3.0.0", "httpx>=0.20.0,<0.27.0", - "PyYAML<7.0,>=6.0", - "ruff<1.0.0,>=0.1.2", - "typing-extensions<5.0.0,>=4.8.0", + "PyYAML>=6.0,<7.0", + "ruff>=0.1.2,<1.0.0", + "typing-extensions>=4.8.0,<5.0.0", ] name = "openapi-python-client" version = "0.17.1" @@ -46,7 +46,43 @@ repository = "https://github.com/openapi-generators/openapi-python-client" [project.scripts] openapi-python-client = "openapi_python_client.cli:app" -[tool.pdm] +[tool.ruff] +select = ["E", "F", "I", "UP", "B", "PL", "RUF"] +line-length = 120 +exclude = [ + ".git", + ".mypy_cache", + ".venv", + "openapi_python_client/templates/*", + "end_to_end_tests/*", + "tests/test_templates/*", +] +ignore = ["E501", "PLR0913"] + +[tool.ruff.per-file-ignores] +"openapi_python_client/cli.py" = ["B008"] + +[tool.coverage.run] +omit = ["openapi_python_client/templates/*"] + +[tool.mypy] +plugins = ["pydantic.mypy"] +disallow_any_generics = true +disallow_untyped_defs = true +warn_redundant_casts = true +strict_equality = true + +[[tool.mypy.overrides]] +module = [ + "importlib_metadata", + "typer", +] +ignore_missing_imports = true + +[tool.pytest.ini_options] +junit_family = "xunit2" + + [tool.pdm.dev-dependencies] dev = [ "pytest", @@ -96,42 +132,12 @@ openapi-python-client update --url https://raw.githubusercontent.com/openapi-gen && mypy integration-tests --strict """ -[tool.ruff] -select = ["E", "F", "I", "UP", "B", "PL", "RUF"] -line-length = 120 -exclude = [ - ".git", - ".mypy_cache", - ".venv", - "openapi_python_client/templates/*", - "end_to_end_tests/*", - "tests/test_templates/*", -] -ignore = ["E501", "PLR0913"] - -[tool.ruff.per-file-ignores] -"openapi_python_client/cli.py" = ["B008"] - -[tool.coverage.run] -omit = ["openapi_python_client/templates/*"] - -[tool.mypy] -plugins = ["pydantic.mypy"] -disallow_any_generics = true -disallow_untyped_defs = true -warn_redundant_casts = true -strict_equality = true +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" -[[tool.mypy.overrides]] -module = [ - "importlib_metadata", - "typer", +[tool.hatch.build.targets.sdist] +include = [ + "openapi_python_client", ] -ignore_missing_imports = true - -[tool.pytest.ini_options] -junit_family = "xunit2" - -[build-system] -requires = ["pdm-backend"] -build-backend = "pdm.backend" +exclude = [".gitignore"] From 84487b047dc475a8d713276aef4c3298997cbe30 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Thu, 4 Jan 2024 18:15:29 -0700 Subject: [PATCH 11/12] Add snapshot tests for metadata types --- end_to_end_tests/golden-record/pyproject.toml | 1 + .../metadata_snapshots/pdm.pyproject.toml | 23 +++++++ .../metadata_snapshots/poetry.pyproject.toml | 25 ++++++++ end_to_end_tests/metadata_snapshots/setup.py | 18 ++++++ end_to_end_tests/regen_golden_record.py | 21 +++++++ .../test-3-1-golden-record/pyproject.toml | 1 + end_to_end_tests/test_end_to_end.py | 62 ++++++++++++++----- .../templates/pyproject.toml.jinja | 1 + 8 files changed, 138 insertions(+), 14 deletions(-) create mode 100644 end_to_end_tests/metadata_snapshots/pdm.pyproject.toml create mode 100644 end_to_end_tests/metadata_snapshots/poetry.pyproject.toml create mode 100644 end_to_end_tests/metadata_snapshots/setup.py diff --git a/end_to_end_tests/golden-record/pyproject.toml b/end_to_end_tests/golden-record/pyproject.toml index 6c57de7f0..a82e01809 100644 --- a/end_to_end_tests/golden-record/pyproject.toml +++ b/end_to_end_tests/golden-record/pyproject.toml @@ -9,6 +9,7 @@ packages = [ ] include = ["CHANGELOG.md", "my_test_api_client/py.typed"] + [tool.poetry.dependencies] python = "^3.8" httpx = ">=0.20.0,<0.27.0" diff --git a/end_to_end_tests/metadata_snapshots/pdm.pyproject.toml b/end_to_end_tests/metadata_snapshots/pdm.pyproject.toml new file mode 100644 index 000000000..31f84cb5b --- /dev/null +++ b/end_to_end_tests/metadata_snapshots/pdm.pyproject.toml @@ -0,0 +1,23 @@ +[project] +name = "test-3-1-features-client" +version = "0.1.0" +description = "A client library for accessing Test 3.1 Features" +authors = [] +readme = "README.md" +requires-python = ">=3.8,<4.0" +dependencies = [ + "httpx>=0.20.0,<0.27.0", + "attrs>=21.3.0", + "python-dateutil>=2.8.0", +] + +[tool.pdm] +package-type = "library" + +[build-system] +requires = ["pdm-backend"] +build-backend = "pdm.backend" + +[tool.ruff] +select = ["F", "I"] +line-length = 120 diff --git a/end_to_end_tests/metadata_snapshots/poetry.pyproject.toml b/end_to_end_tests/metadata_snapshots/poetry.pyproject.toml new file mode 100644 index 000000000..4e409e422 --- /dev/null +++ b/end_to_end_tests/metadata_snapshots/poetry.pyproject.toml @@ -0,0 +1,25 @@ +[tool.poetry] +name = "test-3-1-features-client" +version = "0.1.0" +description = "A client library for accessing Test 3.1 Features" +authors = [] +readme = "README.md" +packages = [ + {include = "test_3_1_features_client"}, +] +include = ["CHANGELOG.md", "test_3_1_features_client/py.typed"] + + +[tool.poetry.dependencies] +python = "^3.8" +httpx = ">=0.20.0,<0.27.0" +attrs = ">=21.3.0" +python-dateutil = "^2.8.0" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.ruff] +select = ["F", "I"] +line-length = 120 diff --git a/end_to_end_tests/metadata_snapshots/setup.py b/end_to_end_tests/metadata_snapshots/setup.py new file mode 100644 index 000000000..6826d63a3 --- /dev/null +++ b/end_to_end_tests/metadata_snapshots/setup.py @@ -0,0 +1,18 @@ +import pathlib + +from setuptools import find_packages, setup + +here = pathlib.Path(__file__).parent.resolve() +long_description = (here / "README.md").read_text(encoding="utf-8") + +setup( + name="test-3-1-features-client", + version="0.1.0", + description="A client library for accessing Test 3.1 Features", + long_description=long_description, + long_description_content_type="text/markdown", + packages=find_packages(), + python_requires=">=3.8, <4", + install_requires=["httpx >= 0.20.0, < 0.27.0", "attrs >= 21.3.0", "python-dateutil >= 2.8.0, < 3"], + package_data={"test_3_1_features_client": ["py.typed"]}, +) diff --git a/end_to_end_tests/regen_golden_record.py b/end_to_end_tests/regen_golden_record.py index 7391ed093..641c183ae 100644 --- a/end_to_end_tests/regen_golden_record.py +++ b/end_to_end_tests/regen_golden_record.py @@ -51,6 +51,26 @@ def regen_golden_record_3_1_features(): output_path.rename(gr_path) +def regen_metadata_snapshots(): + runner = CliRunner() + openapi_path = Path(__file__).parent / "3.1_specific.openapi.yaml" + output_path = Path.cwd() / "test-3-1-features-client" + snapshots_dir = Path(__file__).parent / "metadata_snapshots" + + for (meta, file, rename_to) in (("setup", "setup.py", "setup.py"), ("pdm", "pyproject.toml", "pdm.pyproject.toml"), ("poetry", "pyproject.toml", "poetry.pyproject.toml")): + shutil.rmtree(output_path, ignore_errors=True) + result = runner.invoke(app, ["generate", f"--path={openapi_path}", f"--meta={meta}"]) + + if result.stdout: + print(result.stdout) + if result.exception: + raise result.exception + + (output_path / file).rename(snapshots_dir / rename_to) + + shutil.rmtree(output_path, ignore_errors=True) + + def regen_custom_template_golden_record(): runner = CliRunner() openapi_path = Path(__file__).parent / "baseline_openapi_3.0.json" @@ -104,4 +124,5 @@ def regen_custom_template_golden_record(): if __name__ == "__main__": regen_golden_record() regen_golden_record_3_1_features() + regen_metadata_snapshots() regen_custom_template_golden_record() diff --git a/end_to_end_tests/test-3-1-golden-record/pyproject.toml b/end_to_end_tests/test-3-1-golden-record/pyproject.toml index db26ff221..4e409e422 100644 --- a/end_to_end_tests/test-3-1-golden-record/pyproject.toml +++ b/end_to_end_tests/test-3-1-golden-record/pyproject.toml @@ -9,6 +9,7 @@ packages = [ ] include = ["CHANGELOG.md", "test_3_1_features_client/py.typed"] + [tool.poetry.dependencies] python = "^3.8" httpx = ">=0.20.0,<0.27.0" diff --git a/end_to_end_tests/test_end_to_end.py b/end_to_end_tests/test_end_to_end.py index 334ddd95b..8b61f8d8d 100644 --- a/end_to_end_tests/test_end_to_end.py +++ b/end_to_end_tests/test_end_to_end.py @@ -1,7 +1,7 @@ import shutil from filecmp import cmpfiles, dircmp from pathlib import Path -from typing import Dict, List +from typing import Dict, List, Optional, Tuple import pytest from typer.testing import CliRunner @@ -13,6 +13,7 @@ def _compare_directories( record: Path, test_subject: Path, expected_differences: Dict[Path, str], + ignore: List[str] = None, depth=0, ): """ @@ -26,7 +27,7 @@ def _compare_directories( """ first_printable = record.relative_to(Path.cwd()) second_printable = test_subject.relative_to(Path.cwd()) - dc = dircmp(record, test_subject, ignore=[".ruff_cache", "__pycache__"]) + dc = dircmp(record, test_subject, ignore=[".ruff_cache", "__pycache__"] + (ignore or [])) missing_files = dc.left_only + dc.right_only if missing_files: pytest.fail( @@ -59,6 +60,7 @@ def _compare_directories( record / sub_path, test_subject / sub_path, expected_differences=expected_differences, + ignore=ignore, depth=depth + 1, ) @@ -79,20 +81,10 @@ def run_e2e_test( golden_record_path: str = "golden-record", output_path: str = "my-test-api-client", ): - runner = CliRunner() - openapi_path = Path(__file__).parent / openapi_document - config_path = Path(__file__).parent / "config.yml" - gr_path = Path(__file__).parent / golden_record_path output_path = Path.cwd() / output_path shutil.rmtree(output_path, ignore_errors=True) - - args = ["generate", f"--config={config_path}", f"--path={openapi_path}"] - if extra_args: - args.extend(extra_args) - result = runner.invoke(app, args) - - if result.exit_code != 0: - raise result.exception + generate(extra_args, openapi_document) + gr_path = Path(__file__).parent / golden_record_path # Use absolute paths for expected differences for easier comparisons expected_differences = { @@ -110,6 +102,18 @@ def run_e2e_test( shutil.rmtree(output_path) +def generate(extra_args: Optional[List[str]], openapi_document: str): + """Generate a client from an OpenAPI document and return the path to the generated code""" + runner = CliRunner() + openapi_path = Path(__file__).parent / openapi_document + config_path = Path(__file__).parent / "config.yml" + args = ["generate", f"--config={config_path}", f"--path={openapi_path}"] + if extra_args: + args.extend(extra_args) + result = runner.invoke(app, args) + if result.exit_code != 0: + raise result.exception + def test_baseline_end_to_end_3_0(): run_e2e_test("baseline_openapi_3.0.json", [], {}) @@ -128,6 +132,36 @@ def test_3_1_specific_features(): ) +@pytest.mark.parametrize( + "meta,generated_file,expected_file", + ( + ("setup", "setup.py", "setup.py"), + ("pdm", "pyproject.toml", "pdm.pyproject.toml"), + ("poetry", "pyproject.toml", "poetry.pyproject.toml"), + ) +) +def test_meta(meta: str, generated_file: Optional[str], expected_file: Optional[str]): + output_path = Path.cwd() / "test-3-1-features-client" + shutil.rmtree(output_path, ignore_errors=True) + generate([f"--meta={meta}"], "3.1_specific.openapi.yaml") + + if generated_file and expected_file: + assert (output_path / generated_file).exists() + assert (output_path / generated_file).read_text() == (Path(__file__).parent / "metadata_snapshots" / expected_file).read_text() + + shutil.rmtree(output_path) + + +def test_no_meta(): + output_path = Path.cwd() / "test_3_1_features_client" + shutil.rmtree(output_path, ignore_errors=True) + generate([f"--meta=none"], "3.1_specific.openapi.yaml") + + assert output_path.exists() # Has a different name than with-meta generation + assert (output_path / "__init__.py").exists() + shutil.rmtree(output_path) + + def test_custom_templates(): expected_differences = ( {} diff --git a/openapi_python_client/templates/pyproject.toml.jinja b/openapi_python_client/templates/pyproject.toml.jinja index 0ff9e133e..fced0e8bd 100644 --- a/openapi_python_client/templates/pyproject.toml.jinja +++ b/openapi_python_client/templates/pyproject.toml.jinja @@ -16,6 +16,7 @@ packages = [ ] include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] {% endif %} + {% if pdm %} dependencies = [ "httpx>=0.20.0,<0.27.0", From 9403ca517dfaaddccdd3ad326de9826bf1738aa5 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Fri, 5 Jan 2024 16:11:38 -0700 Subject: [PATCH 12/12] Document PDM changes --- ...etapdm_option_for_generating_pep621_pdm_metadata.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changeset/add_metapdm_option_for_generating_pep621_pdm_metadata.md diff --git a/.changeset/add_metapdm_option_for_generating_pep621_pdm_metadata.md b/.changeset/add_metapdm_option_for_generating_pep621_pdm_metadata.md new file mode 100644 index 000000000..cbed8d823 --- /dev/null +++ b/.changeset/add_metapdm_option_for_generating_pep621_pdm_metadata.md @@ -0,0 +1,10 @@ +--- +default: minor +--- + +# Add `--meta=pdm` option for generating PEP621 + PDM metadata + +The default metadata is still `--meta=poetry`, which generates a `pyproject.toml` file with Poetry-specific metadata. +This change adds the `--meta=pdm` option which includes [PDM](https://pdm-project.org/latest/)-specific metadata, but also +standard [PEP621](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#writing-pyproject-toml) +metadata. This may be useful as a starting point for other dependency managers & build tools (like Hatch).