From b8d29ec6ae8e2b521092eda888f7bc6d7da55359 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Mon, 22 Sep 2025 12:45:16 -0400 Subject: [PATCH 01/25] Upgrade python version and tool versions + remove deprecated features (#46) Upgrades This updates the minimum supported version of python to 3.10 as 3.9 is end-of-life in October. With the upgrade, we now have access to pipe unions without having to import them from the __future__. I removed the __future__ annotations imports which required a little reorganizing of imports and also quoting some type hints. Going from 3.9 -> 3.10 as the target version for ruff and mypy had fewer changes than expected but those have been made here. I adjusted the minimum required versions of tqdm and duckdb with a better idea as to what a minimum version should be. Feature removals Removing psycopg2 in favor of psycopg3 requires a little more setup documentation. There were also changes in tests necessary because of the return type mapping is different. Excel export has been removed, that also allowed removing the dependency. sqlite3 doesn't have json support which I will need to implement the faster transformation logic in 4.0 so it has also been removed. It ships with python so there wasn't a dependency to remove. There's probably some goofy logic now but the database handing code is going to be pretty heavily refactored --- .github/workflows/lint.yaml | 2 +- .github/workflows/test.yaml | 2 +- README.md | 7 + environment.yaml | 8 +- pylock.maximal.toml | 259 ++++++-------- pylock.minimal.toml | 591 +++++++++++++------------------- pylock.toml | 515 +++++++++++----------------- pyproject.toml | 87 +++-- src/ldlite/__init__.py | 100 +----- src/ldlite/_csv.py | 34 +- src/ldlite/_database.py | 7 +- src/ldlite/_folio.py | 9 +- src/ldlite/_jsonx.py | 17 +- src/ldlite/_select.py | 13 +- src/ldlite/_sqlx.py | 55 +-- src/ldlite/_xlsx.py | 87 ----- tests/README.md | 2 +- tests/test_cases/query_cases.py | 26 +- tests/test_duckdb.py | 2 +- tests/test_postgres.py | 33 +- tests/test_sqlite.py | 111 ------ 21 files changed, 676 insertions(+), 1291 deletions(-) delete mode 100644 src/ldlite/_xlsx.py delete mode 100644 tests/test_sqlite.py diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index b7feac4..88c0bbb 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -26,7 +26,7 @@ jobs: - uses: jaxxstorm/action-install-gh-release@v1.10.0 with: repo: houseabsolute/precious - tag: v0.9.0 + tag: v0.10.0 cache: enable # lint diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8b96a06..a49e391 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,7 +35,7 @@ jobs: # install dependencies - uses: pdm-project/setup-pdm@v4 with: - python-version: 3.9 + python-version: "3.10" cache: true cache-dependency-path: pylock.minimal.toml - run: pdm install -G:all --lockfile pylock.minimal.toml diff --git a/README.md b/README.md index 80c1741..a1bb937 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ LDLite supports two modes of usage. See the [Five Colleges Setup](https://github.com/Five-Colleges-Incorporated/ldlite-scripts) for an example of automating overnight data loads. +It is recommended to install the `psycopg[c]` package for optimal reliability and performance in a server context. + ### Usage for ad-hoc local querying To install LDLite or upgrade to the latest version: @@ -31,6 +33,11 @@ $ python -m pip install --upgrade ldlite (On some systems it might be `python3` rather than `python`.) Check out the [migration guide](./MIGRATING.md) for more information about major version upgrades. +*Optional* If you intend to use the `connect_db_postgres()` method install the binary provider: +``` +$ python -m pip install --upgrade psycopg[binary] +``` + To extract and transform data: ```python diff --git a/environment.yaml b/environment.yaml index 7629235..31a8402 100644 --- a/environment.yaml +++ b/environment.yaml @@ -4,7 +4,7 @@ channels: - conda-forge - nodefaults dependencies: - - python>=3.7,<3.10 - - pdm==2.25.4 - - postgresql>=17 - - precious==0.9.0 + - python>=3.10,<3.11 + - pdm==2.25.5 + - precious==0.10.0 + - libpq>=13.0 diff --git a/pylock.maximal.toml b/pylock.maximal.toml index ba50b76..3323bb4 100644 --- a/pylock.maximal.toml +++ b/pylock.maximal.toml @@ -1,7 +1,7 @@ # This file is @generated by PDM. # It is not intended for manual editing. lock-version = "1.0" -requires-python = ">=3.9" +requires-python = ">=3.10" environments = [ "python_version >= \"3.13\"", ] @@ -12,17 +12,23 @@ created-by = "pdm" [[packages]] name = "mypy" -version = "1.17.0" +version = "1.18.2" requires-python = ">=3.9" -sdist = {name = "mypy-1.17.0.tar.gz", url = "https://files.pythonhosted.org/packages/1e/e3/034322d5a779685218ed69286c32faa505247f1f096251ef66c8fd203b08/mypy-1.17.0.tar.gz", hashes = {sha256 = "e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03"}} -wheels = [ - {name = "mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/be/7b/5f8ab461369b9e62157072156935cec9d272196556bdc7c2ff5f4c7c0f9b/mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06"}}, - {name = "mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/9c/f8/c49c9e5a2ac0badcc54beb24e774d2499748302c9568f7f09e8730e953fa/mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a"}}, - {name = "mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/0c/fb3f9c939ad9beed3e328008b3fb90b20fda2cddc0f7e4c20dbefefc3b33/mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889"}}, - {name = "mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4c/66/85607ab5137d65e4f54d9797b77d5a038ef34f714929cf8ad30b03f628df/mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba"}}, - {name = "mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/d0/341dbbfb35ce53d01f8f2969facbb66486cee9804048bf6c01b048127501/mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658"}}, - {name = "mypy-1.17.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/63/70c8b7dbfc520089ac48d01367a97e8acd734f65bd07813081f508a8c94c/mypy-1.17.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c"}}, - {name = "mypy-1.17.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e3/fc/ee058cc4316f219078464555873e99d170bde1d9569abd833300dbeb484a/mypy-1.17.0-py3-none-any.whl",hashes = {sha256 = "15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496"}}, +sdist = {name = "mypy-1.18.2.tar.gz", url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hashes = {sha256 = "06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"}} +wheels = [ + {name = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"}}, + {name = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}}, + {name = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}}, + {name = "mypy-1.18.2-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl",hashes = {sha256 = "749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}}, + {name = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}}, + {name = "mypy-1.18.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}}, + {name = "mypy-1.18.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl",hashes = {sha256 = "22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}}, ] marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" @@ -36,11 +42,11 @@ dependencies = [ [[packages]] name = "pre-commit-hooks" -version = "5.0.0" -requires-python = ">=3.8" -sdist = {name = "pre_commit_hooks-5.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/ac/7d/3299241a753c738d114600c360d754550b28c285281dc6a5132c4ccfae65/pre_commit_hooks-5.0.0.tar.gz", hashes = {sha256 = "10626959a9eaf602fbfc22bc61b6e75801436f82326bfcee82bb1f2fc4bc646e"}} +version = "6.0.0" +requires-python = ">=3.9" +sdist = {name = "pre_commit_hooks-6.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/36/4d/93e63e48f8fd16d6c1e4cef5dabadcade4d1325c7fd6f29f075a4d2284f3/pre_commit_hooks-6.0.0.tar.gz", hashes = {sha256 = "76d8370c006f5026cdd638a397a678d26dda735a3c88137e05885a020f824034"}} wheels = [ - {name = "pre_commit_hooks-5.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1e/29/db1d855a661c02dbde5cab3057969133fcc62e7a0c6393e48fe9d0e81679/pre_commit_hooks-5.0.0-py2.py3-none-any.whl",hashes = {sha256 = "8d71cfb582c5c314a5498d94e0104b6567a8b93fb35903ea845c491f4e290a7a"}}, + {name = "pre_commit_hooks-6.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/12/46/eba9be9daa403fa94854ce16a458c29df9a01c6c047931c3d8be6016cd9a/pre_commit_hooks-6.0.0-py2.py3-none-any.whl",hashes = {sha256 = "76161b76d321d2f8ee2a8e0b84c30ee8443e01376121fd1c90851e33e3bd7ee2"}}, ] marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" @@ -52,27 +58,28 @@ dependencies = [ [[packages]] name = "ruff" -version = "0.12.5" +version = "0.13.1" requires-python = ">=3.7" -sdist = {name = "ruff-0.12.5.tar.gz", url = "https://files.pythonhosted.org/packages/30/cd/01015eb5034605fd98d829c5839ec2c6b4582b479707f7c1c2af861e8258/ruff-0.12.5.tar.gz", hashes = {sha256 = "b209db6102b66f13625940b7f8c7d0f18e20039bb7f6101fbdac935c9612057e"}} -wheels = [ - {name = "ruff-0.12.5-py3-none-linux_armv6l.whl",url = "https://files.pythonhosted.org/packages/d4/de/ad2f68f0798ff15dd8c0bcc2889558970d9a685b3249565a937cd820ad34/ruff-0.12.5-py3-none-linux_armv6l.whl",hashes = {sha256 = "1de2c887e9dec6cb31fcb9948299de5b2db38144e66403b9660c9548a67abd92"}}, - {name = "ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/fc/c6b65cd0e7fbe60f17e7ad619dca796aa49fbca34bb9bea5f8faf1ec2643/ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl",hashes = {sha256 = "d1ab65e7d8152f519e7dea4de892317c9da7a108da1c56b6a3c1d5e7cf4c5e9a"}}, - {name = "ruff-0.12.5-py3-none-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/de/c6bec1dce5ead9f9e6a946ea15e8d698c35f19edc508289d70a577921b30/ruff-0.12.5-py3-none-macosx_11_0_arm64.whl",hashes = {sha256 = "962775ed5b27c7aa3fdc0d8f4d4433deae7659ef99ea20f783d666e77338b8cf"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/16/cf372d2ebe91e4eb5b82a2275c3acfa879e0566a7ac94d331ea37b765ac8/ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "73b4cae449597e7195a49eb1cdca89fd9fbb16140c7579899e87f4c85bf82f73"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/25/bf/cd07e8f6a3a6ec746c62556b4c4b79eeb9b0328b362bb8431b7b8afd3856/ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "8b13489c3dc50de5e2d40110c0cce371e00186b880842e245186ca862bf9a1ac"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/d8/c9/c2ccb3b8cbb5661ffda6925f81a13edbb786e623876141b04919d1128370/ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "f1504fea81461cf4841778b3ef0a078757602a3b3ea4b008feb1308cb3f23e08"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",url = "https://files.pythonhosted.org/packages/6b/58/68a5be2c8e5590ecdad922b2bcd5583af19ba648f7648f95c51c3c1eca81/ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",hashes = {sha256 = "c7da4129016ae26c32dfcbd5b671fe652b5ab7fc40095d80dcff78175e7eddd4"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/bd/d1/ef6b19622009ba8386fdb792c0743f709cf917b0b2f1400589cbe4739a33/ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "ca972c80f7ebcfd8af75a0f18b17c42d9f1ef203d163669150453f50ca98ab7b"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/62/e3/1c98c566fe6809a0c83751d825a03727f242cdbe0d142c9e292725585521/ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "8dbbf9f25dfb501f4237ae7501d6364b76a01341c6f1b2cd6764fe449124bb2a"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/24/ff/96058f6506aac0fbc0d0fc0d60b0d0bd746240a0594657a2d94ad28033ba/ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2c47dea6ae39421851685141ba9734767f960113d51e83fd7bb9958d5be8763a"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/d3/68bc5e7ab96c94b3589d1789f2dd6dd4b27b263310019529ac9be1e8f31b/ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c5076aa0e61e30f848846f0265c873c249d4b558105b221be1828f9f79903dc5"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/52/75/7356af30a14584981cabfefcf6106dea98cec9a7af4acb5daaf4b114845f/ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl",hashes = {sha256 = "a5a4c7830dadd3d8c39b1cc85386e2c1e62344f20766be6f173c22fb5f72f293"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c2/67/91c71d27205871737cae11025ee2b098f512104e26ffd8656fd93d0ada0a/ruff-0.12.5-py3-none-musllinux_1_2_i686.whl",hashes = {sha256 = "46699f73c2b5b137b9dc0fc1a190b43e35b008b398c6066ea1350cce6326adcb"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/04/b6b00383cf2f48e8e78e14eb258942fdf2a9bf0287fbf5cdd398b749193a/ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5a655a0a0d396f0f072faafc18ebd59adde8ca85fb848dc1b0d9f024b9c4d3bb"}}, - {name = "ruff-0.12.5-py3-none-win32.whl",url = "https://files.pythonhosted.org/packages/3e/b9/053d6445dc7544fb6594785056d8ece61daae7214859ada4a152ad56b6e0/ruff-0.12.5-py3-none-win32.whl",hashes = {sha256 = "dfeb2627c459b0b78ca2bbdc38dd11cc9a0a88bf91db982058b26ce41714ffa9"}}, - {name = "ruff-0.12.5-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bc/0f/ab16e8259493137598b9149734fec2e06fdeda9837e6f634f5c4e35916da/ruff-0.12.5-py3-none-win_amd64.whl",hashes = {sha256 = "ae0d90cf5f49466c954991b9d8b953bd093c32c27608e409ae3564c63c5306a5"}}, - {name = "ruff-0.12.5-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/00/db/c376b0661c24cf770cb8815268190668ec1330eba8374a126ceef8c72d55/ruff-0.12.5-py3-none-win_arm64.whl",hashes = {sha256 = "48cdbfc633de2c5c37d9f090ba3b352d1576b0015bfc3bc98eaf230275b7e805"}}, +sdist = {name = "ruff-0.13.1.tar.gz", url = "https://files.pythonhosted.org/packages/ab/33/c8e89216845615d14d2d42ba2bee404e7206a8db782f33400754f3799f05/ruff-0.13.1.tar.gz", hashes = {sha256 = "88074c3849087f153d4bb22e92243ad4c1b366d7055f98726bc19aa08dc12d51"}} +wheels = [ + {name = "ruff-0.13.1-py3-none-linux_armv6l.whl",url = "https://files.pythonhosted.org/packages/f3/41/ca37e340938f45cfb8557a97a5c347e718ef34702546b174e5300dbb1f28/ruff-0.13.1-py3-none-linux_armv6l.whl",hashes = {sha256 = "b2abff595cc3cbfa55e509d89439b5a09a6ee3c252d92020bd2de240836cf45b"}}, + {name = "ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/84/ba378ef4129415066c3e1c80d84e539a0d52feb250685091f874804f28af/ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",hashes = {sha256 = "4ee9f4249bf7f8bb3984c41bfaf6a658162cdb1b22e3103eabc7dd1dc5579334"}}, + {name = "ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8d/b6/ec5e4559ae0ad955515c176910d6d7c93edcbc0ed1a3195a41179c58431d/ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",hashes = {sha256 = "5c5da4af5f6418c07d75e6f3224e08147441f5d1eac2e6ce10dcce5e616a3bae"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/d6/cb3e3b4f03b9b0c4d4d8f06126d34b3394f6b4d764912fe80a1300696ef6/ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "80524f84a01355a59a93cef98d804e2137639823bcee2931f5028e71134a954e"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/d2/ea/bf60cb46d7ade706a246cd3fb99e4cfe854efa3dfbe530d049c684da24ff/ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "ff7f5ce8d7988767dd46a148192a14d0f48d1baea733f055d9064875c7d50389"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2d/3e/05f72f4c3d3a69e65d55a13e1dd1ade76c106d8546e7e54501d31f1dc54a/ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "c55d84715061f8b05469cdc9a446aa6c7294cd4bd55e86a89e572dba14374f8c"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",url = "https://files.pythonhosted.org/packages/81/e7/01b1fc403dd45d6cfe600725270ecc6a8f8a48a55bc6521ad820ed3ceaf8/ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",hashes = {sha256 = "ac57fed932d90fa1624c946dc67a0a3388d65a7edc7d2d8e4ca7bddaa789b3b0"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/fa/92/d9e183d4ed6185a8df2ce9faa3f22e80e95b5f88d9cc3d86a6d94331da3f/ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "c366a71d5b4f41f86a008694f7a0d75fe409ec298685ff72dc882f882d532e36"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/3b/4a/6ddb1b11d60888be224d721e01bdd2d81faaf1720592858ab8bac3600466/ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "f4ea9d1b5ad3e7a83ee8ebb1229c33e5fe771e833d6d3dcfca7b77d95b060d38"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/98/3f1d18a8d9ea33ef2ad508f0417fcb182c99b23258ec5e53d15db8289809/ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "b0f70202996055b555d3d74b626406476cc692f37b13bac8828acff058c9966a"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/8d/86/b6ce62ce9c12765fa6c65078d1938d2490b2b1d9273d0de384952b43c490/ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",hashes = {sha256 = "f8cff7a105dad631085d9505b491db33848007d6b487c3c1979dd8d9b2963783"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/6e/af7943466a41338d04503fb5a81b2fd07251bd272f546622e5b1599a7976/ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9761e84255443316a258dd7dfbd9bfb59c756e52237ed42494917b2577697c6a"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/3f/97/0249b9a24f0f3ebd12f007e81c87cec6d311de566885e9309fcbac5b24cc/ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",hashes = {sha256 = "3d376a88c3102ef228b102211ef4a6d13df330cb0f5ca56fdac04ccec2a99700"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/f6/85/0b64693b2c99d62ae65236ef74508ba39c3febd01466ef7f354885e5050c/ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",hashes = {sha256 = "cbefd60082b517a82c6ec8836989775ac05f8991715d228b3c1d86ccc7df7dae"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/96/fc/342e9f28179915d28b3747b7654f932ca472afbf7090fc0c4011e802f494/ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",hashes = {sha256 = "dd16b9a5a499fe73f3c2ef09a7885cb1d97058614d601809d37c422ed1525317"}}, + {name = "ruff-0.13.1-py3-none-win32.whl",url = "https://files.pythonhosted.org/packages/37/54/6177a0dc10bce6f43e392a2192e6018755473283d0cf43cc7e6afc182aea/ruff-0.13.1-py3-none-win32.whl",hashes = {sha256 = "55e9efa692d7cb18580279f1fbb525146adc401f40735edf0aaeabd93099f9a0"}}, + {name = "ruff-0.13.1-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/51/c6a3a33d9938007b8bdc8ca852ecc8d810a407fb513ab08e34af12dc7c24/ruff-0.13.1-py3-none-win_amd64.whl",hashes = {sha256 = "3a3fb595287ee556de947183489f636b9f76a72f0fa9c028bdcabf5bab2cc5e5"}}, + {name = "ruff-0.13.1-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/04/afc078a12cf68592345b1e2d6ecdff837d286bac023d7a22c54c7a698c5b/ruff-0.13.1-py3-none-win_arm64.whl",hashes = {sha256 = "c0bae9ffd92d54e03c2bf266f466da0a65e145f298ee5b5846ed435f6a00518a"}}, ] marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" @@ -100,55 +107,63 @@ dependencies = [] [[packages]] name = "coverage" -version = "7.10.6" +version = "7.10.7" requires-python = ">=3.9" -sdist = {name = "coverage-7.10.6.tar.gz", url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hashes = {sha256 = "f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90"}} -wheels = [ - {name = "coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d3/aa/76cf0b5ec00619ef208da4689281d48b57f2c7fde883d14bf9441b74d59f/coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "6008a021907be8c4c02f37cdc3ffb258493bdebfeaf9a839f9e71dfdc47b018e"}}, - {name = "coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/65/91/8e41b8c7c505d398d7730206f3cbb4a875a35ca1041efc518051bfce0f6b/coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "5e75e37f23eb144e78940b40395b42f2321951206a4f50e23cfd6e8a198d3ceb"}}, - {name = "coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/87/7f/f718e732a423d442e6616580a951b8d1ec3575ea48bcd0e2228386805e79/coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "0f7cb359a448e043c576f0da00aa8bfd796a01b06aa610ca453d4dde09cc1034"}}, - {name = "coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e6/52/c1106120e6d801ac03e12b5285e971e758e925b6f82ee9b86db3aa10045d/coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "c68018e4fc4e14b5668f1353b41ccf4bc83ba355f0e1b3836861c6f042d89ac1"}}, - {name = "coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3d/ec/3a8645b1bb40e36acde9c0609f08942852a4af91a937fe2c129a38f2d3f5/coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "cd4b2b0707fc55afa160cd5fc33b27ccbf75ca11d81f4ec9863d5793fc6df56a"}}, - {name = "coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/70/09ecb68eeb1155b28a1d16525fd3a9b65fbe75337311a99830df935d62b6/coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4cec13817a651f8804a86e4f79d815b3b28472c910e099e4d5a0e8a3b6a1d4cb"}}, - {name = "coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c6/80/47df374b893fa812e953b5bc93dcb1427a7b3d7a1a7d2db33043d17f74b9/coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "f2a6a8e06bbda06f78739f40bfb56c45d14eb8249d0f0ea6d4b3d48e1f7c695d"}}, - {name = "coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/4a/65/9f98640979ecee1b0d1a7164b589de720ddf8100d1747d9bbdb84be0c0fb/coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "081b98395ced0d9bcf60ada7661a0b75f36b78b9d7e39ea0790bb4ed8da14747"}}, - {name = "coverage-7.10.6-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/1f/55/eeb6603371e6629037f47bd25bef300387257ed53a3c5fdb159b7ac8c651/coverage-7.10.6-cp314-cp314-win32.whl",hashes = {sha256 = "6937347c5d7d069ee776b2bf4e1212f912a9f1f141a429c475e6089462fcecc5"}}, - {name = "coverage-7.10.6-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/15/d1/a0912b7611bc35412e919a2cd59ae98e7ea3b475e562668040a43fb27897/coverage-7.10.6-cp314-cp314-win_amd64.whl",hashes = {sha256 = "adec1d980fa07e60b6ef865f9e5410ba760e4e1d26f60f7e5772c73b9a5b0713"}}, - {name = "coverage-7.10.6-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ef/2d/11880bb8ef80a45338e0b3e0725e4c2d73ffbb4822c29d987078224fd6a5/coverage-7.10.6-cp314-cp314-win_arm64.whl",hashes = {sha256 = "a80f7aef9535442bdcf562e5a0d5a5538ce8abe6bb209cfbf170c462ac2c2a32"}}, - {name = "coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/83/c0/1f00caad775c03a700146f55536ecd097a881ff08d310a58b353a1421be0/coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "0de434f4fbbe5af4fa7989521c655c8c779afb61c53ab561b64dcee6149e4c65"}}, - {name = "coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a9/c4/b1c5d2bd7cc412cbeb035e257fd06ed4e3e139ac871d16a07434e145d18d/coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "6e31b8155150c57e5ac43ccd289d079eb3f825187d7c66e755a055d2c85794c6"}}, - {name = "coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/3f/07/4468d37c94724bf6ec354e4ec2f205fda194343e3e85fd2e59cec57e6a54/coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "98cede73eb83c31e2118ae8d379c12e3e42736903a8afcca92a7218e1f2903b0"}}, - {name = "coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/d8/f8fb351be5fee31690cd8da768fd62f1cfab33c31d9f7baba6cd8960f6b8/coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "f863c08f4ff6b64fa8045b1e3da480f5374779ef187f07b82e0538c68cb4ff8e"}}, - {name = "coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/70/65d4d7cfc75c5c6eb2fed3ee5cdf420fd8ae09c4808723a89a81d5b1b9c3/coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2b38261034fda87be356f2c3f42221fdb4171c3ce7658066ae449241485390d5"}}, - {name = "coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/3c/069df106d19024324cde10e4ec379fe2fb978017d25e97ebee23002fbadf/coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e93b1476b79eae849dc3872faeb0bf7948fd9ea34869590bc16a2a00b9c82a7"}}, - {name = "coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/fc/8a/2974d53904080c5dc91af798b3a54a4ccb99a45595cc0dcec6eb9616a57d/coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "ff8a991f70f4c0cf53088abf1e3886edcc87d53004c7bb94e78650b4d3dac3b5"}}, - {name = "coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/30/38/9616a6b49c686394b318974d7f6e08f38b8af2270ce7488e879888d1e5db/coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ac765b026c9f33044419cbba1da913cfb82cca1b60598ac1c7a5ed6aac4621a0"}}, - {name = "coverage-7.10.6-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/76/16/3ed2d6312b371a8cf804abf4e14895b70e4c3491c6e53536d63fd0958a8d/coverage-7.10.6-cp314-cp314t-win32.whl",hashes = {sha256 = "441c357d55f4936875636ef2cfb3bee36e466dcf50df9afbd398ce79dba1ebb7"}}, - {name = "coverage-7.10.6-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d5/e5/d38d0cb830abede2adb8b147770d2a3d0e7fecc7228245b9b1ae6c24930a/coverage-7.10.6-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "073711de3181b2e204e4870ac83a7c4853115b42e9cd4d145f2231e12d670930"}}, - {name = "coverage-7.10.6-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f4/51/e48e550f6279349895b0ffcd6d2a690e3131ba3a7f4eafccc141966d4dea/coverage-7.10.6-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "137921f2bac5559334ba66122b753db6dc5d1cf01eb7b64eb412bb0d064ef35b"}}, - {name = "coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6"}}, - {name = "coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80"}}, - {name = "coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003"}}, - {name = "coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27"}}, - {name = "coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4"}}, - {name = "coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d"}}, - {name = "coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc"}}, - {name = "coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc"}}, - {name = "coverage-7.10.6-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl",hashes = {sha256 = "160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e"}}, - {name = "coverage-7.10.6-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl",hashes = {sha256 = "628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32"}}, - {name = "coverage-7.10.6-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl",hashes = {sha256 = "df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2"}}, - {name = "coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b"}}, - {name = "coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393"}}, - {name = "coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27"}}, - {name = "coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df"}}, - {name = "coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb"}}, - {name = "coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282"}}, - {name = "coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4"}}, - {name = "coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21"}}, - {name = "coverage-7.10.6-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl",hashes = {sha256 = "92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0"}}, - {name = "coverage-7.10.6-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5"}}, - {name = "coverage-7.10.6-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b"}}, - {name = "coverage-7.10.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl",hashes = {sha256 = "92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3"}}, +sdist = {name = "coverage-7.10.7.tar.gz", url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hashes = {sha256 = "f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239"}} +wheels = [ + {name = "coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520"}}, + {name = "coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd"}}, + {name = "coverage-7.10.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl",hashes = {sha256 = "b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2"}}, + {name = "coverage-7.10.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681"}}, + {name = "coverage-7.10.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880"}}, + {name = "coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63"}}, + {name = "coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399"}}, + {name = "coverage-7.10.7-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl",hashes = {sha256 = "67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235"}}, + {name = "coverage-7.10.7-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d"}}, + {name = "coverage-7.10.7-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a"}}, + {name = "coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d"}}, + {name = "coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f"}}, + {name = "coverage-7.10.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl",hashes = {sha256 = "dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698"}}, + {name = "coverage-7.10.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843"}}, + {name = "coverage-7.10.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546"}}, + {name = "coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c"}}, + {name = "coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2"}}, + {name = "coverage-7.10.7-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl",hashes = {sha256 = "2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a"}}, + {name = "coverage-7.10.7-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb"}}, + {name = "coverage-7.10.7-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb"}}, + {name = "coverage-7.10.7-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl",hashes = {sha256 = "f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260"}}, ] marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" @@ -226,29 +241,6 @@ dependencies = [ "tzdata; sys_platform == \"win32\"", ] -[[packages]] -name = "psycopg2-binary" -version = "2.9.10" -requires-python = ">=3.8" -sdist = {name = "psycopg2-binary-2.9.10.tar.gz", url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hashes = {sha256 = "4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}} -wheels = [ - {name = "psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl",hashes = {sha256 = "26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl",hashes = {sha256 = "e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl",hashes = {sha256 = "27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142"}}, -] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "pytest" version = "8.4.2" @@ -302,19 +294,6 @@ dependencies = [ "colorama; platform_system == \"Windows\"", ] -[[packages]] -name = "types-psycopg2" -version = "2.9.21.20250915" -requires-python = ">=3.9" -sdist = {name = "types_psycopg2-2.9.21.20250915.tar.gz", url = "https://files.pythonhosted.org/packages/8f/20/3dcb89df8d1661cf6c4c2d9f84d4ba94dde48559cdcf7b536a380a9c387f/types_psycopg2-2.9.21.20250915.tar.gz", hashes = {sha256 = "bfeb8f54c32490e7b5edc46215ab4163693192bc90407b4a023822de9239f5c8"}} -wheels = [ - {name = "types_psycopg2-2.9.21.20250915-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/93/4d/ebf1c72809a30150ad142074e1ad5101304f7569c0df2fa872906d76d0af/types_psycopg2-2.9.21.20250915-py3-none-any.whl",hashes = {sha256 = "eefe5ccdc693fc086146e84c9ba437bb278efe1ef330b299a0cb71169dc6c55f"}}, -] -marker = "python_version >= \"3.13\" and \"types\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "types-tqdm" version = "4.67.0.20250809" @@ -330,19 +309,6 @@ dependencies = [ "types-requests", ] -[[packages]] -name = "xlsxwriter" -version = "3.2.9" -requires-python = ">=3.8" -sdist = {name = "xlsxwriter-3.2.9.tar.gz", url = "https://files.pythonhosted.org/packages/46/2c/c06ef49dc36e7954e55b802a8b231770d286a9758b3d936bd1e04ce5ba88/xlsxwriter-3.2.9.tar.gz", hashes = {sha256 = "254b1c37a368c444eac6e2f867405cc9e461b0ed97a3233b2ac1e574efb4140c"}} -wheels = [ - {name = "xlsxwriter-3.2.9-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3a/0c/3662f4a66880196a590b202f0db82d919dd2f89e99a27fadef91c4a33d41/xlsxwriter-3.2.9-py3-none-any.whl",hashes = {sha256 = "9a5db42bc5dff014806c58a20b9eae7322a134abb6fce3c92c181bfb275ec5b3"}}, -] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "pluggy" version = "1.6.0" @@ -527,19 +493,22 @@ dependencies = [ [[packages]] name = "ruamel-yaml-clib" -version = "0.2.12" +version = "0.2.13" requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.12.tar.gz", url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hashes = {sha256 = "6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl",hashes = {sha256 = "4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl",hashes = {sha256 = "3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl",hashes = {sha256 = "e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl",hashes = {sha256 = "6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3"}}, +sdist = {name = "ruamel.yaml.clib-0.2.13.tar.gz", url = "https://files.pythonhosted.org/packages/3c/fd/32c91c4d301ebe7931a3c44f7593650613afe14854e3cc9d2764321b7a46/ruamel.yaml.clib-0.2.13.tar.gz", hashes = {sha256 = "8d4f8d7853053a5a19171a0f515f1e14f503bd3e772c4da6bafe7d0893d4f299"}} +wheels = [ + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/30/b5/3bff051bfdc33f8d797a1a025a1dc74fb13703611917f611e62e12061893/ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "817a3d8dbbefc337e9081d9bddd54ee6ef5d5351cccb5240d731d604c1d86d29"}}, + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/51/a3/8f199f9d6ff862b503eae06a4a9ec9f20fc232ee7590287d969ebf5a8859/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "b29e3a746dd774a49ec6412529dc6a7338efe0828230b7c5da2aef3ee6eb7cbc"}}, + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/fb/47728a32be2e7ac00f854d30b0d39ed62e9eefdff19c024f4e5c49d3341c/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bae8383e02ef5a7c6b44a594746dcdb0994b8bdf4317d2fba3bbafe8262dfa9d"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/9a/21de96f5fc51e495f6ebe87f01a679ec3b9a36082431942d7dc7295175da/ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "b3dae045e57780a6ec39a018220d82931d6cb3e6e8b326a9a804597ffa6f8520"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/26/4203139b2f1fc94b01e5fb5c2e9a5822725baad930ceb869e3525157f1b1/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "f6d476bc7bb9b25d54133f95d0766aaf1662689f6c26e9e08d28a45609a634f2"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/16/db/ec371bb692c404ad1cfad715b89300cca841a4ac31ed3467c66a5911ce01/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5622265f2b64f6933a29a5d8e33385a0c3ef47f509354602d0c28f5d7d126fe3"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/cb/71/230119917102ea682c6a1fa2e322ca18cdd4077342680908999e18fd84cc/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b2ba05d2dbe39435915aa20d53336d55fd0fa6c25eb1c580d60fc1f753e40a41"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/2d/22afc8402474285fc9bf35cb630f6194aecb2c777b304f872dada19ab06c/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",hashes = {sha256 = "a5a43fc6f95c58c1a65cbb7b68b31f9721362e10c5276d3f8db4ccde8e9acb04"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c9/c7/928d0692ac05bb0f05b337e151da28792f25782ae0e2cda1a5bf0dda9dde/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "5ce7178bd66cffe4eb4ce40c2ff525f42ccfa6e2e31eeea27293fe5bd0ae2d93"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b2/2972fae8d9dc10314e39c254638320e1b028511185cebaa96f3382122f40/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "490c5dfaf9f218f335f2f6f7ba52f7ce5460e94d67a42c8dd0096deae7684d23"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/89/e3/fc6c145f7d122a39793f9a8e508ba060a3bc5883065f3f11dbc9011023bd/ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",hashes = {sha256 = "b5e32adbb14ffdb1130c699128070766e5cf781b3b05dd87049c16bb94395212"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/95/e5/6cb4654b62b90116962d88cb74419caa3eb5fc50ccbc932d5553adf70812/ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",hashes = {sha256 = "826ce141d368f10a99a4fc6fab332ba4203f63da25828853d7957e76d13f7d41"}}, ] marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and python_version >= \"3.13\" and \"lint\" in dependency_groups" @@ -674,7 +643,7 @@ marker = "sys_platform == \"win32\" and python_version >= \"3.13\" and \"default dependencies = [] [tool.pdm] -hashes = {sha256 = "9edcf2127050cd04b1c55f2c5d0ef0c306790635417a4e7c2a0ed6e601c76e78"} +hashes = {sha256 = "f41cee4895442b905a0fa8fe84189c460dff00eec403795e10a6ff2120675686"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.minimal.toml b/pylock.minimal.toml index 893d114..c1512f5 100644 --- a/pylock.minimal.toml +++ b/pylock.minimal.toml @@ -1,9 +1,9 @@ # This file is @generated by PDM. # It is not intended for manual editing. lock-version = "1.0" -requires-python = ">=3.9" +requires-python = ">=3.10" environments = [ - "python_version >= \"3.9\"", + "python_version >= \"3.10\"", ] extras = [] dependency-groups = ["default", "lint", "test", "types"] @@ -12,41 +12,41 @@ created-by = "pdm" [[packages]] name = "mypy" -version = "1.17.0" +version = "1.18.2" requires-python = ">=3.9" -sdist = {name = "mypy-1.17.0.tar.gz", url = "https://files.pythonhosted.org/packages/1e/e3/034322d5a779685218ed69286c32faa505247f1f096251ef66c8fd203b08/mypy-1.17.0.tar.gz", hashes = {sha256 = "e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03"}} -wheels = [ - {name = "mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/be/7b/5f8ab461369b9e62157072156935cec9d272196556bdc7c2ff5f4c7c0f9b/mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06"}}, - {name = "mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/9c/f8/c49c9e5a2ac0badcc54beb24e774d2499748302c9568f7f09e8730e953fa/mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a"}}, - {name = "mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/0c/fb3f9c939ad9beed3e328008b3fb90b20fda2cddc0f7e4c20dbefefc3b33/mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889"}}, - {name = "mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4c/66/85607ab5137d65e4f54d9797b77d5a038ef34f714929cf8ad30b03f628df/mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba"}}, - {name = "mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/d0/341dbbfb35ce53d01f8f2969facbb66486cee9804048bf6c01b048127501/mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658"}}, - {name = "mypy-1.17.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/63/70c8b7dbfc520089ac48d01367a97e8acd734f65bd07813081f508a8c94c/mypy-1.17.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c"}}, - {name = "mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/12/e9/e6824ed620bbf51d3bf4d6cbbe4953e83eaf31a448d1b3cfb3620ccb641c/mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb"}}, - {name = "mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/ba/51/a4afd1ae279707953be175d303f04a5a7bd7e28dc62463ad29c1c857927e/mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d"}}, - {name = "mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8a/71/19adfeac926ba8205f1d1466d0d360d07b46486bf64360c54cb5a2bd86a8/mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8"}}, - {name = "mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e"}}, - {name = "mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/dc/56f53b5255a166f5bd0f137eed960e5065f2744509dfe69474ff0ba772a5/mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8"}}, - {name = "mypy-1.17.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/69/ac/070bad311171badc9add2910e7f89271695a25c136de24bbafc7eded56d5/mypy-1.17.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d"}}, - {name = "mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/24/82efb502b0b0f661c49aa21cfe3e1999ddf64bf5500fc03b5a1536a39d39/mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be"}}, - {name = "mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/03/96/8ef9a6ff8cedadff4400e2254689ca1dc4b420b92c55255b44573de10c54/mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61"}}, - {name = "mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/df/32/7ce359a56be779d38021d07941cfbb099b41411d72d827230a36203dbb81/mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f"}}, - {name = "mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/16/b775047054de4d8dbd668df9137707e54b07fe18c7923839cd1e524bf756/mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d"}}, - {name = "mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a1/cf/fa33eaf29a606102c8d9ffa45a386a04c2203d9ad18bf4eef3e20c43ebc8/mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3"}}, - {name = "mypy-1.17.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/94/75/3f5a29209f27e739ca57e6350bc6b783a38c7621bdf9cac3ab8a08665801/mypy-1.17.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70"}}, - {name = "mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/6a/31/e762baa3b73905c856d45ab77b4af850e8159dffffd86a52879539a08c6b/mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6"}}, - {name = "mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/1c/c1/25b2f0d46fb7e0b5e2bee61ec3a47fe13eff9e3c2f2234f144858bbe6485/mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d"}}, - {name = "mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/02/78/6d646603a57aa8a2886df1b8881fe777ea60f28098790c1089230cd9c61d/mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b"}}, - {name = "mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4f/19/dae6c55e87ee426fb76980f7e78484450cad1c01c55a1dc4e91c930bea01/mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a"}}, - {name = "mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/86/e1/f916845a235235a6c1e4d4d065a3930113767001d491b8b2e1b61ca56647/mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f"}}, - {name = "mypy-1.17.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ae/dc/414760708a4ea1b096bd214d26a24e30ac5e917ef293bc33cdb6fe22d2da/mypy-1.17.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937"}}, - {name = "mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/9f/a0/6263dd11941231f688f0a8f2faf90ceac1dc243d148d314a089d2fe25108/mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl",hashes = {sha256 = "63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab"}}, - {name = "mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/02/13/b8f16d6b0dc80277129559c8e7dbc9011241a0da8f60d031edb0e6e9ac8f/mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl",hashes = {sha256 = "f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad"}}, - {name = "mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/14/ef/978ba79df0d65af680e20d43121363cf643eb79b04bf3880d01fc8afeb6f/mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c"}}, - {name = "mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/f4/10/55ef70b104151a0d8280474f05268ff0a2a79be8d788d5e647257d121309/mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8"}}, - {name = "mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/8c/7781fcd2e1eef48fbedd3a422c21fe300a8e03ed5be2eb4bd10246a77f4e/mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97"}}, - {name = "mypy-1.17.0-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/78/13/03ac759dabe86e98ca7b6681f114f90ee03f3ff8365a57049d311bd4a4e3/mypy-1.17.0-cp39-cp39-win_amd64.whl",hashes = {sha256 = "ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4"}}, - {name = "mypy-1.17.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e3/fc/ee058cc4316f219078464555873e99d170bde1d9569abd833300dbeb484a/mypy-1.17.0-py3-none-any.whl",hashes = {sha256 = "15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496"}}, +sdist = {name = "mypy-1.18.2.tar.gz", url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hashes = {sha256 = "06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"}} +wheels = [ + {name = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"}}, + {name = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}}, + {name = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}}, + {name = "mypy-1.18.2-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl",hashes = {sha256 = "749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}}, + {name = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}}, + {name = "mypy-1.18.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}}, + {name = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"}}, + {name = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"}}, + {name = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"}}, + {name = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"}}, + {name = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"}}, + {name = "mypy-1.18.2-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"}}, + {name = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"}}, + {name = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"}}, + {name = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"}}, + {name = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"}}, + {name = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"}}, + {name = "mypy-1.18.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"}}, + {name = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/03/6f/657961a0743cff32e6c0611b63ff1c1970a0b482ace35b069203bf705187/mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"}}, + {name = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/10/e9/420822d4f661f13ca8900f5fa239b40ee3be8b62b32f3357df9a3045a08b/mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"}}, + {name = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/aa/73/a05b2bbaa7005f4642fcfe40fb73f2b4fb6bb44229bd585b5878e9a87ef8/mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"}}, + {name = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4f/01/f6e4b9f0d031c11ccbd6f17da26564f3a0f3c4155af344006434b0a05a9d/mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"}}, + {name = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/97/19727e7499bfa1ae0773d06afd30ac66a58ed7437d940c70548634b24185/mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"}}, + {name = "mypy-1.18.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/4f/90dc8c15c1441bf31cf0f9918bb077e452618708199e530f4cbd5cede6ff/mypy-1.18.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"}}, + {name = "mypy-1.18.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl",hashes = {sha256 = "22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}}, ] marker = "\"lint\" in dependency_groups" @@ -60,11 +60,11 @@ dependencies = [ [[packages]] name = "pre-commit-hooks" -version = "5.0.0" -requires-python = ">=3.8" -sdist = {name = "pre_commit_hooks-5.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/ac/7d/3299241a753c738d114600c360d754550b28c285281dc6a5132c4ccfae65/pre_commit_hooks-5.0.0.tar.gz", hashes = {sha256 = "10626959a9eaf602fbfc22bc61b6e75801436f82326bfcee82bb1f2fc4bc646e"}} +version = "6.0.0" +requires-python = ">=3.9" +sdist = {name = "pre_commit_hooks-6.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/36/4d/93e63e48f8fd16d6c1e4cef5dabadcade4d1325c7fd6f29f075a4d2284f3/pre_commit_hooks-6.0.0.tar.gz", hashes = {sha256 = "76d8370c006f5026cdd638a397a678d26dda735a3c88137e05885a020f824034"}} wheels = [ - {name = "pre_commit_hooks-5.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1e/29/db1d855a661c02dbde5cab3057969133fcc62e7a0c6393e48fe9d0e81679/pre_commit_hooks-5.0.0-py2.py3-none-any.whl",hashes = {sha256 = "8d71cfb582c5c314a5498d94e0104b6567a8b93fb35903ea845c491f4e290a7a"}}, + {name = "pre_commit_hooks-6.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/12/46/eba9be9daa403fa94854ce16a458c29df9a01c6c047931c3d8be6016cd9a/pre_commit_hooks-6.0.0-py2.py3-none-any.whl",hashes = {sha256 = "76161b76d321d2f8ee2a8e0b84c30ee8443e01376121fd1c90851e33e3bd7ee2"}}, ] marker = "\"lint\" in dependency_groups" @@ -76,27 +76,28 @@ dependencies = [ [[packages]] name = "ruff" -version = "0.12.5" +version = "0.13.1" requires-python = ">=3.7" -sdist = {name = "ruff-0.12.5.tar.gz", url = "https://files.pythonhosted.org/packages/30/cd/01015eb5034605fd98d829c5839ec2c6b4582b479707f7c1c2af861e8258/ruff-0.12.5.tar.gz", hashes = {sha256 = "b209db6102b66f13625940b7f8c7d0f18e20039bb7f6101fbdac935c9612057e"}} -wheels = [ - {name = "ruff-0.12.5-py3-none-linux_armv6l.whl",url = "https://files.pythonhosted.org/packages/d4/de/ad2f68f0798ff15dd8c0bcc2889558970d9a685b3249565a937cd820ad34/ruff-0.12.5-py3-none-linux_armv6l.whl",hashes = {sha256 = "1de2c887e9dec6cb31fcb9948299de5b2db38144e66403b9660c9548a67abd92"}}, - {name = "ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/fc/c6b65cd0e7fbe60f17e7ad619dca796aa49fbca34bb9bea5f8faf1ec2643/ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl",hashes = {sha256 = "d1ab65e7d8152f519e7dea4de892317c9da7a108da1c56b6a3c1d5e7cf4c5e9a"}}, - {name = "ruff-0.12.5-py3-none-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/de/c6bec1dce5ead9f9e6a946ea15e8d698c35f19edc508289d70a577921b30/ruff-0.12.5-py3-none-macosx_11_0_arm64.whl",hashes = {sha256 = "962775ed5b27c7aa3fdc0d8f4d4433deae7659ef99ea20f783d666e77338b8cf"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/16/cf372d2ebe91e4eb5b82a2275c3acfa879e0566a7ac94d331ea37b765ac8/ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "73b4cae449597e7195a49eb1cdca89fd9fbb16140c7579899e87f4c85bf82f73"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/25/bf/cd07e8f6a3a6ec746c62556b4c4b79eeb9b0328b362bb8431b7b8afd3856/ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "8b13489c3dc50de5e2d40110c0cce371e00186b880842e245186ca862bf9a1ac"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/d8/c9/c2ccb3b8cbb5661ffda6925f81a13edbb786e623876141b04919d1128370/ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "f1504fea81461cf4841778b3ef0a078757602a3b3ea4b008feb1308cb3f23e08"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",url = "https://files.pythonhosted.org/packages/6b/58/68a5be2c8e5590ecdad922b2bcd5583af19ba648f7648f95c51c3c1eca81/ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",hashes = {sha256 = "c7da4129016ae26c32dfcbd5b671fe652b5ab7fc40095d80dcff78175e7eddd4"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/bd/d1/ef6b19622009ba8386fdb792c0743f709cf917b0b2f1400589cbe4739a33/ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "ca972c80f7ebcfd8af75a0f18b17c42d9f1ef203d163669150453f50ca98ab7b"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/62/e3/1c98c566fe6809a0c83751d825a03727f242cdbe0d142c9e292725585521/ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "8dbbf9f25dfb501f4237ae7501d6364b76a01341c6f1b2cd6764fe449124bb2a"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/24/ff/96058f6506aac0fbc0d0fc0d60b0d0bd746240a0594657a2d94ad28033ba/ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2c47dea6ae39421851685141ba9734767f960113d51e83fd7bb9958d5be8763a"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/d3/68bc5e7ab96c94b3589d1789f2dd6dd4b27b263310019529ac9be1e8f31b/ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c5076aa0e61e30f848846f0265c873c249d4b558105b221be1828f9f79903dc5"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/52/75/7356af30a14584981cabfefcf6106dea98cec9a7af4acb5daaf4b114845f/ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl",hashes = {sha256 = "a5a4c7830dadd3d8c39b1cc85386e2c1e62344f20766be6f173c22fb5f72f293"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c2/67/91c71d27205871737cae11025ee2b098f512104e26ffd8656fd93d0ada0a/ruff-0.12.5-py3-none-musllinux_1_2_i686.whl",hashes = {sha256 = "46699f73c2b5b137b9dc0fc1a190b43e35b008b398c6066ea1350cce6326adcb"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/04/b6b00383cf2f48e8e78e14eb258942fdf2a9bf0287fbf5cdd398b749193a/ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5a655a0a0d396f0f072faafc18ebd59adde8ca85fb848dc1b0d9f024b9c4d3bb"}}, - {name = "ruff-0.12.5-py3-none-win32.whl",url = "https://files.pythonhosted.org/packages/3e/b9/053d6445dc7544fb6594785056d8ece61daae7214859ada4a152ad56b6e0/ruff-0.12.5-py3-none-win32.whl",hashes = {sha256 = "dfeb2627c459b0b78ca2bbdc38dd11cc9a0a88bf91db982058b26ce41714ffa9"}}, - {name = "ruff-0.12.5-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bc/0f/ab16e8259493137598b9149734fec2e06fdeda9837e6f634f5c4e35916da/ruff-0.12.5-py3-none-win_amd64.whl",hashes = {sha256 = "ae0d90cf5f49466c954991b9d8b953bd093c32c27608e409ae3564c63c5306a5"}}, - {name = "ruff-0.12.5-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/00/db/c376b0661c24cf770cb8815268190668ec1330eba8374a126ceef8c72d55/ruff-0.12.5-py3-none-win_arm64.whl",hashes = {sha256 = "48cdbfc633de2c5c37d9f090ba3b352d1576b0015bfc3bc98eaf230275b7e805"}}, +sdist = {name = "ruff-0.13.1.tar.gz", url = "https://files.pythonhosted.org/packages/ab/33/c8e89216845615d14d2d42ba2bee404e7206a8db782f33400754f3799f05/ruff-0.13.1.tar.gz", hashes = {sha256 = "88074c3849087f153d4bb22e92243ad4c1b366d7055f98726bc19aa08dc12d51"}} +wheels = [ + {name = "ruff-0.13.1-py3-none-linux_armv6l.whl",url = "https://files.pythonhosted.org/packages/f3/41/ca37e340938f45cfb8557a97a5c347e718ef34702546b174e5300dbb1f28/ruff-0.13.1-py3-none-linux_armv6l.whl",hashes = {sha256 = "b2abff595cc3cbfa55e509d89439b5a09a6ee3c252d92020bd2de240836cf45b"}}, + {name = "ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/84/ba378ef4129415066c3e1c80d84e539a0d52feb250685091f874804f28af/ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",hashes = {sha256 = "4ee9f4249bf7f8bb3984c41bfaf6a658162cdb1b22e3103eabc7dd1dc5579334"}}, + {name = "ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8d/b6/ec5e4559ae0ad955515c176910d6d7c93edcbc0ed1a3195a41179c58431d/ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",hashes = {sha256 = "5c5da4af5f6418c07d75e6f3224e08147441f5d1eac2e6ce10dcce5e616a3bae"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/d6/cb3e3b4f03b9b0c4d4d8f06126d34b3394f6b4d764912fe80a1300696ef6/ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "80524f84a01355a59a93cef98d804e2137639823bcee2931f5028e71134a954e"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/d2/ea/bf60cb46d7ade706a246cd3fb99e4cfe854efa3dfbe530d049c684da24ff/ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "ff7f5ce8d7988767dd46a148192a14d0f48d1baea733f055d9064875c7d50389"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2d/3e/05f72f4c3d3a69e65d55a13e1dd1ade76c106d8546e7e54501d31f1dc54a/ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "c55d84715061f8b05469cdc9a446aa6c7294cd4bd55e86a89e572dba14374f8c"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",url = "https://files.pythonhosted.org/packages/81/e7/01b1fc403dd45d6cfe600725270ecc6a8f8a48a55bc6521ad820ed3ceaf8/ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",hashes = {sha256 = "ac57fed932d90fa1624c946dc67a0a3388d65a7edc7d2d8e4ca7bddaa789b3b0"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/fa/92/d9e183d4ed6185a8df2ce9faa3f22e80e95b5f88d9cc3d86a6d94331da3f/ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "c366a71d5b4f41f86a008694f7a0d75fe409ec298685ff72dc882f882d532e36"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/3b/4a/6ddb1b11d60888be224d721e01bdd2d81faaf1720592858ab8bac3600466/ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "f4ea9d1b5ad3e7a83ee8ebb1229c33e5fe771e833d6d3dcfca7b77d95b060d38"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/98/3f1d18a8d9ea33ef2ad508f0417fcb182c99b23258ec5e53d15db8289809/ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "b0f70202996055b555d3d74b626406476cc692f37b13bac8828acff058c9966a"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/8d/86/b6ce62ce9c12765fa6c65078d1938d2490b2b1d9273d0de384952b43c490/ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",hashes = {sha256 = "f8cff7a105dad631085d9505b491db33848007d6b487c3c1979dd8d9b2963783"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/6e/af7943466a41338d04503fb5a81b2fd07251bd272f546622e5b1599a7976/ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9761e84255443316a258dd7dfbd9bfb59c756e52237ed42494917b2577697c6a"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/3f/97/0249b9a24f0f3ebd12f007e81c87cec6d311de566885e9309fcbac5b24cc/ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",hashes = {sha256 = "3d376a88c3102ef228b102211ef4a6d13df330cb0f5ca56fdac04ccec2a99700"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/f6/85/0b64693b2c99d62ae65236ef74508ba39c3febd01466ef7f354885e5050c/ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",hashes = {sha256 = "cbefd60082b517a82c6ec8836989775ac05f8991715d228b3c1d86ccc7df7dae"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/96/fc/342e9f28179915d28b3747b7654f932ca472afbf7090fc0c4011e802f494/ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",hashes = {sha256 = "dd16b9a5a499fe73f3c2ef09a7885cb1d97058614d601809d37c422ed1525317"}}, + {name = "ruff-0.13.1-py3-none-win32.whl",url = "https://files.pythonhosted.org/packages/37/54/6177a0dc10bce6f43e392a2192e6018755473283d0cf43cc7e6afc182aea/ruff-0.13.1-py3-none-win32.whl",hashes = {sha256 = "55e9efa692d7cb18580279f1fbb525146adc401f40735edf0aaeabd93099f9a0"}}, + {name = "ruff-0.13.1-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/51/c6a3a33d9938007b8bdc8ca852ecc8d810a407fb513ab08e34af12dc7c24/ruff-0.13.1-py3-none-win_amd64.whl",hashes = {sha256 = "3a3fb595287ee556de947183489f636b9f76a72f0fa9c028bdcabf5bab2cc5e5"}}, + {name = "ruff-0.13.1-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/04/afc078a12cf68592345b1e2d6ecdff837d286bac023d7a22c54c7a698c5b/ruff-0.13.1-py3-none-win_arm64.whl",hashes = {sha256 = "c0bae9ffd92d54e03c2bf266f466da0a65e145f298ee5b5846ed435f6a00518a"}}, ] marker = "\"lint\" in dependency_groups" @@ -105,116 +106,130 @@ dependencies = [] [[packages]] name = "duckdb" -version = "0.6.1" -sdist = {name = "duckdb-0.6.1.tar.gz", url = "https://files.pythonhosted.org/packages/48/80/0dee966cde56d2e1b3ea8e3389b2e93288d662bc0b85b6b0508f3151f3c0/duckdb-0.6.1.tar.gz", hashes = {sha256 = "6d26e9f1afcb924a6057785e506810d48332d4764ddc4a5b414d0f2bf0cacfb4"}} -wheels = [ - {name = "duckdb-0.6.1-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/2e/d7/0320924f9e817442afad06a5e428e8f5fb55b6cb20bfd2b0be4b3975ec08/duckdb-0.6.1-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "b4bbe2f6c1b109c626f9318eee80934ad2a5b81a51409c6b5083c6c5f9bdb125"}}, - {name = "duckdb-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/a7/c01998a05ed41fd3bf124079de9508ee6002e5b120a4ba353817535eaa7a/duckdb-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "cfea36b58928ce778d17280d4fb3bf0a2d7cff407667baedd69c5b41463ac0fd"}}, - {name = "duckdb-0.6.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bc/1b/a0b13a6e985ff1024e0d52b372f43e385ce1538773ecac250e82543572e2/duckdb-0.6.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "0b64eb53d0d0695814bf1b65c0f91ab7ed66b515f89c88038f65ad5e0762571c"}}, - {name = "duckdb-0.6.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/1e/5e/8b7472fdaedce2a3eed50da24335bfa81ca5dbca66d6b684a1646ab52727/duckdb-0.6.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "35b01bc724e1933293f4c34f410d2833bfbb56d5743b515d805bbfed0651476e"}}, - {name = "duckdb-0.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/4d/5baca267898d4d290a9dabe3d6d023cba38fb1774234f7fa4cc069a02638/duckdb-0.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "fec2c2466654ce786843bda2bfba71e0e4719106b41d36b17ceb1901e130aa71"}}, - {name = "duckdb-0.6.1-cp311-cp311-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/55/d9/d80159f4304e351db0459a16e9c8d139c87a495300007cc105b75452c30f/duckdb-0.6.1-cp311-cp311-musllinux_1_1_i686.whl",hashes = {sha256 = "82cd30f5cf368658ef879b1c60276bc8650cf67cfe3dc3e3009438ba39251333"}}, - {name = "duckdb-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/5c/ad/1186693bc6d73f5ba1ac4e13772ba57abfcc970aa03ccdfb8c7405b039f1/duckdb-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "a782bbfb7f5e97d4a9c834c9e78f023fb8b3f6687c22ca99841e6ed944b724da"}}, - {name = "duckdb-0.6.1-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/8a/54/4210ce0b26a010fd2755f8d78dcaeceeb4d1ddda76d2e884c0b130fae6dc/duckdb-0.6.1-cp311-cp311-win32.whl",hashes = {sha256 = "e3702d4a9ade54c6403f6615a98bbec2020a76a60f5db7fcf085df1bd270e66e"}}, - {name = "duckdb-0.6.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/78/cc/508a045cb18164d0890eb09f38bc7f8346aa03c387217c71aeeab1be61ec/duckdb-0.6.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "93b074f473d68c944b0eeb2edcafd91ad11da8432b484836efaaab4e26351d48"}}, - {name = "duckdb-0.6.1-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/94/68/c633dcd576dd63e627619a6274c17b6ddc8e2637fa9b037a5241b687c40b/duckdb-0.6.1-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "e566514f9327f89264e98ac14ee7a84fbd9857328028258422c3e8375ee19d25"}}, - {name = "duckdb-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/c5/ef/ff74822cbd8792138edad7da762fc1d371723761fe9362a44df85b09774c/duckdb-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "b31c2883de5b19591a2852165e6b3f9821f77af649835f27bc146b26e4aa30cb"}}, - {name = "duckdb-0.6.1-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/98/74/069f636ba410c7055847cd202bb8fb7e8ea1b0e0a2ae6b131ba40e0d4322/duckdb-0.6.1-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "998165b2fb1f1d2b0ad742096015ea70878f7d40304643c7424c3ed3ddf07bfc"}}, - {name = "duckdb-0.6.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/a2/02/a36ca6545c81cb6ec339fcff178b931b0079cdd9d39806da2d440dcdab32/duckdb-0.6.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3941b3a1e8a1cdb7b90ab3917b87af816e71f9692e5ada7f19b6b60969f731e5"}}, - {name = "duckdb-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/7f/fa/d79b39cec15fd227c7174108f24541bd69fc7f1751ec2cf02099055e2592/duckdb-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "143611bd1b7c13343f087d4d423a7a8a4f33a114c5326171e867febf3f0fcfe1"}}, - {name = "duckdb-0.6.1-cp310-cp310-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/35/53/d85036800c1672f15e178a623b2fcb3ac203664cbfa54180c39c74ad4102/duckdb-0.6.1-cp310-cp310-musllinux_1_1_i686.whl",hashes = {sha256 = "125ba45e8b08f28858f918ec9cbd3a19975e5d8d9e8275ef4ad924028a616e14"}}, - {name = "duckdb-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/30/b4/5f7f1d46392bbf0d95ebc53762b18228fd7331c7f9eebb72469469419672/duckdb-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "e609a65b31c92f2f7166831f74b56f5ed54b33d8c2c4b4c3974c26fdc50464c5"}}, - {name = "duckdb-0.6.1-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/e6/2d/b43e5864efde07dce1d20a07cf2a238efb71878e002a14b0234da4a60936/duckdb-0.6.1-cp310-cp310-win32.whl",hashes = {sha256 = "b39045074fb9a3f068496475a5d627ad4fa572fa3b4980e3b479c11d0b706f2d"}}, - {name = "duckdb-0.6.1-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/47/8d/140845f6f61f9fe936f5743fedb6625c0ff4781f3be928e4d3a20d551fc7/duckdb-0.6.1-cp310-cp310-win_amd64.whl",hashes = {sha256 = "16fa96ffaa3d842a9355a633fb8bc092d119be08d4bc02013946d8594417bc14"}}, - {name = "duckdb-0.6.1-cp39-cp39-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/1d/77/6bc4ebcc95986ce57c74e94066f9a668b8508d32b0a07a427eb92b11e19f/duckdb-0.6.1-cp39-cp39-macosx_10_9_universal2.whl",hashes = {sha256 = "c35ff4b1117096ef72d101524df0079da36c3735d52fcf1d907ccffa63bd6202"}}, - {name = "duckdb-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/ef/a0/42dc092e852b3fc577445a53119d954d5b0c50815782b91a0cc66af4a1a1/duckdb-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl",hashes = {sha256 = "5c54910fbb6de0f21d562e18a5c91540c19876db61b862fc9ffc8e31be8b3f03"}}, - {name = "duckdb-0.6.1-cp39-cp39-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/b6/ae/ea1b6860227f0bb175d8a331a235c66a24883c746ee308a9391c5e697613/duckdb-0.6.1-cp39-cp39-macosx_11_0_arm64.whl",hashes = {sha256 = "99a7172563a3ae67d867572ce27cf3962f58e76f491cb7f602f08c2af39213b3"}}, - {name = "duckdb-0.6.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/7b/dd/3439c82a6bc61c677098ba0d1216665321d0624ef6d0e3bb2cc79c3c9616/duckdb-0.6.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "7363ffe857d00216b659116647fbf1e925cb3895699015d4a4e50b746de13041"}}, - {name = "duckdb-0.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/84/8f/72a0be1eb246471b58162eb319ac003ac5ac09a47aec72755a91743d3954/duckdb-0.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "06c1cef25f896b2284ba048108f645c72fab5c54aa5a6f62f95663f44ff8a79b"}}, - {name = "duckdb-0.6.1-cp39-cp39-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/74/ad/271475c8b9c4bf42b4c59946eb9e1f1a0177966f02850804f62c4e81657d/duckdb-0.6.1-cp39-cp39-musllinux_1_1_i686.whl",hashes = {sha256 = "e92dd6aad7e8c29d002947376b6f5ce28cae29eb3b6b58a64a46cdbfc5cb7943"}}, - {name = "duckdb-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/2a/d8/aa2facdb198cab383221c5e13a7738f09830e3989908b02abd1cab682a0b/duckdb-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl",hashes = {sha256 = "4b280b2d8a01ecd4fe2feab041df70233c534fafbe33a38565b52c1e017529c7"}}, - {name = "duckdb-0.6.1-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/92/7c/5879a645e7a3abc13781c368a0ca550fe64e049f5c2e73b8d5834bb2a010/duckdb-0.6.1-cp39-cp39-win32.whl",hashes = {sha256 = "d9212d76e90b8469743924a4d22bef845be310d0d193d54ae17d9ef1f753cfa7"}}, - {name = "duckdb-0.6.1-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8d/3d/2c5e19de3eb44213cb860d095e597eaa0e264ce34c918bb8a239b3b2c03d/duckdb-0.6.1-cp39-cp39-win_amd64.whl",hashes = {sha256 = "00b7be8f67ec1a8edaa8844f521267baa1a795f4c482bfad56c72c26e1862ab2"}}, +version = "0.7.1" +sdist = {name = "duckdb-0.7.1.tar.gz", url = "https://files.pythonhosted.org/packages/17/1f/50d7128d768910e7d1304476144fa75e5ee477bc5ce55c517418a7aa89aa/duckdb-0.7.1.tar.gz", hashes = {sha256 = "a7db6da0366b239ea1e4541fcc19556b286872f5015c9a54c2e347146e25a2ad"}} +wheels = [ + {name = "duckdb-0.7.1-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/f0/50/b18438bd9b50613c77085b49d63c2220d40959dac157c87e1af396209c55/duckdb-0.7.1-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "54606dfd24d7181d3098030ca6858f6be52f3ccbf42fff05f7587f2d9cdf4343"}}, + {name = "duckdb-0.7.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/0a/56/69188b534126e6492d7bb99db84734690c12d05e29d362c8def9d169732e/duckdb-0.7.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "bd9367ae650b6605ffe00412183cf0edb688a5fc9fbb03ed757e8310e7ec3b6c"}}, + {name = "duckdb-0.7.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e9/68/6a34414619ac36b8f8e88bf6ea83b54f2966e4d948d199ec9b733c4716f6/duckdb-0.7.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "aaf33aeb543c7816bd915cd10141866d54f92f698e1b5712de9d8b7076da19df"}}, + {name = "duckdb-0.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/3f/f3/8fe095ceead5bbc3c15fd92322d4c20f2fefccac2cee32777303c6b396e0/duckdb-0.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "2e56b0329c38c0356b40449917bab6fce6ac27d356257b9a9da613d2a0f064e0"}}, + {name = "duckdb-0.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/25/d6/adf293922cc3bbf03de6efa4f15f773d3ccb0a84fb2aec902a25e6d924b5/duckdb-0.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "604b8b476d6cc6bf91625d8c2722ef9c50c402b3d64bc518c838d6c279e6d93b"}}, + {name = "duckdb-0.7.1-cp311-cp311-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/6d/f9/a8561235b2796fc5d616254c2f614c8ebb362c18480b37b8abe74631874c/duckdb-0.7.1-cp311-cp311-musllinux_1_1_i686.whl",hashes = {sha256 = "32a268508c6d7fdc99d5442736051de74c28a5166c4cc3dcbbf35d383299b941"}}, + {name = "duckdb-0.7.1-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/e0/37/165030849faf8c123c8c7393260ed7779bd8a0ac60d57bb61f72fafaadab/duckdb-0.7.1-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "90794406fa2111414877ee9db154fef940911f3920c312c1cf69947621737c8d"}}, + {name = "duckdb-0.7.1-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/7c/65/8114a523f9d369c7ba0b1aba9ac5695357767568f080b5fde4c5d3b1a502/duckdb-0.7.1-cp311-cp311-win32.whl",hashes = {sha256 = "bf20c5ee62cbbf10b39ebdfd70d454ce914e70545c7cb6cb78cb5befef96328a"}}, + {name = "duckdb-0.7.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a0/0e/97a3f1d717bb4969b9a6fe86c7c3e2c4050d36a5d992a5a8dcbfb00da867/duckdb-0.7.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "bb2700785cab37cd1e7a76c4547a5ab0f8a7c28ad3f3e4d02a8fae52be223090"}}, + {name = "duckdb-0.7.1-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/17/4c/49928ee4b0b7a4ac5466f8caa2b0b6d51b8547bcea9692ffac0bf1948f1f/duckdb-0.7.1-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "3e0170be6cc315c179169dfa3e06485ef7009ef8ce399cd2908f29105ef2c67b"}}, + {name = "duckdb-0.7.1-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/08/4a/180fa637efc60e89cfdfa38103dfce03dfead171db05bd75a0b8f18ae0c8/duckdb-0.7.1-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "6360d41023e726646507d5479ba60960989a09f04527b36abeef3643c61d8c48"}}, + {name = "duckdb-0.7.1-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/9b/85c6c8262a76196218fd9fff36e2f59ea04dcc5773ff5e296c79f4053951/duckdb-0.7.1-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "578c269d7aa27184e8d45421694f89deda3f41fe6bd2a8ce48b262b9fc975326"}}, + {name = "duckdb-0.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/5f/db/dbfddb1c320b593a3539ec698a20a5741ddcc1acb81d5dd19a485f815633/duckdb-0.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "36aae9a923c9f78da1cf3fcf75873f62d32ea017d4cef7c706d16d3eca527ca2"}}, + {name = "duckdb-0.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/72/808bf4a16321fc92abf5a14cd67338466bd14e21e3397f61c93cb3b5139c/duckdb-0.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "630e0122a02f19bb1fafae00786350b2c31ae8422fce97c827bd3686e7c386af"}}, + {name = "duckdb-0.7.1-cp310-cp310-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/22/ea/ccc3f7082d8a1b8627107d612988a7dc6a44b70862c10728f3e8d5e23b3a/duckdb-0.7.1-cp310-cp310-musllinux_1_1_i686.whl",hashes = {sha256 = "9b9ca2d294725e523ce207bc37f28787478ae6f7a223e2cf3a213a2d498596c3"}}, + {name = "duckdb-0.7.1-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/a0/3d/931fd20729506f5c83fa5f3e58df960d4f378440d7a8bef736f1508869a4/duckdb-0.7.1-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "0bd89f388205b6c99b62650169efe9a02933555ee1d46ddf79fbd0fb9e62652b"}}, + {name = "duckdb-0.7.1-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/e3/ad/068cd08e8aa30f10e480a2ce323709293b83e75c0b66c6be0a42c313abdc/duckdb-0.7.1-cp310-cp310-win32.whl",hashes = {sha256 = "a9e987565a268fd8da9f65e54621d28f39c13105b8aee34c96643074babe6d9c"}}, + {name = "duckdb-0.7.1-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1e/2d/a45ef237d190e9811a4461afea431f56a99032a7204a74aee23d4598e6bc/duckdb-0.7.1-cp310-cp310-win_amd64.whl",hashes = {sha256 = "5d986b5ad1307b069309f9707c0c5051323e29865aefa059eb6c3b22dc9751b6"}}, ] marker = "\"default\" in dependency_groups" [packages.tool.pdm] -dependencies = [ - "numpy>=1.14", -] +dependencies = [] [[packages]] name = "coverage" -version = "7.9.2" +version = "7.10.7" requires-python = ">=3.9" -sdist = {name = "coverage-7.9.2.tar.gz", url = "https://files.pythonhosted.org/packages/04/b7/c0465ca253df10a9e8dae0692a4ae6e9726d245390aaef92360e1d6d3832/coverage-7.9.2.tar.gz", hashes = {sha256 = "997024fa51e3290264ffd7492ec97d0690293ccd2b45a6cd7d82d945a4a80c8b"}} -wheels = [ - {name = "coverage-7.9.2-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/94/9d/7a8edf7acbcaa5e5c489a646226bed9591ee1c5e6a84733c0140e9ce1ae1/coverage-7.9.2-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "985abe7f242e0d7bba228ab01070fde1d6c8fa12f142e43debe9ed1dde686038"}}, - {name = "coverage-7.9.2-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e8/9e/5cd6f130150712301f7e40fb5865c1bc27b97689ec57297e568d972eec3c/coverage-7.9.2-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "82c3939264a76d44fde7f213924021ed31f55ef28111a19649fec90c0f109e6d"}}, - {name = "coverage-7.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a8/de/6287a2c2036f9fd991c61cefa8c64e57390e30c894ad3aa52fac4c1e14a8/coverage-7.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "ae5d563e970dbe04382f736ec214ef48103d1b875967c89d83c6e3f21706d5b3"}}, - {name = "coverage-7.9.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/06/cc/9b5a9961d8160e3cb0b558c71f8051fe08aa2dd4b502ee937225da564ed1/coverage-7.9.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "bdd612e59baed2a93c8843c9a7cb902260f181370f1d772f4842987535071d14"}}, - {name = "coverage-7.9.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/49/d9/4616b787d9f597d6443f5588619c1c9f659e1f5fc9eebf63699eb6d34b78/coverage-7.9.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "256ea87cb2a1ed992bcdfc349d8042dcea1b80436f4ddf6e246d6bee4b5d73b6"}}, - {name = "coverage-7.9.2-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/48/83/801cdc10f137b2d02b005a761661649ffa60eb173dcdaeb77f571e4dc192/coverage-7.9.2-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f44ae036b63c8ea432f610534a2668b0c3aee810e7037ab9d8ff6883de480f5b"}}, - {name = "coverage-7.9.2-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c8/a4/41911ed7e9d3ceb0ffb019e7635468df7499f5cc3edca5f7dfc078e9c5ec/coverage-7.9.2-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "82d76ad87c932935417a19b10cfe7abb15fd3f923cfe47dbdaa74ef4e503752d"}}, - {name = "coverage-7.9.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/10/41/344543b71d31ac9cb00a664d5d0c9ef134a0fe87cb7d8430003b20fa0b7d/coverage-7.9.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "619317bb86de4193debc712b9e59d5cffd91dc1d178627ab2a77b9870deb2868"}}, - {name = "coverage-7.9.2-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/d5/81/3b68c77e4812105e2a060f6946ba9e6f898ddcdc0d2bfc8b4b152a9ae522/coverage-7.9.2-cp313-cp313-win32.whl",hashes = {sha256 = "0a07757de9feb1dfafd16ab651e0f628fd7ce551604d1bf23e47e1ddca93f08a"}}, - {name = "coverage-7.9.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/06/a2/7fac400f6a346bb1a4004eb2a76fbff0e242cd48926a2ce37a22a6a1d917/coverage-7.9.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "115db3d1f4d3f35f5bb021e270edd85011934ff97c8797216b62f461dd69374b"}}, - {name = "coverage-7.9.2-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/08/47/2c6c215452b4f90d87017e61ea0fd9e0486bb734cb515e3de56e2c32075f/coverage-7.9.2-cp313-cp313-win_arm64.whl",hashes = {sha256 = "48f82f889c80af8b2a7bb6e158d95a3fbec6a3453a1004d04e4f3b5945a02694"}}, - {name = "coverage-7.9.2-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/a3/46/e211e942b22d6af5e0f323faa8a9bc7c447a1cf1923b64c47523f36ed488/coverage-7.9.2-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "55a28954545f9d2f96870b40f6c3386a59ba8ed50caf2d949676dac3ecab99f5"}}, - {name = "coverage-7.9.2-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d2/2f/762551f97e124442eccd907bf8b0de54348635b8866a73567eb4e6417acf/coverage-7.9.2-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "cdef6504637731a63c133bb2e6f0f0214e2748495ec15fe42d1e219d1b133f0b"}}, - {name = "coverage-7.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/7a/b7/76d2d132b7baf7360ed69be0bcab968f151fa31abe6d067f0384439d9edb/coverage-7.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "bcd5ebe66c7a97273d5d2ddd4ad0ed2e706b39630ed4b53e713d360626c3dbb3"}}, - {name = "coverage-7.9.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/a0/17/392b219837d7ad47d8e5974ce5f8dc3deb9f99a53b3bd4d123602f960c81/coverage-7.9.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "9303aed20872d7a3c9cb39c5d2b9bdbe44e3a9a1aecb52920f7e7495410dfab8"}}, - {name = "coverage-7.9.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d5/77/4256d3577fe1b0daa8d3836a1ebe68eaa07dd2cbaf20cf5ab1115d6949d4/coverage-7.9.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "bc18ea9e417a04d1920a9a76fe9ebd2f43ca505b81994598482f938d5c315f46"}}, - {name = "coverage-7.9.2-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/53/99/fc1a008eef1805e1ddb123cf17af864743354479ea5129a8f838c433cc2c/coverage-7.9.2-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "6406cff19880aaaadc932152242523e892faff224da29e241ce2fca329866584"}}, - {name = "coverage-7.9.2-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/92/c0/f63bf667e18b7f88c2bdb3160870e277c4874ced87e21426128d70aa741f/coverage-7.9.2-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "2d0d4f6ecdf37fcc19c88fec3e2277d5dee740fb51ffdd69b9579b8c31e4232e"}}, - {name = "coverage-7.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/8c/32/37dd1c42ce3016ff8ec9e4b607650d2e34845c0585d3518b2a93b4830c1a/coverage-7.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c33624f50cf8de418ab2b4d6ca9eda96dc45b2c4231336bac91454520e8d1fac"}}, - {name = "coverage-7.9.2-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/da/2e/af6b86f7c95441ce82f035b3affe1cd147f727bbd92f563be35e2d585683/coverage-7.9.2-cp313-cp313t-win32.whl",hashes = {sha256 = "1df6b76e737c6a92210eebcb2390af59a141f9e9430210595251fbaf02d46926"}}, - {name = "coverage-7.9.2-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/4d/bb/8a785d91b308867f6b2e36e41c569b367c00b70c17f54b13ac29bcd2d8c8/coverage-7.9.2-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "f5fd54310b92741ebe00d9c0d1d7b2b27463952c022da6d47c175d246a98d1bd"}}, - {name = "coverage-7.9.2-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/1d/a0/a6bffb5e0f41a47279fd45a8f3155bf193f77990ae1c30f9c224b61cacb0/coverage-7.9.2-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "c48c2375287108c887ee87d13b4070a381c6537d30e8487b24ec721bf2a781cb"}}, - {name = "coverage-7.9.2-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/53/d7/7deefc6fd4f0f1d4c58051f4004e366afc9e7ab60217ac393f247a1de70a/coverage-7.9.2-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "ae9eb07f1cfacd9cfe8eaee6f4ff4b8a289a668c39c165cd0c8548484920ffc0"}}, - {name = "coverage-7.9.2-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/95/0c/ee03c95d32be4d519e6a02e601267769ce2e9a91fc8faa1b540e3626c680/coverage-7.9.2-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "9ce85551f9a1119f02adc46d3014b5ee3f765deac166acf20dbb851ceb79b6f3"}}, - {name = "coverage-7.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/8b/9f/826fa4b544b27620086211b87a52ca67592622e1f3af9e0a62c87aea153a/coverage-7.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "f8f6389ac977c5fb322e0e38885fbbf901743f79d47f50db706e7644dcdcb6e1"}}, - {name = "coverage-7.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/7f/b3/4477aafe2a546427b58b9c540665feff874f4db651f4d3cb21b308b3a6d2/coverage-7.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "ff0d9eae8cdfcd58fe7893b88993723583a6ce4dfbfd9f29e001922544f95615"}}, - {name = "coverage-7.9.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/c2/efffa43778490c226d9d434827702f2dfbc8041d79101a795f11cbb2cf1e/coverage-7.9.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "fae939811e14e53ed8a9818dad51d434a41ee09df9305663735f2e2d2d7d959b"}}, - {name = "coverage-7.9.2-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c6/e7/a59888e882c9a5f0192d8627a30ae57910d5d449c80229b55e7643c078c4/coverage-7.9.2-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "31991156251ec202c798501e0a42bbdf2169dcb0f137b1f5c0f4267f3fc68ef9"}}, - {name = "coverage-7.9.2-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/92/a5/72fcd653ae3d214927edc100ce67440ed8a0a1e3576b8d5e6d066ed239db/coverage-7.9.2-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "d0d67963f9cbfc7c7f96d4ac74ed60ecbebd2ea6eeb51887af0f8dce205e545f"}}, - {name = "coverage-7.9.2-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5c/f5/84e70e4df28f4a131d580d7d510aa1ffd95037293da66fd20d446090a13b/coverage-7.9.2-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "49b752a2858b10580969ec6af6f090a9a440a64a301ac1528d7ca5f7ed497f4d"}}, - {name = "coverage-7.9.2-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/39/e7/d73d7cbdbd09fdcf4642655ae843ad403d9cbda55d725721965f3580a314/coverage-7.9.2-cp312-cp312-win32.whl",hashes = {sha256 = "88d7598b8ee130f32f8a43198ee02edd16d7f77692fa056cb779616bbea1b355"}}, - {name = "coverage-7.9.2-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/d6/7486dcc3474e2e6ad26a2af2db7e7c162ccd889c4c68fa14ea8ec189c9e9/coverage-7.9.2-cp312-cp312-win_amd64.whl",hashes = {sha256 = "9dfb070f830739ee49d7c83e4941cc767e503e4394fdecb3b54bfdac1d7662c0"}}, - {name = "coverage-7.9.2-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/b7/34/0439f1ae2593b0346164d907cdf96a529b40b7721a45fdcf8b03c95fcd90/coverage-7.9.2-cp312-cp312-win_arm64.whl",hashes = {sha256 = "4e2c058aef613e79df00e86b6d42a641c877211384ce5bd07585ed7ba71ab31b"}}, - {name = "coverage-7.9.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/39/40/916786453bcfafa4c788abee4ccd6f592b5b5eca0cd61a32a4e5a7ef6e02/coverage-7.9.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "a7a56a2964a9687b6aba5b5ced6971af308ef6f79a91043c05dd4ee3ebc3e9ba"}}, - {name = "coverage-7.9.2-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/9f/66/cc13bae303284b546a030762957322bbbff1ee6b6cb8dc70a40f8a78512f/coverage-7.9.2-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "123d589f32c11d9be7fe2e66d823a236fe759b0096f5db3fb1b75b2fa414a4fa"}}, - {name = "coverage-7.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/0f/3c/d56a764b2e5a3d43257c36af4a62c379df44636817bb5f89265de4bf8bd7/coverage-7.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "333b2e0ca576a7dbd66e85ab402e35c03b0b22f525eed82681c4b866e2e2653a"}}, - {name = "coverage-7.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/b1/46/bd064ea8b3c94eb4ca5d90e34d15b806cba091ffb2b8e89a0d7066c45791/coverage-7.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "326802760da234baf9f2f85a39e4a4b5861b94f6c8d95251f699e4f73b1835dc"}}, - {name = "coverage-7.9.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/02/d91992c2b29bc7afb729463bc918ebe5f361be7f1daae93375a5759d1e28/coverage-7.9.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "19e7be4cfec248df38ce40968c95d3952fbffd57b400d4b9bb580f28179556d2"}}, - {name = "coverage-7.9.2-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b7/4f/8fadff6bf56595a16d2d6e33415841b0163ac660873ed9a4e9046194f779/coverage-7.9.2-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0b4a4cb73b9f2b891c1788711408ef9707666501ba23684387277ededab1097c"}}, - {name = "coverage-7.9.2-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/9b/d2/e0be7446a2bba11739edb9f9ba4eff30b30d8257370e237418eb44a14d11/coverage-7.9.2-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "2c8937fa16c8c9fbbd9f118588756e7bcdc7e16a470766a9aef912dd3f117dbd"}}, - {name = "coverage-7.9.2-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9d/7d/dcbac9345000121b8b57a3094c2dfcf1ccc52d8a14a40c1d4bc89f936f80/coverage-7.9.2-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "42da2280c4d30c57a9b578bafd1d4494fa6c056d4c419d9689e66d775539be74"}}, - {name = "coverage-7.9.2-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/41/58/11e8db0a0c0510cf31bbbdc8caf5d74a358b696302a45948d7c768dfd1cf/coverage-7.9.2-cp311-cp311-win32.whl",hashes = {sha256 = "14fa8d3da147f5fdf9d298cacc18791818f3f1a9f542c8958b80c228320e90c6"}}, - {name = "coverage-7.9.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3a/7d/751794ec8907a15e257136e48dc1021b1f671220ecccfd6c4eaf30802714/coverage-7.9.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "549cab4892fc82004f9739963163fd3aac7a7b0df430669b75b86d293d2df2a7"}}, - {name = "coverage-7.9.2-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/62/5b/34abcedf7b946c1c9e15b44f326cb5b0da852885312b30e916f674913428/coverage-7.9.2-cp311-cp311-win_arm64.whl",hashes = {sha256 = "c2667a2b913e307f06aa4e5677f01a9746cd08e4b35e14ebcde6420a9ebb4c62"}}, - {name = "coverage-7.9.2-pp39.pp310.pp311-none-any.whl",url = "https://files.pythonhosted.org/packages/d7/85/f8bbefac27d286386961c25515431482a425967e23d3698b75a250872924/coverage-7.9.2-pp39.pp310.pp311-none-any.whl",hashes = {sha256 = "8a1166db2fb62473285bcb092f586e081e92656c7dfa8e9f62b4d39d7e6b5050"}}, - {name = "coverage-7.9.2-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/a1/0d/5c2114fd776c207bd55068ae8dc1bef63ecd1b767b3389984a8e58f2b926/coverage-7.9.2-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "66283a192a14a3854b2e7f3418d7db05cdf411012ab7ff5db98ff3b181e1f912"}}, - {name = "coverage-7.9.2-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/cf/ad/dc51f40492dc2d5fcd31bb44577bc0cc8920757d6bc5d3e4293146524ef9/coverage-7.9.2-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "4e01d138540ef34fcf35c1aa24d06c3de2a4cffa349e29a10056544f35cca15f"}}, - {name = "coverage-7.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a2/a3/55cb3ff1b36f00df04439c3993d8529193cdf165a2467bf1402539070f16/coverage-7.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "f22627c1fe2745ee98d3ab87679ca73a97e75ca75eb5faee48660d060875465f"}}, - {name = "coverage-7.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/eb/c9/a8410b91b6be4f6e9c2e9f0dce93749b6b40b751d7065b4410bf89cb654b/coverage-7.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "4b1c2d8363247b46bd51f393f86c94096e64a1cf6906803fa8d5a9d03784bdbf"}}, - {name = "coverage-7.9.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/c4/6f3e56d467c612b9070ae71d5d3b114c0b899b5788e1ca3c93068ccb7018/coverage-7.9.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "c10c882b114faf82dbd33e876d0cbd5e1d1ebc0d2a74ceef642c6152f3f4d547"}}, - {name = "coverage-7.9.2-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/fd/20/04eda789d15af1ce79bce5cc5fd64057c3a0ac08fd0576377a3096c24663/coverage-7.9.2-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "de3c0378bdf7066c3988d66cd5232d161e933b87103b014ab1b0b4676098fa45"}}, - {name = "coverage-7.9.2-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a9/5a/217b32c94cc1a0b90f253514815332d08ec0812194a1ce9cca97dda1cd20/coverage-7.9.2-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "1e2f097eae0e5991e7623958a24ced3282676c93c013dde41399ff63e230fcf2"}}, - {name = "coverage-7.9.2-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/73/1d019c48f413465eb5d3b6898b6279e87141c80049f7dbf73fd020138549/coverage-7.9.2-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "28dc1f67e83a14e7079b6cea4d314bc8b24d1aed42d3582ff89c0295f09b181e"}}, - {name = "coverage-7.9.2-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/49/6c/a2beca7aa2595dad0c0d3f350382c381c92400efe5261e2631f734a0e3fe/coverage-7.9.2-cp310-cp310-win32.whl",hashes = {sha256 = "bf7d773da6af9e10dbddacbf4e5cab13d06d0ed93561d44dae0188a42c65be7e"}}, - {name = "coverage-7.9.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fc/c8/91e5e4a21f9a51e2c7cdd86e587ae01a4fcff06fc3fa8cde4d6f7cf68df4/coverage-7.9.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "0c0378ba787681ab1897f7c89b415bd56b0b2d9a47e5a3d8dc0ea55aac118d6c"}}, - {name = "coverage-7.9.2-cp39-cp39-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/ab/b4b06662ccaa00ca7bbee967b7035a33a58b41efb92d8c89a6c523a2ccd5/coverage-7.9.2-cp39-cp39-macosx_10_9_x86_64.whl",hashes = {sha256 = "ddc39510ac922a5c4c27849b739f875d3e1d9e590d1e7b64c98dadf037a16cce"}}, - {name = "coverage-7.9.2-cp39-cp39-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/5e/04619995657acc898d15bfad42b510344b3a74d4d5bc34f2e279d46c781c/coverage-7.9.2-cp39-cp39-macosx_11_0_arm64.whl",hashes = {sha256 = "a535c0c7364acd55229749c2b3e5eebf141865de3a8f697076a3291985f02d30"}}, - {name = "coverage-7.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/14/e7/1465710224dc6d31c534e7714cbd907210622a044adc81c810e72eea873f/coverage-7.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "df0f9ef28e0f20c767ccdccfc5ae5f83a6f4a2fbdfbcbcc8487a8a78771168c8"}}, - {name = "coverage-7.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/ab/f2/44c6fbd2794afeb9ab6c0a14d3c088ab1dae3dff3df2624609981237bbb4/coverage-7.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "2f3da12e0ccbcb348969221d29441ac714bbddc4d74e13923d3d5a7a0bebef7a"}}, - {name = "coverage-7.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/6a/d2/7a79845429c0aa2e6788bc45c26a2e3052fa91082c9ea1dea56fb531952c/coverage-7.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "0a17eaf46f56ae0f870f14a3cbc2e4632fe3771eab7f687eda1ee59b73d09fe4"}}, - {name = "coverage-7.9.2-cp39-cp39-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9c/7d/2731d1b4c9c672d82d30d218224dfc62939cf3800bc8aba0258fefb191f5/coverage-7.9.2-cp39-cp39-musllinux_1_2_aarch64.whl",hashes = {sha256 = "669135a9d25df55d1ed56a11bf555f37c922cf08d80799d4f65d77d7d6123fcf"}}, - {name = "coverage-7.9.2-cp39-cp39-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/1b/83/685958715429a9da09cf172c15750ca5c795dd7259466f2645403696557b/coverage-7.9.2-cp39-cp39-musllinux_1_2_i686.whl",hashes = {sha256 = "9d3a700304d01a627df9db4322dc082a0ce1e8fc74ac238e2af39ced4c083193"}}, - {name = "coverage-7.9.2-cp39-cp39-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/ff/161a4313308b3783126790adfae1970adbe4886fda8788792e435249910a/coverage-7.9.2-cp39-cp39-musllinux_1_2_x86_64.whl",hashes = {sha256 = "71ae8b53855644a0b1579d4041304ddc9995c7b21c8a1f16753c4d8903b4dfed"}}, - {name = "coverage-7.9.2-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/17/14/fe33f41b2e80811021de059621f44c01ebe4d6b08bdb82d54a514488e933/coverage-7.9.2-cp39-cp39-win32.whl",hashes = {sha256 = "dd7a57b33b5cf27acb491e890720af45db05589a80c1ffc798462a765be6d4d7"}}, - {name = "coverage-7.9.2-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/6e/30/63d850ec31b5c6f6a7b4e853016375b846258300320eda29376e2786ceeb/coverage-7.9.2-cp39-cp39-win_amd64.whl",hashes = {sha256 = "f65bb452e579d5540c8b37ec105dd54d8b9307b07bcaa186818c104ffda22441"}}, - {name = "coverage-7.9.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3c/38/bbe2e63902847cf79036ecc75550d0698af31c91c7575352eb25190d0fb3/coverage-7.9.2-py3-none-any.whl",hashes = {sha256 = "e425cd5b00f6fc0ed7cdbd766c70be8baab4b7839e4d4fe5fac48581dd968ea4"}}, +sdist = {name = "coverage-7.10.7.tar.gz", url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hashes = {sha256 = "f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239"}} +wheels = [ + {name = "coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520"}}, + {name = "coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd"}}, + {name = "coverage-7.10.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl",hashes = {sha256 = "b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2"}}, + {name = "coverage-7.10.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681"}}, + {name = "coverage-7.10.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880"}}, + {name = "coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63"}}, + {name = "coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399"}}, + {name = "coverage-7.10.7-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl",hashes = {sha256 = "67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235"}}, + {name = "coverage-7.10.7-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d"}}, + {name = "coverage-7.10.7-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a"}}, + {name = "coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d"}}, + {name = "coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f"}}, + {name = "coverage-7.10.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl",hashes = {sha256 = "dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698"}}, + {name = "coverage-7.10.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843"}}, + {name = "coverage-7.10.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546"}}, + {name = "coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c"}}, + {name = "coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2"}}, + {name = "coverage-7.10.7-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl",hashes = {sha256 = "2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a"}}, + {name = "coverage-7.10.7-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb"}}, + {name = "coverage-7.10.7-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb"}}, + {name = "coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/13/e4/eb12450f71b542a53972d19117ea5a5cea1cab3ac9e31b0b5d498df1bd5a/coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "7bb3b9ddb87ef7725056572368040c32775036472d5a033679d1fa6c8dc08417"}}, + {name = "coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/37/66/593f9be12fc19fb36711f19a5371af79a718537204d16ea1d36f16bd78d2/coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "18afb24843cbc175687225cab1138c95d262337f5473512010e46831aa0c2973"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/66/80/4c49f7ae09cafdacc73fbc30949ffe77359635c168f4e9ff33c9ebb07838/coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "399a0b6347bcd3822be369392932884b8216d0944049ae22925631a9b3d4ba4c"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a6/90/a64aaacab3b37a17aaedd83e8000142561a29eb262cede42d94a67f7556b/coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "314f2c326ded3f4b09be11bc282eb2fc861184bc95748ae67b360ac962770be7"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/2e/2dda59afd6103b342e096f246ebc5f87a3363b5412609946c120f4e7750d/coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c41e71c9cfb854789dee6fc51e46743a6d138b1803fab6cb860af43265b42ea6"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/53/dc/8d8119c9051d50f3119bb4a75f29f1e4a6ab9415cd1fa8bf22fcc3fb3b5f/coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "bc01f57ca26269c2c706e838f6422e2a8788e41b3e3c65e2f41148212e57cd59"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/b3/edaff9c5d79ee4d4b6d3fe046f2b1d799850425695b789d491a64225d493/coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a6442c59a8ac8b85812ce33bc4d05bde3fb22321fa8294e2a5b487c3505f611b"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/11/25/9a0728564bb05863f7e513e5a594fe5ffef091b325437f5430e8cfb0d530/coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "78a384e49f46b80fb4c901d52d92abe098e78768ed829c673fbb53c498bef73a"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/fd/ca2650443bfbef5b0e74373aac4df67b08180d2f184b482c41499668e258/coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "5e1e9802121405ede4b0133aa4340ad8186a1d2526de5b7c3eca519db7bb89fb"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/24/79/f692f125fb4299b6f963b0745124998ebb8e73ecdfce4ceceb06a8c6bec5/coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "d41213ea25a86f69efd1575073d34ea11aabe075604ddf3d148ecfec9e1e96a1"}}, + {name = "coverage-7.10.7-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/5e/75/61b9bbd6c7d24d896bfeec57acba78e0f8deac68e6baf2d4804f7aae1f88/coverage-7.10.7-cp312-cp312-win32.whl",hashes = {sha256 = "77eb4c747061a6af8d0f7bdb31f1e108d172762ef579166ec84542f711d90256"}}, + {name = "coverage-7.10.7-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ca/f3/3bf7905288b45b075918d372498f1cf845b5b579b723c8fd17168018d5f5/coverage-7.10.7-cp312-cp312-win_amd64.whl",hashes = {sha256 = "f51328ffe987aecf6d09f3cd9d979face89a617eacdaea43e7b3080777f647ba"}}, + {name = "coverage-7.10.7-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/5c/44/3e32dbe933979d05cf2dac5e697c8599cfe038aaf51223ab901e208d5a62/coverage-7.10.7-cp312-cp312-win_arm64.whl",hashes = {sha256 = "bda5e34f8a75721c96085903c6f2197dc398c20ffd98df33f866a9c8fd95f4bf"}}, + {name = "coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/5d/c1a17867b0456f2e9ce2d8d4708a4c3a089947d0bec9c66cdf60c9e7739f/coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "a609f9c93113be646f44c2a0256d6ea375ad047005d7f57a5c15f614dc1b2f59"}}, + {name = "coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/54/f0/514dcf4b4e3698b9a9077f084429681bf3aad2b4a72578f89d7f643eb506/coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "65646bb0359386e07639c367a22cf9b5bf6304e8630b565d0626e2bdf329227a"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/20/f6/9626b81d17e2a4b25c63ac1b425ff307ecdeef03d67c9a147673ae40dc36/coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "5f33166f0dfcce728191f520bd2692914ec70fac2713f6bf3ce59c3deacb4699"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/b0/ef/bd8e719c2f7417ba03239052e099b76ea1130ac0cbb183ee1fcaa58aaff3/coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "35f5e3f9e455bb17831876048355dca0f758b6df22f49258cb5a91da23ef437d"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a5/b6/bf054de41ec948b151ae2b79a55c107f5760979538f5fb80c195f2517718/coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4da86b6d62a496e908ac2898243920c7992499c1712ff7c2b6d837cc69d9467e"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/0f/e5/3860756aa6f9318227443c6ce4ed7bf9e70bb7f1447a0353f45ac5c7974b/coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "6b8b09c1fad947c84bbbc95eca841350fad9cbfa5a2d7ca88ac9f8d836c92e23"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/26/0f/bd08bd042854f7fd07b45808927ebcce99a7ed0f2f412d11629883517ac2/coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4376538f36b533b46f8971d3a3e63464f2c7905c9800db97361c43a2b14792ab"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/8e/a7/4777b14de4abcc2e80c6b1d430f5d51eb18ed1d75fca56cbce5f2db9b36e/coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "121da30abb574f6ce6ae09840dae322bef734480ceafe410117627aa54f76d82"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/34/72/17d082b00b53cd45679bad682fac058b87f011fd8b9fe31d77f5f8d3a4e4/coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "88127d40df529336a9836870436fc2751c339fbaed3a836d42c93f3e4bd1d0a2"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/7a/92367572eb5bdd6a84bfa278cc7e97db192f9f45b28c94a9ca1a921c3577/coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ba58bbcd1b72f136080c0bccc2400d66cc6115f3f906c499013d065ac33a4b61"}}, + {name = "coverage-7.10.7-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/2f/88/a23cc185f6a805dfc4fdf14a94016835eeb85e22ac3a0e66d5e89acd6462/coverage-7.10.7-cp311-cp311-win32.whl",hashes = {sha256 = "972b9e3a4094b053a4e46832b4bc829fc8a8d347160eb39d03f1690316a99c14"}}, + {name = "coverage-7.10.7-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fe/ef/0b510a399dfca17cec7bc2f05ad8bd78cf55f15c8bc9a73ab20c5c913c2e/coverage-7.10.7-cp311-cp311-win_amd64.whl",hashes = {sha256 = "a7b55a944a7f43892e28ad4bc0561dfd5f0d73e605d1aa5c3c976b52aea121d2"}}, + {name = "coverage-7.10.7-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/7f/023657f301a276e4ba1850f82749bc136f5a7e8768060c2e5d9744a22951/coverage-7.10.7-cp311-cp311-win_arm64.whl",hashes = {sha256 = "736f227fb490f03c6488f9b6d45855f8e0fd749c007f9303ad30efab0e73c05a"}}, + {name = "coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/e5/6c/3a3f7a46888e69d18abe3ccc6fe4cb16cccb1e6a2f99698931dafca489e6/coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "fc04cc7a3db33664e0c2d10eb8990ff6b3536f6842c9590ae8da4c614b9ed05a"}}, + {name = "coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/03/94/952d30f180b1a916c11a56f5c22d3535e943aa22430e9e3322447e520e1c/coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "e201e015644e207139f7e2351980feb7040e6f4b2c2978892f3e3789d1c125e5"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/50/2b/9e0cf8ded1e114bcd8b2fd42792b57f1c4e9e4ea1824cde2af93a67305be/coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "240af60539987ced2c399809bd34f7c78e8abe0736af91c3d7d0e795df633d17"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/19/20/d0384ac06a6f908783d9b6aa6135e41b093971499ec488e47279f5b846e6/coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8421e088bc051361b01c4b3a50fd39a4b9133079a2229978d9d30511fd05231b"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/60/83/5c283cff3d41285f8eab897651585db908a909c572bdc014bcfaf8a8b6ae/coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6be8ed3039ae7f7ac5ce058c308484787c86e8437e72b30bf5e88b8ea10f3c87"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/60/22/02eb98fdc5ff79f423e990d877693e5310ae1eab6cb20ae0b0b9ac45b23b/coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e28299d9f2e889e6d51b1f043f58d5f997c373cc12e6403b90df95b8b047c13e"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b4/bc/25c83bcf3ad141b32cd7dc45485ef3c01a776ca3aa8ef0a93e77e8b5bc43/coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c4e16bd7761c5e454f4efd36f345286d6f7c5fa111623c355691e2755cae3b9e"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3c/b7/95574702888b58c0928a6e982038c596f9c34d52c5e5107f1eef729399b5/coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "b1c81d0e5e160651879755c9c675b974276f135558cf4ba79fee7b8413a515df"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/47/b6/40095c185f235e085df0e0b158f6bd68cc6e1d80ba6c7721dc81d97ec318/coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "606cc265adc9aaedcc84f1f064f0e8736bc45814f15a357e30fca7ecc01504e0"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c8/50/4aea0556da7a4b93ec9168420d170b55e2eb50ae21b25062513d020c6861/coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "10b24412692df990dbc34f8fb1b6b13d236ace9dfdd68df5b28c2e39cafbba13"}}, + {name = "coverage-7.10.7-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/6a/28/ea1a84a60828177ae3b100cb6723838523369a44ec5742313ed7db3da160/coverage-7.10.7-cp310-cp310-win32.whl",hashes = {sha256 = "b51dcd060f18c19290d9b8a9dd1e0181538df2ce0717f562fff6cf74d9fc0b5b"}}, + {name = "coverage-7.10.7-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fc/1a/a81d46bbeb3c3fd97b9602ebaa411e076219a150489bcc2c025f151bd52d/coverage-7.10.7-cp310-cp310-win_amd64.whl",hashes = {sha256 = "3a622ac801b17198020f09af3eaf45666b344a0d69fc2a6ffe2ea83aeef1d807"}}, + {name = "coverage-7.10.7-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl",hashes = {sha256 = "f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260"}}, ] marker = "\"test\" in dependency_groups" @@ -261,15 +276,6 @@ wheels = [ {name = "orjson-3.9.0-cp310-cp310-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/49/a1/de519d9901d92ef086d8ddfc80d63a2ee51871887af5397ed4896cf06202/orjson-3.9.0-cp310-cp310-musllinux_1_1_aarch64.whl",hashes = {sha256 = "2536a7f30fd4d77532769ea9285cd20c69bd2b40acf980de94bbc79b1c6fad5a"}}, {name = "orjson-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/e3/96/fa927d1c19866b11dcfaf56d4de9d29b4ec4c14786b4a8c816cb58bb7e95/orjson-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "21f6a6fdfbc13cd715c61e9fa9daeff732df6401ab7d6a2ebad0042313a40bd1"}}, {name = "orjson-3.9.0-cp310-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/df/8c/1184f03df5233823f88a1d3c5c1878f985a9958d06512d875fc9f8f5340b/orjson-3.9.0-cp310-none-win_amd64.whl",hashes = {sha256 = "46c9733330b75c116438f555c0b971a2388b5f502e2dd4ec3bf6bacb96f82741"}}, - {name = "orjson-3.9.0-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/5c/ca/4d7a76381df4119c9ccfdaae1ab62004ed909f24519673118c3ad651a857/orjson-3.9.0-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "a901c432828c191332d75f358142736c433d4a192f7794123e1d30d68193de86"}}, - {name = "orjson-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/b2/95/707184b9b991a58bc8f290aed0c3942f642e85c089f0228168af41e54cf3/orjson-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "271b6f1018757fc6bca40ae72e6cdb6cf84584dde2d1e5eaac30e387a13d9e72"}}, - {name = "orjson-3.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/8b/8a/59611e84d2d76f5eb23ffaa9c7c8aaa728174b5e1cb86c6a29b8418ec349/orjson-3.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "949698bdddb1daff986d73e6bbe6cd68833cd80c4adc6b69fafbd46634d4672c"}}, - {name = "orjson-3.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/ad/c3/bdc121a246921d0699c695eb73cf56417ab487767c4f761f9425dd1bf59c/orjson-3.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "108c58d2c7648c991f82f9b2217c50981ad7cf6aaee3efbfaa9d807e49cd69b8"}}, - {name = "orjson-3.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/ee/45/47bcbad2c90b2846428bcd3a0a4623e37bb74ae3583bb96929b2e625d095/orjson-3.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "08cb43569198c1f5c89ecafcbfc62414f6115d894ff908d8cf8e5e24801364e6"}}, - {name = "orjson-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/c8/a604ad0c7f0ffb5897328e0ca4a81697c2ffe1fac3f72bbaee59b12629cb/orjson-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "09ee828572fadcd58bf356d2c1bad99a95c7c9c1f182b407abbc7dec1810f542"}}, - {name = "orjson-3.9.0-cp39-cp39-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/61/ac/1923bf83c0e36a9ac35d4c7347f715ce87b807c8692403b66047c7ac11e1/orjson-3.9.0-cp39-cp39-musllinux_1_1_aarch64.whl",hashes = {sha256 = "0e7fe5d603ee9177ff2e45858b4fc47fea2da0688f23d9773654889d56dfbc82"}}, - {name = "orjson-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/10/1f/2915887049c72a195a7991ec8e5cf0344fcd6a940a2e50abee860752b7bf/orjson-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl",hashes = {sha256 = "9ee5f1ba82146a50d61fb58d310a37c0f406eda898172f9c98673b5d6f9461c3"}}, - {name = "orjson-3.9.0-cp39-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c9/d9/0382e682322a996476ece62f92cc90cb067da3266a6a9ed71da9b49cc442/orjson-3.9.0-cp39-none-win_amd64.whl",hashes = {sha256 = "3235c31d0fe674f6e3433e9ddfed212aa840c83a9b6ef5ae128950e2c808c303"}}, ] marker = "\"default\" in dependency_groups" @@ -293,61 +299,13 @@ dependencies = [ "tzdata; sys_platform == \"win32\"", ] -[[packages]] -name = "psycopg2-binary" -version = "2.9.5" -requires-python = ">=3.6" -sdist = {name = "psycopg2-binary-2.9.5.tar.gz", url = "https://files.pythonhosted.org/packages/8c/45/77147700f5088efaf9235a3a62b611b594d477a5c5613b5316d0ebd18be0/psycopg2-binary-2.9.5.tar.gz", hashes = {sha256 = "33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c"}} -wheels = [ - {name = "psycopg2_binary-2.9.5-cp311-cp311-macosx_10_9_universal2.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/00/bcdc61fb9c96f122fa8d1afb0608160b5b7fbba935ce8058e6b74520cade/psycopg2_binary-2.9.5-cp311-cp311-macosx_10_9_universal2.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl",hashes = {sha256 = "426c2ae999135d64e6a18849a7d1ad0e1bd007277e4a8f4752eaa40a96b550ff"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/0b/71b366318c88ce6517561048b3310388c12cfe6bd038e3531cda9fe30327/psycopg2_binary-2.9.5-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "7cf1d44e710ca3a9ce952bda2855830fe9f9017ed6259e01fcd71ea6287565f5"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/e1/9b/da86cea11053996728cf473d02d63a2137a74834a0e93af4ee4c42c993ae/psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "024030b13bdcbd53d8a93891a2cf07719715724fc9fee40243f3bd78b4264b8f"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/36/af/a9f06e2469e943364b2383b45b3209b40350c105281948df62153394b4a9/psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "bcda1c84a1c533c528356da5490d464a139b6e84eb77cc0b432e38c5c6dd7882"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_aarch64.whl",url = "https://files.pythonhosted.org/packages/b9/97/61d8794442b50456f3263ca263af9fde2a1fde93811b74fe0c5a9519f6ca/psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_aarch64.whl",hashes = {sha256 = "2ef892cabdccefe577088a79580301f09f2a713eb239f4f9f62b2b29cafb0577"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_ppc64le.whl",url = "https://files.pythonhosted.org/packages/62/ed/2b7b8727677e2d4b5d53a962a2c9e11d7d141b9a5cb8681b37110d953341/psycopg2_binary-2.9.5-cp311-cp311-manylinux_2_24_ppc64le.whl",hashes = {sha256 = "af0516e1711995cb08dc19bbd05bec7dbdebf4185f68870595156718d237df3e"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/b0/82/27c5e2442ba10ab4f01de9c3bf2043581aa8e80e2f64fb64d9cc2eb847d6/psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/66/e7/4764b10034b1323d33758823883034c1347f6ebeaf2b45b60f076749d360/psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_i686.whl",hashes = {sha256 = "e67b3c26e9b6d37b370c83aa790bbc121775c57bfb096c2e77eacca25fd0233b"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl",url = "https://files.pythonhosted.org/packages/fa/52/ecd23580763212731eec723313ee3678484ed7de0d22214f6b70120aaa29/psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl",hashes = {sha256 = "5fc447058d083b8c6ac076fc26b446d44f0145308465d745fba93a28c14c9e32"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/e3/57/7b776b14f68532be17659a20741f17457e0583c800ddcc3610270cec584c/psycopg2_binary-2.9.5-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "d892bfa1d023c3781a3cab8dd5af76b626c483484d782e8bd047c180db590e4c"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/32/85/8a6dbcf799136e6085e0cfb869babb8e19843df23c405a65840bc22f6dbf/psycopg2_binary-2.9.5-cp311-cp311-win32.whl",hashes = {sha256 = "2abccab84d057723d2ca8f99ff7b619285d40da6814d50366f61f0fc385c3903"}}, - {name = "psycopg2_binary-2.9.5-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/89/ca/4eb68b87bb664a6f6c56b72ac876626c8c036b086892fb6cc803c8d38d2b/psycopg2_binary-2.9.5-cp311-cp311-win_amd64.whl",hashes = {sha256 = "bef7e3f9dc6f0c13afdd671008534be5744e0e682fb851584c8c3a025ec09720"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl",url = "https://files.pythonhosted.org/packages/53/4f/8216992bcb530c6e599f8276a27b87b5cbbc06423e68eb2668413481214c/psycopg2_binary-2.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl",hashes = {sha256 = "0775d6252ccb22b15da3b5d7adbbf8cfe284916b14b6dc0ff503a23edb01ee85"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c7/4e/c94d534a29f17b4b54b5a7e4020e9e4dc51641a9cdce806323df68d0f5ca/psycopg2_binary-2.9.5-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "2ec46ed947801652c9643e0b1dc334cfb2781232e375ba97312c2fc256597632"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/03/b8/f85694de7d17b37bc4bdc31e8e623b9727c4b7491b1e7b752f2d8b5cc8e0/psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3520d7af1ebc838cc6084a3281145d5cd5bdd43fdef139e6db5af01b92596cb7"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/72/29/e16ac3d2722f2a3bc20823e6acc30d9ad56136652cce1324502adf94da1f/psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5cbc554ba47ecca8cd3396ddaca85e1ecfe3e48dd57dc5e415e59551affe568e"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_aarch64.whl",url = "https://files.pythonhosted.org/packages/67/8d/aab7e25dd2961eb355eb889e1a668cd49635243e9b9051ac5b2f5fb7a84f/psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_aarch64.whl",hashes = {sha256 = "5d28ecdf191db558d0c07d0f16524ee9d67896edf2b7990eea800abeb23ebd61"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_ppc64le.whl",url = "https://files.pythonhosted.org/packages/25/62/b73e3441e5a291b0ea3559face0ad70ee53b10d20ebe8bf01e48006abd3e/psycopg2_binary-2.9.5-cp310-cp310-manylinux_2_24_ppc64le.whl",hashes = {sha256 = "b9c33d4aef08dfecbd1736ceab8b7b3c4358bf10a0121483e5cd60d3d308cc64"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/5c/26/5000a9f311162dc560aecc8c141bee498e061140c22b0a301a84bc5d0e0f/psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_aarch64.whl",hashes = {sha256 = "05b3d479425e047c848b9782cd7aac9c6727ce23181eb9647baf64ffdfc3da41"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/95/d5/bbaf6ea0fb7d555e86656b67e03c7bf6506ef3fdfd73470e93ce7073db19/psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_i686.whl",hashes = {sha256 = "1e491e6489a6cb1d079df8eaa15957c277fdedb102b6a68cfbf40c4994412fd0"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl",url = "https://files.pythonhosted.org/packages/17/e7/58947b0f3e6f7ed244bbc7831e42fcf1ef582e8a6c13364cb2cdf19724a3/psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl",hashes = {sha256 = "9e32cedc389bcb76d9f24ea8a012b3cb8385ee362ea437e1d012ffaed106c17d"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/91/f2/556cc32bbf1271310a6cc74f3f2852b2b8dd3231789d942bda4f4625231e/psycopg2_binary-2.9.5-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "46850a640df62ae940e34a163f72e26aca1f88e2da79148e1862faaac985c302"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/4a/49/ba8b695e63f49e09331347731253909d853dc6e5316740ef7cf0389460d9/psycopg2_binary-2.9.5-cp310-cp310-win32.whl",hashes = {sha256 = "3d790f84201c3698d1bfb404c917f36e40531577a6dda02e45ba29b64d539867"}}, - {name = "psycopg2_binary-2.9.5-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e6/a9/00b93fee5384a6e0d5fef8fecc753c9729d1f911eea90f8628a4a6310855/psycopg2_binary-2.9.5-cp310-cp310-win_amd64.whl",hashes = {sha256 = "1764546ffeaed4f9428707be61d68972eb5ede81239b46a45843e0071104d0dd"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl",url = "https://files.pythonhosted.org/packages/fa/88/e44363a9c68abfab4f596850636b4be496d479845877a507a73a651ef623/psycopg2_binary-2.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl",hashes = {sha256 = "25382c7d174c679ce6927c16b6fbb68b10e56ee44b1acb40671e02d29f2fce7c"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/63/db/67c2a94c3d89c48a2a4efc2029f6dc082faa3bc3dd14de49346c126c9600/psycopg2_binary-2.9.5-cp39-cp39-macosx_11_0_arm64.whl",hashes = {sha256 = "9c38d3869238e9d3409239bc05bc27d6b7c99c2a460ea337d2814b35fb4fea1b"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/db/c8/9f58d89b864f052a2e99cb3a9fd3e64c20984b1319b5d207eb629b4f9c40/psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "5c6527c8efa5226a9e787507652dd5ba97b62d29b53c371a85cd13f957fe4d42"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/25/5b84c484aefa78f91366eea8b778de797681a5bc626b569555011874de58/psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "e59137cdb970249ae60be2a49774c6dfb015bd0403f05af1fe61862e9626642d"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_aarch64.whl",url = "https://files.pythonhosted.org/packages/31/48/e7fe28aca3e2bf3b5fd6f73f681c0be26837b680c815b7cf53b0311a5a28/psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_aarch64.whl",hashes = {sha256 = "d4c7b3a31502184e856df1f7bbb2c3735a05a8ce0ade34c5277e1577738a5c91"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d7/4a/96d3d343ba3d7f1408f091e43bc6265267b625421e1a4aa5f4ea210013e1/psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_24_ppc64le.whl",hashes = {sha256 = "b9a794cef1d9c1772b94a72eec6da144c18e18041d294a9ab47669bc77a80c1d"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/0e/07/c689d0c42e86da7e055e3298a3854931c38e8332e571e6cdf71cedec4aa3/psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_aarch64.whl",hashes = {sha256 = "c5254cbd4f4855e11cebf678c1a848a3042d455a22a4ce61349c36aafd4c2267"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/ff/e2/e82829bbf209d9fa4ca5df95b244eab30ee170d6c3ba2bf8f0a8a02c64bf/psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_i686.whl",hashes = {sha256 = "c5e65c6ac0ae4bf5bef1667029f81010b6017795dcb817ba5c7b8a8d61fab76f"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl",url = "https://files.pythonhosted.org/packages/29/e5/9dc756e4eb496764199ca1fbee235e0b6b935c987922af2243e6e0001d24/psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl",hashes = {sha256 = "74eddec4537ab1f701a1647214734bc52cee2794df748f6ae5908e00771f180a"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/f1/39/6e2d51b2f35b4e272f9380797e1b838a1d2086f06414ea837f62a3505243/psycopg2_binary-2.9.5-cp39-cp39-musllinux_1_1_x86_64.whl",hashes = {sha256 = "01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/8f/c6/cc416da1edbeaf8e9c69eb811d4495920a6dc7fe71b689ce67db1e84bfce/psycopg2_binary-2.9.5-cp39-cp39-win32.whl",hashes = {sha256 = "937880290775033a743f4836aa253087b85e62784b63fd099ee725d567a48aa1"}}, - {name = "psycopg2_binary-2.9.5-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3e/97/d8bda00145b96d79dc9ff6790640e6b1c503c2ccadd76a45fef8dc342b95/psycopg2_binary-2.9.5-cp39-cp39-win_amd64.whl",hashes = {sha256 = "484405b883630f3e74ed32041a87456c5e0e63a8e3429aa93e8714c366d62bd1"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "pytest" -version = "8.4.1" +version = "8.4.2" requires-python = ">=3.9" -sdist = {name = "pytest-8.4.1.tar.gz", url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hashes = {sha256 = "7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c"}} +sdist = {name = "pytest-8.4.2.tar.gz", url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hashes = {sha256 = "86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}} wheels = [ - {name = "pytest-8.4.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl",hashes = {sha256 = "539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7"}}, + {name = "pytest-8.4.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl",hashes = {sha256 = "872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}}, ] marker = "\"test\" in dependency_groups" @@ -381,11 +339,11 @@ dependencies = [ [[packages]] name = "tqdm" -version = "4.64.1" +version = "4.64.0" requires-python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -sdist = {name = "tqdm-4.64.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/c2/d8a40e5363fb01806870e444fc1d066282743292ff32a9da54af51ce36a2/tqdm-4.64.1.tar.gz", hashes = {sha256 = "5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}} +sdist = {name = "tqdm-4.64.0.tar.gz", url = "https://files.pythonhosted.org/packages/98/2a/838de32e09bd511cf69fe4ae13ffc748ac143449bfc24bb3fd172d53a84f/tqdm-4.64.0.tar.gz", hashes = {sha256 = "40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d"}} wheels = [ - {name = "tqdm-4.64.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/47/bb/849011636c4da2e44f1253cd927cfb20ada4374d8b3a4e425416e84900cc/tqdm-4.64.1-py2.py3-none-any.whl",hashes = {sha256 = "6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1"}}, + {name = "tqdm-4.64.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8a/c4/d15f1e627fff25443ded77ea70a7b5532d6371498f9285d44d62587e209c/tqdm-4.64.0-py2.py3-none-any.whl",hashes = {sha256 = "74a2cdefe14d11442cedf3ba4e21a3b84ff9a2dbdc6cfae2c34addb2a14a5ea6"}}, ] marker = "\"default\" in dependency_groups" @@ -395,45 +353,18 @@ dependencies = [ "importlib-resources; python_version < \"3.7\"", ] -[[packages]] -name = "types-psycopg2" -version = "2.9.21.20" -requires-python = ">=3.7" -sdist = {name = "types-psycopg2-2.9.21.20.tar.gz", url = "https://files.pythonhosted.org/packages/65/1a/5309006abcc034e3e96e516990ee900fd77b59a9efc6b3be571732693bf6/types-psycopg2-2.9.21.20.tar.gz", hashes = {sha256 = "73baea689575bf5bb1b915b783fb0524044c6242928aeef1ae5a9e32f0780d3d"}} -wheels = [ - {name = "types_psycopg2-2.9.21.20-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/4c/6c/bb61543162fd21c5e7dc6dce990cbb42a382b8ebcf512bb20fd846bf411b/types_psycopg2-2.9.21.20-py3-none-any.whl",hashes = {sha256 = "5b1e2e1d9478f8a298ea7038f8ea988e0ccc1f0af39f84636d57ef0da6f29e95"}}, -] -marker = "\"types\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "types-tqdm" -version = "4.66.0.5" -requires-python = ">=3.7" -sdist = {name = "types-tqdm-4.66.0.5.tar.gz", url = "https://files.pythonhosted.org/packages/c2/f3/f6d3da69ffee5b0707a82a079b31ba6c584269a6a9fad06ce51699ee30f2/types-tqdm-4.66.0.5.tar.gz", hashes = {sha256 = "74bd7e469238c28816300f72a9b713d02036f6b557734616430adb7b7e74112c"}} +version = "4.64.0" +sdist = {name = "types-tqdm-4.64.0.tar.gz", url = "https://files.pythonhosted.org/packages/47/80/e2e4bf6648fd9e2ab8809e2035474e5f9f06aa493b75f976d527c39576ee/types-tqdm-4.64.0.tar.gz", hashes = {sha256 = "7ef720bb9d7e1c2ba068adcfa02b07fea2ded684ab260ae5fb67ed32fa1832fb"}} wheels = [ - {name = "types_tqdm-4.66.0.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/50/70/3ae9020334d8ba80800e132ec3a51152fbef47c519b42ce3dafcb4aa26aa/types_tqdm-4.66.0.5-py3-none-any.whl",hashes = {sha256 = "d2c38085bec440e8ad1e94e8619f7cb3d1dd0a7ee06a863ccd0610a5945046ef"}}, + {name = "types_tqdm-4.64.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c8/bd/7718894f71def1ba9d103669e1677c510aae5d4bc9d2d9bd919858a9be99/types_tqdm-4.64.0-py3-none-any.whl",hashes = {sha256 = "aea2d870b272c260c7651a6982416d95fc301572ada70e72ea03f8be2a49a99e"}}, ] marker = "\"types\" in dependency_groups" [packages.tool.pdm] dependencies = [] -[[packages]] -name = "xlsxwriter" -version = "3.0.6" -requires-python = ">=3.6" -sdist = {name = "XlsxWriter-3.0.6.tar.gz", url = "https://files.pythonhosted.org/packages/d4/b5/cef6fadeaf316a3bbe82a506252081f2e6533cdf4b69ed64f8831ac01fb0/XlsxWriter-3.0.6.tar.gz", hashes = {sha256 = "2f9e5ea13343fe85486e349d4e5fdf746bb69dc7bc1dedfa9b5fae2bb48c0795"}} -wheels = [ - {name = "XlsxWriter-3.0.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/28/5d/a6ed474f8fdd5692e7b2f9275ece3a2efa034f26fefd1e5040b3a215d820/XlsxWriter-3.0.6-py3-none-any.whl",hashes = {sha256 = "56eae8ae587536734009aa819845c3e3c865462399823085b0baabbb081a929c"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "tomli" version = "2.2.1" @@ -633,62 +564,6 @@ marker = "\"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] -[[packages]] -name = "numpy" -version = "2.0.2" -requires-python = ">=3.9" -sdist = {name = "numpy-2.0.2.tar.gz", url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hashes = {sha256 = "883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78"}} -wheels = [ - {name = "numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl",hashes = {sha256 = "df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b"}}, - {name = "numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e"}}, - {name = "numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c"}}, - {name = "numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl",hashes = {sha256 = "a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c"}}, - {name = "numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692"}}, - {name = "numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a"}}, - {name = "numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c"}}, - {name = "numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded"}}, - {name = "numpy-2.0.2-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl",hashes = {sha256 = "671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5"}}, - {name = "numpy-2.0.2-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl",hashes = {sha256 = "cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a"}}, - {name = "numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448"}}, - {name = "numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195"}}, - {name = "numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl",hashes = {sha256 = "807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57"}}, - {name = "numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl",hashes = {sha256 = "8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a"}}, - {name = "numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669"}}, - {name = "numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951"}}, - {name = "numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9"}}, - {name = "numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15"}}, - {name = "numpy-2.0.2-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl",hashes = {sha256 = "a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4"}}, - {name = "numpy-2.0.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc"}}, - {name = "numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece"}}, - {name = "numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04"}}, - {name = "numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl",hashes = {sha256 = "8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66"}}, - {name = "numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl",hashes = {sha256 = "becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b"}}, - {name = "numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd"}}, - {name = "numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318"}}, - {name = "numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8"}}, - {name = "numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326"}}, - {name = "numpy-2.0.2-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl",hashes = {sha256 = "984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97"}}, - {name = "numpy-2.0.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131"}}, - {name = "numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl",hashes = {sha256 = "9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c"}}, - {name = "numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl",hashes = {sha256 = "423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd"}}, - {name = "numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl",hashes = {sha256 = "2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b"}}, - {name = "numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl",hashes = {sha256 = "97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729"}}, - {name = "numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1"}}, - {name = "numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd"}}, - {name = "numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl",hashes = {sha256 = "5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d"}}, - {name = "numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d"}}, - {name = "numpy-2.0.2-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl",hashes = {sha256 = "905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa"}}, - {name = "numpy-2.0.2-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl",hashes = {sha256 = "a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73"}}, - {name = "numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl",hashes = {sha256 = "7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8"}}, - {name = "numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl",hashes = {sha256 = "312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4"}}, - {name = "numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c"}}, - {name = "numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl",url = "https://files.pythonhosted.org/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl",hashes = {sha256 = "a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "packaging" version = "25.0" @@ -745,55 +620,49 @@ dependencies = [ [[packages]] name = "ruamel-yaml-clib" -version = "0.2.12" +version = "0.2.13" requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.12.tar.gz", url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hashes = {sha256 = "6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl",hashes = {sha256 = "4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl",hashes = {sha256 = "3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl",hashes = {sha256 = "e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl",hashes = {sha256 = "6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl",hashes = {sha256 = "bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl",hashes = {sha256 = "e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl",hashes = {sha256 = "0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl",hashes = {sha256 = "cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl",hashes = {sha256 = "bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl",hashes = {sha256 = "a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl",hashes = {sha256 = "22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl",hashes = {sha256 = "3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl",hashes = {sha256 = "ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/46/ccdef7a84ad745c37cb3d9a81790f28fbc9adf9c237dba682017b123294e/ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl",hashes = {sha256 = "fc4b630cd3fa2cf7fce38afa91d7cfe844a9f75d7f0f36393fa98815e911d987"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/29/09/932360f30ad1b7b79f08757e0a6fb8c5392a52cdcc182779158fe66d25ac/ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux2014_aarch64.whl",hashes = {sha256 = "bc5f1e1c28e966d61d2519f2a3d451ba989f9ea0f2307de7bc45baa526de9e45"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/2a/5b27602e7a4344c1334e26bf4739746206b7a60a8acdba33a61473468b73/ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5a0e060aace4c24dcaf71023bbd7d42674e3b230f7e7b97317baf1e953e5b519"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/da/1c/23497017c554fc06ff5701b29355522cff850f626337fff35d9ab352cb18/ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "e2f1c3765db32be59d18ab3953f43ab62a761327aafc1594a2a1fbe038b8b8a7"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/68/e6/f3d4ff3223f9ea49c3b7169ec0268e42bd49f87c70c0e3e853895e4a7ae2/ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl",hashes = {sha256 = "d85252669dc32f98ebcd5d36768f5d4faeaeaa2d655ac0473be490ecdae3c285"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/84/62/ead07043527642491e5011b143f44b81ef80f1025a96069b7210e0f2f0f3/ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl",hashes = {sha256 = "e143ada795c341b56de9418c58d028989093ee611aa27ffb9b7f609c00d813ed"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/52/b3/fe4d84446f7e4887e3bea7ceff0a7df23790b5ed625f830e79ace88ebefb/ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2c59aa6170b990d8d2719323e628aaf36f3bfbc1c26279c0eeeb24d05d2d11c7"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/6e/b3/7feb99a00bfaa5c6868617bb7651308afde85e5a0b23cd187fe5de65feeb/ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl",hashes = {sha256 = "beffaed67936fbbeffd10966a4eb53c402fafd3d6833770516bf7314bc6ffa12"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/07/de635108684b7a5bb06e432b0930c5a04b6c59efe73bd966d8db3cc208f2/ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl",hashes = {sha256 = "040ae85536960525ea62868b642bdb0c2cc6021c9f9d507810c0c604e66f5a7b"}}, +sdist = {name = "ruamel.yaml.clib-0.2.13.tar.gz", url = "https://files.pythonhosted.org/packages/3c/fd/32c91c4d301ebe7931a3c44f7593650613afe14854e3cc9d2764321b7a46/ruamel.yaml.clib-0.2.13.tar.gz", hashes = {sha256 = "8d4f8d7853053a5a19171a0f515f1e14f503bd3e772c4da6bafe7d0893d4f299"}} +wheels = [ + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/30/b5/3bff051bfdc33f8d797a1a025a1dc74fb13703611917f611e62e12061893/ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "817a3d8dbbefc337e9081d9bddd54ee6ef5d5351cccb5240d731d604c1d86d29"}}, + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/51/a3/8f199f9d6ff862b503eae06a4a9ec9f20fc232ee7590287d969ebf5a8859/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "b29e3a746dd774a49ec6412529dc6a7338efe0828230b7c5da2aef3ee6eb7cbc"}}, + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/fb/47728a32be2e7ac00f854d30b0d39ed62e9eefdff19c024f4e5c49d3341c/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bae8383e02ef5a7c6b44a594746dcdb0994b8bdf4317d2fba3bbafe8262dfa9d"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/9a/21de96f5fc51e495f6ebe87f01a679ec3b9a36082431942d7dc7295175da/ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "b3dae045e57780a6ec39a018220d82931d6cb3e6e8b326a9a804597ffa6f8520"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/26/4203139b2f1fc94b01e5fb5c2e9a5822725baad930ceb869e3525157f1b1/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "f6d476bc7bb9b25d54133f95d0766aaf1662689f6c26e9e08d28a45609a634f2"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/16/db/ec371bb692c404ad1cfad715b89300cca841a4ac31ed3467c66a5911ce01/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5622265f2b64f6933a29a5d8e33385a0c3ef47f509354602d0c28f5d7d126fe3"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/cb/71/230119917102ea682c6a1fa2e322ca18cdd4077342680908999e18fd84cc/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b2ba05d2dbe39435915aa20d53336d55fd0fa6c25eb1c580d60fc1f753e40a41"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/2d/22afc8402474285fc9bf35cb630f6194aecb2c777b304f872dada19ab06c/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",hashes = {sha256 = "a5a43fc6f95c58c1a65cbb7b68b31f9721362e10c5276d3f8db4ccde8e9acb04"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c9/c7/928d0692ac05bb0f05b337e151da28792f25782ae0e2cda1a5bf0dda9dde/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "5ce7178bd66cffe4eb4ce40c2ff525f42ccfa6e2e31eeea27293fe5bd0ae2d93"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b2/2972fae8d9dc10314e39c254638320e1b028511185cebaa96f3382122f40/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "490c5dfaf9f218f335f2f6f7ba52f7ce5460e94d67a42c8dd0096deae7684d23"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/89/e3/fc6c145f7d122a39793f9a8e508ba060a3bc5883065f3f11dbc9011023bd/ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",hashes = {sha256 = "b5e32adbb14ffdb1130c699128070766e5cf781b3b05dd87049c16bb94395212"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/95/e5/6cb4654b62b90116962d88cb74419caa3eb5fc50ccbc932d5553adf70812/ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",hashes = {sha256 = "826ce141d368f10a99a4fc6fab332ba4203f63da25828853d7957e76d13f7d41"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/ae/b6b3ed185206af04c779eec77a4a57587278b713b72034957d127307bbef/ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "810500056a0e294131042eca6687a786e82aad817e8e0bc5ce059d2f95b67fef"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/6f/2b/b0307fc587cebabd8faaaeb1476c825fe4dbb5ad2b5c152dfbcc31b258c4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "f8e44b1b583f93a8f4d00e5285d9ea8ccd9524cdd4c54788db2880a11f21287d"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/a9/2ddad6eb03195206aca765b4ff7bd7098c46fbc65957d5ac53f96ef8d6f4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "4d1ab027be86f7d5ccc9b777a22194fd3850012df413f216bf1608768b4daa2f"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/42/a0/ded38d60fc34f69afef6f3e379f896a80d34532bb6b4828e95f7003be610/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "55f01d82d7d96213f0963609876ae841c81e217985c668100c5fb95cc9a564b3"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/3e/49/121067d5621a77913dc0fd473bdf2ec4a515c564806b107d3b1257cd5b14/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",hashes = {sha256 = "031c7cdd5751cda19ddf90e42756ec2ee72a30791c2f65f5f800f9ee929862f0"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/fc/0845929db1840eec6aa6133b8c89941e251c3bc67180aee7d71a30bc1c80/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "ba745411caabc994963729663a7c2d09398795c36dc4b5672ca4fdc445ab6544"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d6/0a/dd0007d41a321edf64c4bda0aab70936281ee213406e6913105499f7d62a/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fb90267cc3748858236b9cedb580191be1d0d218f6cde64e954fa759d90fb08d"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/93/0d/eeed0a9824b14fa089a82247fca96de6b202af84e4093ba2a15afc0b4cb9/ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",hashes = {sha256 = "5188c3212c10fcd14a6de8ce787c0713a49fc5972054703f790cfd9f1d27a90b"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/45/c882a32e4b5c0ed6a5b4e0933af427fef48f3aad7259b87f38e33ee20536/ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",hashes = {sha256 = "518b13f9fe601a559a759f3d21cdb2590cb85611934a7c0f09c09dc1a869ec83"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/86/fa6be53f11d1c663a261d137d616bbb326cb937b361a55a00cacf9ba76aa/ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "825a7483da63b9448fdad9778269a5d02e5f64040aa8326fec071e830c2fc49c"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/f1/d26dbf3c53befd01d8b341cb29c555c1e910ef29478b4ebd50d1d67fbc64/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "54707e2200b9e1c34a62af09edd3ea3469a722951365311398458abe36ff45d6"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a8/80/119ce9e40690b7e0dfc6bec41369333593f8738fa4f58dbbffdb9b80339b/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "958b1fc6334cd745db7099a69da4f60503cfbbc05ce1412b1d06c5922cd8314b"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/0b/85/09625df6b3ccf0ae0ddc93c0ab4d89f785debc0ae1e7efa541696b788b6a/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d50c415df5ba918c483a2486a90dd5a3e6df634fca688f71d266e15a618d643f"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/e0/2e/c05050760b20fe10cb17b3fe7efd5d5653baefa862121f5b0825418f3d8b/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "bbdb57e57a5bb3510bfb43496bab44857546c56c7f04bb7bfd0b248388d41c2e"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d7/e0/6cfd5c61070f0e5556a724c753919b8758b86fe89f5b53eb9f53d0506b27/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "df8ef03eb60fc2e1c0570612363091898b97a7b3181422e1b34c3ee22d7e0a9e"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/85/01/14964bd94bbe809497d1affc0625e428803cc9fd21e145b1b2edcbbc3c92/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "89168de27694f7903a1317381525efdf7ea2c377b5b1eeeb927940870a7e8945"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/1d/c0/a39cc7de38b5acc81241dda9888ecabc1ee90fb3ebf9189ddfc65c08555d/ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",hashes = {sha256 = "8cdb4c720137bb7834cf2c09753d5f3468023eebb7f6ad2604ddf920328753dd"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1f/7f/d5c1e0279df8dd9ca92138bec8387a07112d97598f668ccb3190d0bc06aa/ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",hashes = {sha256 = "670d8a9c5b22af152863236b7a7fec471aafefc5e89b637b8f98d280cb92a0ce"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/73/88/8d40634f34fd206be8aab060537890ae939f67d3598718426be62493e4fe/ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "a67efad34e15232f03333d4a7cc96b1db8ecb676439b6a3db10d49ffbd3a8606"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/3b/25/9deabe6323318acb61e521e6fdcc92575af7f5d4f716def8c42d0cb0d6b2/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "ce8be9ce9c967a9952e92d9280d18de9ae331284645b50dc32f71ef207ef00e1"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/ce/48e9802811c6fe757aae2387e2feb24bf6964fa9a467c26da6c20daea916/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "e16f9611130aa3695aaff32d956e49b45cef902aa15cf9de18ebf919d6acc153"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/28/f6/dff4b9988da26b994f8bb019344ec44b81699f0abf0515040001d6cce8a3/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3a6afcf136a474703e9c7fa62fab76870775c98a4f59f599fdd24348dca3a229"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/81/bd/80fccf71b3387c2fcde566b3d45c827d8380401ee76907e1639ff297f996/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",hashes = {sha256 = "70328e9afcb83deb689547989e6b79fc8f094964b8b754b44a70ba7e68e523fe"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/d6/80134d4c11bd396d438964de26f9d7d9300e35bc2fbdca1584634f262d0a/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "fc2c45c0b5b7845278148f18a4039b6d8fde3f7266dd00986684453a57d3444a"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/99/a4/903a317cbb13071663ad370a4a16e7ba44e62d057352782d760dcd904a72/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fa3c15cefc29ed3f7ad6ac370bd46d8e431d1fa0ba03eb54912e8c5d826e458e"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/b4/7e/c1e1aa7ffb1716db2e9701b9516ec8c4f9a63e7d5cd54b9cced38260f584/ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",hashes = {sha256 = "e9117696191427cd2c5028878b89012e01cee51b2ae8f5dd440a79d6ba4a1011"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f8/1d/067de099bb82c7df5a853989bad5773edf89cc1016a23c6abbcbb28139d2/ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4ba827c038348ebde594788b66a4741ce9606b979b684e3bc1e7d1c11d6ac817"}}, ] marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and \"lint\" in dependency_groups" @@ -887,8 +756,8 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "9edcf2127050cd04b1c55f2c5d0ef0c306790635417a4e7c2a0ed6e601c76e78"} +hashes = {sha256 = "f41cee4895442b905a0fa8fe84189c460dff00eec403795e10a6ff2120675686"} strategy = ["direct_minimal_versions", "inherit_metadata", "static_urls"] [[tool.pdm.targets]] -requires_python = ">=3.9" +requires_python = ">=3.10" diff --git a/pylock.toml b/pylock.toml index 6cf66b9..150c7d5 100644 --- a/pylock.toml +++ b/pylock.toml @@ -1,9 +1,9 @@ # This file is @generated by PDM. # It is not intended for manual editing. lock-version = "1.0" -requires-python = ">=3.9" +requires-python = ">=3.10" environments = [ - "python_version >= \"3.9\"", + "python_version >= \"3.10\"", ] extras = [] dependency-groups = ["default", "lint", "test", "types"] @@ -12,41 +12,41 @@ created-by = "pdm" [[packages]] name = "mypy" -version = "1.17.0" +version = "1.18.2" requires-python = ">=3.9" -sdist = {name = "mypy-1.17.0.tar.gz", url = "https://files.pythonhosted.org/packages/1e/e3/034322d5a779685218ed69286c32faa505247f1f096251ef66c8fd203b08/mypy-1.17.0.tar.gz", hashes = {sha256 = "e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03"}} -wheels = [ - {name = "mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/be/7b/5f8ab461369b9e62157072156935cec9d272196556bdc7c2ff5f4c7c0f9b/mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06"}}, - {name = "mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/9c/f8/c49c9e5a2ac0badcc54beb24e774d2499748302c9568f7f09e8730e953fa/mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a"}}, - {name = "mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/0c/fb3f9c939ad9beed3e328008b3fb90b20fda2cddc0f7e4c20dbefefc3b33/mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889"}}, - {name = "mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4c/66/85607ab5137d65e4f54d9797b77d5a038ef34f714929cf8ad30b03f628df/mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba"}}, - {name = "mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/d0/341dbbfb35ce53d01f8f2969facbb66486cee9804048bf6c01b048127501/mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658"}}, - {name = "mypy-1.17.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/63/70c8b7dbfc520089ac48d01367a97e8acd734f65bd07813081f508a8c94c/mypy-1.17.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c"}}, - {name = "mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/12/e9/e6824ed620bbf51d3bf4d6cbbe4953e83eaf31a448d1b3cfb3620ccb641c/mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb"}}, - {name = "mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/ba/51/a4afd1ae279707953be175d303f04a5a7bd7e28dc62463ad29c1c857927e/mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d"}}, - {name = "mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8a/71/19adfeac926ba8205f1d1466d0d360d07b46486bf64360c54cb5a2bd86a8/mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8"}}, - {name = "mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e"}}, - {name = "mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/dc/56f53b5255a166f5bd0f137eed960e5065f2744509dfe69474ff0ba772a5/mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8"}}, - {name = "mypy-1.17.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/69/ac/070bad311171badc9add2910e7f89271695a25c136de24bbafc7eded56d5/mypy-1.17.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d"}}, - {name = "mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/24/82efb502b0b0f661c49aa21cfe3e1999ddf64bf5500fc03b5a1536a39d39/mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be"}}, - {name = "mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/03/96/8ef9a6ff8cedadff4400e2254689ca1dc4b420b92c55255b44573de10c54/mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61"}}, - {name = "mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/df/32/7ce359a56be779d38021d07941cfbb099b41411d72d827230a36203dbb81/mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f"}}, - {name = "mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/16/b775047054de4d8dbd668df9137707e54b07fe18c7923839cd1e524bf756/mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d"}}, - {name = "mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a1/cf/fa33eaf29a606102c8d9ffa45a386a04c2203d9ad18bf4eef3e20c43ebc8/mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3"}}, - {name = "mypy-1.17.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/94/75/3f5a29209f27e739ca57e6350bc6b783a38c7621bdf9cac3ab8a08665801/mypy-1.17.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70"}}, - {name = "mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/6a/31/e762baa3b73905c856d45ab77b4af850e8159dffffd86a52879539a08c6b/mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6"}}, - {name = "mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/1c/c1/25b2f0d46fb7e0b5e2bee61ec3a47fe13eff9e3c2f2234f144858bbe6485/mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d"}}, - {name = "mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/02/78/6d646603a57aa8a2886df1b8881fe777ea60f28098790c1089230cd9c61d/mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b"}}, - {name = "mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4f/19/dae6c55e87ee426fb76980f7e78484450cad1c01c55a1dc4e91c930bea01/mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a"}}, - {name = "mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/86/e1/f916845a235235a6c1e4d4d065a3930113767001d491b8b2e1b61ca56647/mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f"}}, - {name = "mypy-1.17.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ae/dc/414760708a4ea1b096bd214d26a24e30ac5e917ef293bc33cdb6fe22d2da/mypy-1.17.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937"}}, - {name = "mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/9f/a0/6263dd11941231f688f0a8f2faf90ceac1dc243d148d314a089d2fe25108/mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl",hashes = {sha256 = "63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab"}}, - {name = "mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/02/13/b8f16d6b0dc80277129559c8e7dbc9011241a0da8f60d031edb0e6e9ac8f/mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl",hashes = {sha256 = "f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad"}}, - {name = "mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/14/ef/978ba79df0d65af680e20d43121363cf643eb79b04bf3880d01fc8afeb6f/mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c"}}, - {name = "mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/f4/10/55ef70b104151a0d8280474f05268ff0a2a79be8d788d5e647257d121309/mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8"}}, - {name = "mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/8c/7781fcd2e1eef48fbedd3a422c21fe300a8e03ed5be2eb4bd10246a77f4e/mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97"}}, - {name = "mypy-1.17.0-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/78/13/03ac759dabe86e98ca7b6681f114f90ee03f3ff8365a57049d311bd4a4e3/mypy-1.17.0-cp39-cp39-win_amd64.whl",hashes = {sha256 = "ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4"}}, - {name = "mypy-1.17.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e3/fc/ee058cc4316f219078464555873e99d170bde1d9569abd833300dbeb484a/mypy-1.17.0-py3-none-any.whl",hashes = {sha256 = "15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496"}}, +sdist = {name = "mypy-1.18.2.tar.gz", url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hashes = {sha256 = "06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"}} +wheels = [ + {name = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"}}, + {name = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}}, + {name = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}}, + {name = "mypy-1.18.2-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl",hashes = {sha256 = "749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}}, + {name = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}}, + {name = "mypy-1.18.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}}, + {name = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"}}, + {name = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"}}, + {name = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"}}, + {name = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"}}, + {name = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"}}, + {name = "mypy-1.18.2-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"}}, + {name = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"}}, + {name = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"}}, + {name = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"}}, + {name = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"}}, + {name = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"}}, + {name = "mypy-1.18.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"}}, + {name = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/03/6f/657961a0743cff32e6c0611b63ff1c1970a0b482ace35b069203bf705187/mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"}}, + {name = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/10/e9/420822d4f661f13ca8900f5fa239b40ee3be8b62b32f3357df9a3045a08b/mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"}}, + {name = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/aa/73/a05b2bbaa7005f4642fcfe40fb73f2b4fb6bb44229bd585b5878e9a87ef8/mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"}}, + {name = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4f/01/f6e4b9f0d031c11ccbd6f17da26564f3a0f3c4155af344006434b0a05a9d/mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"}}, + {name = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/97/19727e7499bfa1ae0773d06afd30ac66a58ed7437d940c70548634b24185/mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"}}, + {name = "mypy-1.18.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/4f/90dc8c15c1441bf31cf0f9918bb077e452618708199e530f4cbd5cede6ff/mypy-1.18.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"}}, + {name = "mypy-1.18.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl",hashes = {sha256 = "22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}}, ] marker = "\"lint\" in dependency_groups" @@ -60,11 +60,11 @@ dependencies = [ [[packages]] name = "pre-commit-hooks" -version = "5.0.0" -requires-python = ">=3.8" -sdist = {name = "pre_commit_hooks-5.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/ac/7d/3299241a753c738d114600c360d754550b28c285281dc6a5132c4ccfae65/pre_commit_hooks-5.0.0.tar.gz", hashes = {sha256 = "10626959a9eaf602fbfc22bc61b6e75801436f82326bfcee82bb1f2fc4bc646e"}} +version = "6.0.0" +requires-python = ">=3.9" +sdist = {name = "pre_commit_hooks-6.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/36/4d/93e63e48f8fd16d6c1e4cef5dabadcade4d1325c7fd6f29f075a4d2284f3/pre_commit_hooks-6.0.0.tar.gz", hashes = {sha256 = "76d8370c006f5026cdd638a397a678d26dda735a3c88137e05885a020f824034"}} wheels = [ - {name = "pre_commit_hooks-5.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1e/29/db1d855a661c02dbde5cab3057969133fcc62e7a0c6393e48fe9d0e81679/pre_commit_hooks-5.0.0-py2.py3-none-any.whl",hashes = {sha256 = "8d71cfb582c5c314a5498d94e0104b6567a8b93fb35903ea845c491f4e290a7a"}}, + {name = "pre_commit_hooks-6.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/12/46/eba9be9daa403fa94854ce16a458c29df9a01c6c047931c3d8be6016cd9a/pre_commit_hooks-6.0.0-py2.py3-none-any.whl",hashes = {sha256 = "76161b76d321d2f8ee2a8e0b84c30ee8443e01376121fd1c90851e33e3bd7ee2"}}, ] marker = "\"lint\" in dependency_groups" @@ -76,27 +76,28 @@ dependencies = [ [[packages]] name = "ruff" -version = "0.12.5" +version = "0.13.1" requires-python = ">=3.7" -sdist = {name = "ruff-0.12.5.tar.gz", url = "https://files.pythonhosted.org/packages/30/cd/01015eb5034605fd98d829c5839ec2c6b4582b479707f7c1c2af861e8258/ruff-0.12.5.tar.gz", hashes = {sha256 = "b209db6102b66f13625940b7f8c7d0f18e20039bb7f6101fbdac935c9612057e"}} -wheels = [ - {name = "ruff-0.12.5-py3-none-linux_armv6l.whl",url = "https://files.pythonhosted.org/packages/d4/de/ad2f68f0798ff15dd8c0bcc2889558970d9a685b3249565a937cd820ad34/ruff-0.12.5-py3-none-linux_armv6l.whl",hashes = {sha256 = "1de2c887e9dec6cb31fcb9948299de5b2db38144e66403b9660c9548a67abd92"}}, - {name = "ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/fc/c6b65cd0e7fbe60f17e7ad619dca796aa49fbca34bb9bea5f8faf1ec2643/ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl",hashes = {sha256 = "d1ab65e7d8152f519e7dea4de892317c9da7a108da1c56b6a3c1d5e7cf4c5e9a"}}, - {name = "ruff-0.12.5-py3-none-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/de/c6bec1dce5ead9f9e6a946ea15e8d698c35f19edc508289d70a577921b30/ruff-0.12.5-py3-none-macosx_11_0_arm64.whl",hashes = {sha256 = "962775ed5b27c7aa3fdc0d8f4d4433deae7659ef99ea20f783d666e77338b8cf"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/16/cf372d2ebe91e4eb5b82a2275c3acfa879e0566a7ac94d331ea37b765ac8/ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "73b4cae449597e7195a49eb1cdca89fd9fbb16140c7579899e87f4c85bf82f73"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/25/bf/cd07e8f6a3a6ec746c62556b4c4b79eeb9b0328b362bb8431b7b8afd3856/ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "8b13489c3dc50de5e2d40110c0cce371e00186b880842e245186ca862bf9a1ac"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/d8/c9/c2ccb3b8cbb5661ffda6925f81a13edbb786e623876141b04919d1128370/ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "f1504fea81461cf4841778b3ef0a078757602a3b3ea4b008feb1308cb3f23e08"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",url = "https://files.pythonhosted.org/packages/6b/58/68a5be2c8e5590ecdad922b2bcd5583af19ba648f7648f95c51c3c1eca81/ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",hashes = {sha256 = "c7da4129016ae26c32dfcbd5b671fe652b5ab7fc40095d80dcff78175e7eddd4"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/bd/d1/ef6b19622009ba8386fdb792c0743f709cf917b0b2f1400589cbe4739a33/ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "ca972c80f7ebcfd8af75a0f18b17c42d9f1ef203d163669150453f50ca98ab7b"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/62/e3/1c98c566fe6809a0c83751d825a03727f242cdbe0d142c9e292725585521/ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "8dbbf9f25dfb501f4237ae7501d6364b76a01341c6f1b2cd6764fe449124bb2a"}}, - {name = "ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/24/ff/96058f6506aac0fbc0d0fc0d60b0d0bd746240a0594657a2d94ad28033ba/ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2c47dea6ae39421851685141ba9734767f960113d51e83fd7bb9958d5be8763a"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/d3/68bc5e7ab96c94b3589d1789f2dd6dd4b27b263310019529ac9be1e8f31b/ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c5076aa0e61e30f848846f0265c873c249d4b558105b221be1828f9f79903dc5"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/52/75/7356af30a14584981cabfefcf6106dea98cec9a7af4acb5daaf4b114845f/ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl",hashes = {sha256 = "a5a4c7830dadd3d8c39b1cc85386e2c1e62344f20766be6f173c22fb5f72f293"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c2/67/91c71d27205871737cae11025ee2b098f512104e26ffd8656fd93d0ada0a/ruff-0.12.5-py3-none-musllinux_1_2_i686.whl",hashes = {sha256 = "46699f73c2b5b137b9dc0fc1a190b43e35b008b398c6066ea1350cce6326adcb"}}, - {name = "ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/04/b6b00383cf2f48e8e78e14eb258942fdf2a9bf0287fbf5cdd398b749193a/ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5a655a0a0d396f0f072faafc18ebd59adde8ca85fb848dc1b0d9f024b9c4d3bb"}}, - {name = "ruff-0.12.5-py3-none-win32.whl",url = "https://files.pythonhosted.org/packages/3e/b9/053d6445dc7544fb6594785056d8ece61daae7214859ada4a152ad56b6e0/ruff-0.12.5-py3-none-win32.whl",hashes = {sha256 = "dfeb2627c459b0b78ca2bbdc38dd11cc9a0a88bf91db982058b26ce41714ffa9"}}, - {name = "ruff-0.12.5-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bc/0f/ab16e8259493137598b9149734fec2e06fdeda9837e6f634f5c4e35916da/ruff-0.12.5-py3-none-win_amd64.whl",hashes = {sha256 = "ae0d90cf5f49466c954991b9d8b953bd093c32c27608e409ae3564c63c5306a5"}}, - {name = "ruff-0.12.5-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/00/db/c376b0661c24cf770cb8815268190668ec1330eba8374a126ceef8c72d55/ruff-0.12.5-py3-none-win_arm64.whl",hashes = {sha256 = "48cdbfc633de2c5c37d9f090ba3b352d1576b0015bfc3bc98eaf230275b7e805"}}, +sdist = {name = "ruff-0.13.1.tar.gz", url = "https://files.pythonhosted.org/packages/ab/33/c8e89216845615d14d2d42ba2bee404e7206a8db782f33400754f3799f05/ruff-0.13.1.tar.gz", hashes = {sha256 = "88074c3849087f153d4bb22e92243ad4c1b366d7055f98726bc19aa08dc12d51"}} +wheels = [ + {name = "ruff-0.13.1-py3-none-linux_armv6l.whl",url = "https://files.pythonhosted.org/packages/f3/41/ca37e340938f45cfb8557a97a5c347e718ef34702546b174e5300dbb1f28/ruff-0.13.1-py3-none-linux_armv6l.whl",hashes = {sha256 = "b2abff595cc3cbfa55e509d89439b5a09a6ee3c252d92020bd2de240836cf45b"}}, + {name = "ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/84/ba378ef4129415066c3e1c80d84e539a0d52feb250685091f874804f28af/ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",hashes = {sha256 = "4ee9f4249bf7f8bb3984c41bfaf6a658162cdb1b22e3103eabc7dd1dc5579334"}}, + {name = "ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8d/b6/ec5e4559ae0ad955515c176910d6d7c93edcbc0ed1a3195a41179c58431d/ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",hashes = {sha256 = "5c5da4af5f6418c07d75e6f3224e08147441f5d1eac2e6ce10dcce5e616a3bae"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/d6/cb3e3b4f03b9b0c4d4d8f06126d34b3394f6b4d764912fe80a1300696ef6/ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "80524f84a01355a59a93cef98d804e2137639823bcee2931f5028e71134a954e"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/d2/ea/bf60cb46d7ade706a246cd3fb99e4cfe854efa3dfbe530d049c684da24ff/ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "ff7f5ce8d7988767dd46a148192a14d0f48d1baea733f055d9064875c7d50389"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2d/3e/05f72f4c3d3a69e65d55a13e1dd1ade76c106d8546e7e54501d31f1dc54a/ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "c55d84715061f8b05469cdc9a446aa6c7294cd4bd55e86a89e572dba14374f8c"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",url = "https://files.pythonhosted.org/packages/81/e7/01b1fc403dd45d6cfe600725270ecc6a8f8a48a55bc6521ad820ed3ceaf8/ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",hashes = {sha256 = "ac57fed932d90fa1624c946dc67a0a3388d65a7edc7d2d8e4ca7bddaa789b3b0"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/fa/92/d9e183d4ed6185a8df2ce9faa3f22e80e95b5f88d9cc3d86a6d94331da3f/ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "c366a71d5b4f41f86a008694f7a0d75fe409ec298685ff72dc882f882d532e36"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/3b/4a/6ddb1b11d60888be224d721e01bdd2d81faaf1720592858ab8bac3600466/ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "f4ea9d1b5ad3e7a83ee8ebb1229c33e5fe771e833d6d3dcfca7b77d95b060d38"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/98/3f1d18a8d9ea33ef2ad508f0417fcb182c99b23258ec5e53d15db8289809/ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "b0f70202996055b555d3d74b626406476cc692f37b13bac8828acff058c9966a"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/8d/86/b6ce62ce9c12765fa6c65078d1938d2490b2b1d9273d0de384952b43c490/ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",hashes = {sha256 = "f8cff7a105dad631085d9505b491db33848007d6b487c3c1979dd8d9b2963783"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/6e/af7943466a41338d04503fb5a81b2fd07251bd272f546622e5b1599a7976/ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9761e84255443316a258dd7dfbd9bfb59c756e52237ed42494917b2577697c6a"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/3f/97/0249b9a24f0f3ebd12f007e81c87cec6d311de566885e9309fcbac5b24cc/ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",hashes = {sha256 = "3d376a88c3102ef228b102211ef4a6d13df330cb0f5ca56fdac04ccec2a99700"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/f6/85/0b64693b2c99d62ae65236ef74508ba39c3febd01466ef7f354885e5050c/ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",hashes = {sha256 = "cbefd60082b517a82c6ec8836989775ac05f8991715d228b3c1d86ccc7df7dae"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/96/fc/342e9f28179915d28b3747b7654f932ca472afbf7090fc0c4011e802f494/ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",hashes = {sha256 = "dd16b9a5a499fe73f3c2ef09a7885cb1d97058614d601809d37c422ed1525317"}}, + {name = "ruff-0.13.1-py3-none-win32.whl",url = "https://files.pythonhosted.org/packages/37/54/6177a0dc10bce6f43e392a2192e6018755473283d0cf43cc7e6afc182aea/ruff-0.13.1-py3-none-win32.whl",hashes = {sha256 = "55e9efa692d7cb18580279f1fbb525146adc401f40735edf0aaeabd93099f9a0"}}, + {name = "ruff-0.13.1-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/51/c6a3a33d9938007b8bdc8ca852ecc8d810a407fb513ab08e34af12dc7c24/ruff-0.13.1-py3-none-win_amd64.whl",hashes = {sha256 = "3a3fb595287ee556de947183489f636b9f76a72f0fa9c028bdcabf5bab2cc5e5"}}, + {name = "ruff-0.13.1-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/04/afc078a12cf68592345b1e2d6ecdff837d286bac023d7a22c54c7a698c5b/ruff-0.13.1-py3-none-win_arm64.whl",hashes = {sha256 = "c0bae9ffd92d54e03c2bf266f466da0a65e145f298ee5b5846ed435f6a00518a"}}, ] marker = "\"lint\" in dependency_groups" @@ -137,13 +138,6 @@ wheels = [ {name = "duckdb-1.3.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/65/50/9a1289619447d93a8c63b08f6ab22e1e6ce73a681e0dceb0cd0ea7558613/duckdb-1.3.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6b7e6bb613b73745f03bff4bb412f362d4a1e158bdcb3946f61fd18e9e1a8ddf"}}, {name = "duckdb-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e0/d1/8dc959e3ca16c4c32ab34e28ceea189edc9bf32523aaa976080fd2101835/duckdb-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1c90646b52a0eccda1f76b10ac98b502deb9017569e84073da00a2ab97763578"}}, {name = "duckdb-1.3.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7b/e8/126767fe5acbe01230f7431d999a2c2ef028ffdaebda8fe32ddb57628815/duckdb-1.3.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4cdffb1e60defbfa75407b7f2ccc322f535fd462976940731dfd1644146f90c6"}}, - {name = "duckdb-1.3.2-cp39-cp39-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/e1/2e98d78eebcf405f1900e22c4ec3f5f7e2d4ed889693f95103255f6a1452/duckdb-1.3.2-cp39-cp39-macosx_12_0_arm64.whl",hashes = {sha256 = "18862e3b8a805f2204543d42d5f103b629cb7f7f2e69f5188eceb0b8a023f0af"}}, - {name = "duckdb-1.3.2-cp39-cp39-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/f7/73/ee28ba97b5dd2da5d1bb4e592e79384d54288d82ec34e75c068012b36f53/duckdb-1.3.2-cp39-cp39-macosx_12_0_universal2.whl",hashes = {sha256 = "75ed129761b6159f0b8eca4854e496a3c4c416e888537ec47ff8eb35fda2b667"}}, - {name = "duckdb-1.3.2-cp39-cp39-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/a6/0b/67f938499c6c52df90c821a8a3f25699274ce7fbf46fa9227bc4c0bd92fe/duckdb-1.3.2-cp39-cp39-macosx_12_0_x86_64.whl",hashes = {sha256 = "875193ae9f718bc80ab5635435de5b313e3de3ec99420a9b25275ddc5c45ff58"}}, - {name = "duckdb-1.3.2-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/6c/2d/373665ef567ef0d6bcf9caf9803b697168f9e6904aff99d5782a1c5e91d1/duckdb-1.3.2-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "09b5fd8a112301096668903781ad5944c3aec2af27622bd80eae54149de42b42"}}, - {name = "duckdb-1.3.2-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b1/18/9a89fa02689db8496d414f96d2e0ea56a24910c546c126c8a4626f3a51ee/duckdb-1.3.2-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "10cb87ad964b989175e7757d7ada0b1a7264b401a79be2f828cf8f7c366f7f95"}}, - {name = "duckdb-1.3.2-cp39-cp39-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/2e/97/2b09ad149081d75534fe063ff6a1b4b91fffe7e17816a7d9261aa7456788/duckdb-1.3.2-cp39-cp39-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4389fc3812e26977034fe3ff08d1f7dbfe6d2d8337487b4686f2b50e254d7ee3"}}, - {name = "duckdb-1.3.2-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/6d/78/8c096f1ef46205f561e7e62d1aff749a079cf57f5c433485f55e15463041/duckdb-1.3.2-cp39-cp39-win_amd64.whl",hashes = {sha256 = "07952ec6f45dd3c7db0f825d231232dc889f1f2490b97a4e9b7abb6830145a19"}}, ] marker = "\"default\" in dependency_groups" @@ -152,97 +146,101 @@ dependencies = [] [[packages]] name = "coverage" -version = "7.10.6" +version = "7.10.7" requires-python = ">=3.9" -sdist = {name = "coverage-7.10.6.tar.gz", url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hashes = {sha256 = "f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90"}} -wheels = [ - {name = "coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d3/aa/76cf0b5ec00619ef208da4689281d48b57f2c7fde883d14bf9441b74d59f/coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "6008a021907be8c4c02f37cdc3ffb258493bdebfeaf9a839f9e71dfdc47b018e"}}, - {name = "coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/65/91/8e41b8c7c505d398d7730206f3cbb4a875a35ca1041efc518051bfce0f6b/coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "5e75e37f23eb144e78940b40395b42f2321951206a4f50e23cfd6e8a198d3ceb"}}, - {name = "coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/87/7f/f718e732a423d442e6616580a951b8d1ec3575ea48bcd0e2228386805e79/coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "0f7cb359a448e043c576f0da00aa8bfd796a01b06aa610ca453d4dde09cc1034"}}, - {name = "coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e6/52/c1106120e6d801ac03e12b5285e971e758e925b6f82ee9b86db3aa10045d/coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "c68018e4fc4e14b5668f1353b41ccf4bc83ba355f0e1b3836861c6f042d89ac1"}}, - {name = "coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3d/ec/3a8645b1bb40e36acde9c0609f08942852a4af91a937fe2c129a38f2d3f5/coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "cd4b2b0707fc55afa160cd5fc33b27ccbf75ca11d81f4ec9863d5793fc6df56a"}}, - {name = "coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/70/09ecb68eeb1155b28a1d16525fd3a9b65fbe75337311a99830df935d62b6/coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4cec13817a651f8804a86e4f79d815b3b28472c910e099e4d5a0e8a3b6a1d4cb"}}, - {name = "coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c6/80/47df374b893fa812e953b5bc93dcb1427a7b3d7a1a7d2db33043d17f74b9/coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "f2a6a8e06bbda06f78739f40bfb56c45d14eb8249d0f0ea6d4b3d48e1f7c695d"}}, - {name = "coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/4a/65/9f98640979ecee1b0d1a7164b589de720ddf8100d1747d9bbdb84be0c0fb/coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "081b98395ced0d9bcf60ada7661a0b75f36b78b9d7e39ea0790bb4ed8da14747"}}, - {name = "coverage-7.10.6-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/1f/55/eeb6603371e6629037f47bd25bef300387257ed53a3c5fdb159b7ac8c651/coverage-7.10.6-cp314-cp314-win32.whl",hashes = {sha256 = "6937347c5d7d069ee776b2bf4e1212f912a9f1f141a429c475e6089462fcecc5"}}, - {name = "coverage-7.10.6-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/15/d1/a0912b7611bc35412e919a2cd59ae98e7ea3b475e562668040a43fb27897/coverage-7.10.6-cp314-cp314-win_amd64.whl",hashes = {sha256 = "adec1d980fa07e60b6ef865f9e5410ba760e4e1d26f60f7e5772c73b9a5b0713"}}, - {name = "coverage-7.10.6-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ef/2d/11880bb8ef80a45338e0b3e0725e4c2d73ffbb4822c29d987078224fd6a5/coverage-7.10.6-cp314-cp314-win_arm64.whl",hashes = {sha256 = "a80f7aef9535442bdcf562e5a0d5a5538ce8abe6bb209cfbf170c462ac2c2a32"}}, - {name = "coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/83/c0/1f00caad775c03a700146f55536ecd097a881ff08d310a58b353a1421be0/coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "0de434f4fbbe5af4fa7989521c655c8c779afb61c53ab561b64dcee6149e4c65"}}, - {name = "coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a9/c4/b1c5d2bd7cc412cbeb035e257fd06ed4e3e139ac871d16a07434e145d18d/coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "6e31b8155150c57e5ac43ccd289d079eb3f825187d7c66e755a055d2c85794c6"}}, - {name = "coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/3f/07/4468d37c94724bf6ec354e4ec2f205fda194343e3e85fd2e59cec57e6a54/coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "98cede73eb83c31e2118ae8d379c12e3e42736903a8afcca92a7218e1f2903b0"}}, - {name = "coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/d8/f8fb351be5fee31690cd8da768fd62f1cfab33c31d9f7baba6cd8960f6b8/coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "f863c08f4ff6b64fa8045b1e3da480f5374779ef187f07b82e0538c68cb4ff8e"}}, - {name = "coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/70/65d4d7cfc75c5c6eb2fed3ee5cdf420fd8ae09c4808723a89a81d5b1b9c3/coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2b38261034fda87be356f2c3f42221fdb4171c3ce7658066ae449241485390d5"}}, - {name = "coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/3c/069df106d19024324cde10e4ec379fe2fb978017d25e97ebee23002fbadf/coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e93b1476b79eae849dc3872faeb0bf7948fd9ea34869590bc16a2a00b9c82a7"}}, - {name = "coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/fc/8a/2974d53904080c5dc91af798b3a54a4ccb99a45595cc0dcec6eb9616a57d/coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "ff8a991f70f4c0cf53088abf1e3886edcc87d53004c7bb94e78650b4d3dac3b5"}}, - {name = "coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/30/38/9616a6b49c686394b318974d7f6e08f38b8af2270ce7488e879888d1e5db/coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ac765b026c9f33044419cbba1da913cfb82cca1b60598ac1c7a5ed6aac4621a0"}}, - {name = "coverage-7.10.6-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/76/16/3ed2d6312b371a8cf804abf4e14895b70e4c3491c6e53536d63fd0958a8d/coverage-7.10.6-cp314-cp314t-win32.whl",hashes = {sha256 = "441c357d55f4936875636ef2cfb3bee36e466dcf50df9afbd398ce79dba1ebb7"}}, - {name = "coverage-7.10.6-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d5/e5/d38d0cb830abede2adb8b147770d2a3d0e7fecc7228245b9b1ae6c24930a/coverage-7.10.6-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "073711de3181b2e204e4870ac83a7c4853115b42e9cd4d145f2231e12d670930"}}, - {name = "coverage-7.10.6-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f4/51/e48e550f6279349895b0ffcd6d2a690e3131ba3a7f4eafccc141966d4dea/coverage-7.10.6-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "137921f2bac5559334ba66122b753db6dc5d1cf01eb7b64eb412bb0d064ef35b"}}, - {name = "coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6"}}, - {name = "coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80"}}, - {name = "coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003"}}, - {name = "coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27"}}, - {name = "coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4"}}, - {name = "coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d"}}, - {name = "coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc"}}, - {name = "coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc"}}, - {name = "coverage-7.10.6-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl",hashes = {sha256 = "160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e"}}, - {name = "coverage-7.10.6-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl",hashes = {sha256 = "628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32"}}, - {name = "coverage-7.10.6-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl",hashes = {sha256 = "df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2"}}, - {name = "coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b"}}, - {name = "coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393"}}, - {name = "coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27"}}, - {name = "coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df"}}, - {name = "coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb"}}, - {name = "coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282"}}, - {name = "coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4"}}, - {name = "coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21"}}, - {name = "coverage-7.10.6-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl",hashes = {sha256 = "92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0"}}, - {name = "coverage-7.10.6-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5"}}, - {name = "coverage-7.10.6-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b"}}, - {name = "coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/06/263f3305c97ad78aab066d116b52250dd316e74fcc20c197b61e07eb391a/coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "5b2dd6059938063a2c9fee1af729d4f2af28fd1a545e9b7652861f0d752ebcea"}}, - {name = "coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e9/60/1e1ded9a4fe80d843d7d53b3e395c1db3ff32d6c301e501f393b2e6c1c1f/coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "388d80e56191bf846c485c14ae2bc8898aa3124d9d35903fef7d907780477634"}}, - {name = "coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b8/25/52136173c14e26dfed8b106ed725811bb53c30b896d04d28d74cb64318b3/coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "90cb5b1a4670662719591aa92d0095bb41714970c0b065b02a2610172dbf0af6"}}, - {name = "coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/cb/1d/ae25a7dc58fcce8b172d42ffe5313fc267afe61c97fa872b80ee72d9515a/coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "961834e2f2b863a0e14260a9a273aff07ff7818ab6e66d2addf5628590c628f9"}}, - {name = "coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f5/7a/1f561d47743710fe996957ed7c124b421320f150f1d38523d8d9102d3e2a/coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "bf9a19f5012dab774628491659646335b1928cfc931bf8d97b0d5918dd58033c"}}, - {name = "coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/6c/ad/8b97cd5d28aecdfde792dcbf646bac141167a5cacae2cd775998b45fabb5/coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "99c4283e2a0e147b9c9cc6bc9c96124de9419d6044837e9799763a0e29a7321a"}}, - {name = "coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/33/6a/95c32b558d9a61858ff9d79580d3877df3eb5bc9eed0941b1f187c89e143/coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "282b1b20f45df57cc508c1e033403f02283adfb67d4c9c35a90281d81e5c52c5"}}, - {name = "coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0d/9c/8ce95dee640a38e760d5b747c10913e7a06554704d60b41e73fdea6a1ffd/coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "8cdbe264f11afd69841bd8c0d83ca10b5b32853263ee62e6ac6a0ab63895f972"}}, - {name = "coverage-7.10.6-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/04/12/7a55b0bdde78a98e2eb2356771fd2dcddb96579e8342bb52aa5bc52e96f0/coverage-7.10.6-cp312-cp312-win32.whl",hashes = {sha256 = "a517feaf3a0a3eca1ee985d8373135cfdedfbba3882a5eab4362bda7c7cf518d"}}, - {name = "coverage-7.10.6-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/36/4a/32b185b8b8e327802c9efce3d3108d2fe2d9d31f153a0f7ecfd59c773705/coverage-7.10.6-cp312-cp312-win_amd64.whl",hashes = {sha256 = "856986eadf41f52b214176d894a7de05331117f6035a28ac0016c0f63d887629"}}, - {name = "coverage-7.10.6-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/08/3a/d5d8dc703e4998038c3099eaf77adddb00536a3cec08c8dcd556a36a3eb4/coverage-7.10.6-cp312-cp312-win_arm64.whl",hashes = {sha256 = "acf36b8268785aad739443fa2780c16260ee3fa09d12b3a70f772ef100939d80"}}, - {name = "coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/16/2bea27e212c4980753d6d563a0803c150edeaaddb0771a50d2afc410a261/coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "c706db3cabb7ceef779de68270150665e710b46d56372455cd741184f3868d8f"}}, - {name = "coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/2a/51/e7159e068831ab37e31aac0969d47b8c5ee25b7d307b51e310ec34869315/coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "8e0c38dc289e0508ef68ec95834cb5d2e96fdbe792eaccaa1bccac3966bbadcc"}}, - {name = "coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e7/c0/246ccbea53d6099325d25cd208df94ea435cd55f0db38099dd721efc7a1f/coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "752a3005a1ded28f2f3a6e8787e24f28d6abe176ca64677bcd8d53d6fe2ec08a"}}, - {name = "coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/7d/fb/7435ef8ab9b2594a6e3f58505cc30e98ae8b33265d844007737946c59389/coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "689920ecfd60f992cafca4f5477d55720466ad2c7fa29bb56ac8d44a1ac2b47a"}}, - {name = "coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/51/f8/d9d64e8da7bcddb094d511154824038833c81e3a039020a9d6539bf303e9/coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ec98435796d2624d6905820a42f82149ee9fc4f2d45c2c5bc5a44481cc50db62"}}, - {name = "coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/43/28/c43ba0ef19f446d6463c751315140d8f2a521e04c3e79e5c5fe211bfa430/coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "b37201ce4a458c7a758ecc4efa92fa8ed783c66e0fa3c42ae19fc454a0792153"}}, - {name = "coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/79/3e/53635bd0b72beaacf265784508a0b386defc9ab7fad99ff95f79ce9db555/coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "2904271c80898663c810a6b067920a61dd8d38341244a3605bd31ab55250dad5"}}, - {name = "coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/4c/55/0964aa87126624e8c159e32b0bc4e84edef78c89a1a4b924d28dd8265625/coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5aea98383463d6e1fa4e95416d8de66f2d0cb588774ee20ae1b28df826bcb619"}}, - {name = "coverage-7.10.6-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/eb/ab/6cfa9dc518c6c8e14a691c54e53a9433ba67336c760607e299bfcf520cb1/coverage-7.10.6-cp311-cp311-win32.whl",hashes = {sha256 = "e3fb1fa01d3598002777dd259c0c2e6d9d5e10e7222976fc8e03992f972a2cba"}}, - {name = "coverage-7.10.6-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/5b/18/99b25346690cbc55922e7cfef06d755d4abee803ef335baff0014268eff4/coverage-7.10.6-cp311-cp311-win_amd64.whl",hashes = {sha256 = "f35ed9d945bece26553d5b4c8630453169672bea0050a564456eb88bdffd927e"}}, - {name = "coverage-7.10.6-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d8/ed/81d86648a07ccb124a5cf1f1a7788712b8d7216b593562683cd5c9b0d2c1/coverage-7.10.6-cp311-cp311-win_arm64.whl",hashes = {sha256 = "99e1a305c7765631d74b98bf7dbf54eeea931f975e80f115437d23848ee8c27c"}}, - {name = "coverage-7.10.6-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/a8/1d/2e64b43d978b5bd184e0756a41415597dfef30fcbd90b747474bd749d45f/coverage-7.10.6-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "70e7bfbd57126b5554aa482691145f798d7df77489a177a6bef80de78860a356"}}, - {name = "coverage-7.10.6-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/23/62/b1e0f513417c02cc10ef735c3ee5186df55f190f70498b3702d516aad06f/coverage-7.10.6-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "e41be6f0f19da64af13403e52f2dec38bbc2937af54df8ecef10850ff8d35301"}}, - {name = "coverage-7.10.6-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e7/16/b800640b7a43e7c538429e4d7223e0a94fd72453a1a048f70bf766f12e96/coverage-7.10.6-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "c61fc91ab80b23f5fddbee342d19662f3d3328173229caded831aa0bd7595460"}}, - {name = "coverage-7.10.6-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/fb/6f/5e03631c3305cad187eaf76af0b559fff88af9a0b0c180d006fb02413d7a/coverage-7.10.6-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "10356fdd33a7cc06e8051413140bbdc6f972137508a3572e3f59f805cd2832fd"}}, - {name = "coverage-7.10.6-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/a1/f30ea0fb400b080730125b490771ec62b3375789f90af0bb68bfb8a921d7/coverage-7.10.6-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "80b1695cf7c5ebe7b44bf2521221b9bb8cdf69b1f24231149a7e3eb1ae5fa2fb"}}, - {name = "coverage-7.10.6-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/02/8e/cfa8fee8e8ef9a6bb76c7bef039f3302f44e615d2194161a21d3d83ac2e9/coverage-7.10.6-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2e4c33e6378b9d52d3454bd08847a8651f4ed23ddbb4a0520227bd346382bbc6"}}, - {name = "coverage-7.10.6-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/93/a9/51be09b75c55c4f6c16d8d73a6a1d46ad764acca0eab48fa2ffaef5958fe/coverage-7.10.6-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "c8a3ec16e34ef980a46f60dc6ad86ec60f763c3f2fa0db6d261e6e754f72e945"}}, - {name = "coverage-7.10.6-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/a6/ba188b376529ce36483b2d585ca7bdac64aacbe5aa10da5978029a9c94db/coverage-7.10.6-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7d79dabc0a56f5af990cc6da9ad1e40766e82773c075f09cc571e2076fef882e"}}, - {name = "coverage-7.10.6-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/d0/4c/37ed872374a21813e0d3215256180c9a382c3f5ced6f2e5da0102fc2fd3e/coverage-7.10.6-cp310-cp310-win32.whl",hashes = {sha256 = "86b9b59f2b16e981906e9d6383eb6446d5b46c278460ae2c36487667717eccf1"}}, - {name = "coverage-7.10.6-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8e/36/9311352fdc551dec5b973b61f4e453227ce482985a9368305880af4f85dd/coverage-7.10.6-cp310-cp310-win_amd64.whl",hashes = {sha256 = "e132b9152749bd33534e5bd8565c7576f135f157b4029b975e15ee184325f528"}}, - {name = "coverage-7.10.6-cp39-cp39-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/91/70/f73ad83b1d2fd2d5825ac58c8f551193433a7deaf9b0d00a8b69ef61cd9a/coverage-7.10.6-cp39-cp39-macosx_10_9_x86_64.whl",hashes = {sha256 = "90558c35af64971d65fbd935c32010f9a2f52776103a259f1dee865fe8259352"}}, - {name = "coverage-7.10.6-cp39-cp39-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/01/e8/099b55cd48922abbd4b01ddd9ffa352408614413ebfc965501e981aced6b/coverage-7.10.6-cp39-cp39-macosx_11_0_arm64.whl",hashes = {sha256 = "8953746d371e5695405806c46d705a3cd170b9cc2b9f93953ad838f6c1e58612"}}, - {name = "coverage-7.10.6-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/ee/d1/c6bac7c9e1003110a318636fef3b5c039df57ab44abcc41d43262a163c28/coverage-7.10.6-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "c83f6afb480eae0313114297d29d7c295670a41c11b274e6bca0c64540c1ce7b"}}, - {name = "coverage-7.10.6-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/01/f9/82c6c061838afbd2172e773156c0aa84a901d59211b4975a4e93accf5c89/coverage-7.10.6-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "7eb68d356ba0cc158ca535ce1381dbf2037fa8cb5b1ae5ddfc302e7317d04144"}}, - {name = "coverage-7.10.6-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/81/6a/35674445b1d38161148558a3ff51b0aa7f0b54b1def3abe3fbd34efe05bc/coverage-7.10.6-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5b15a87265e96307482746d86995f4bff282f14b027db75469c446da6127433b"}}, - {name = "coverage-7.10.6-cp39-cp39-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/18/27/98c99e7cafb288730a93535092eb433b5503d529869791681c4f2e2012a8/coverage-7.10.6-cp39-cp39-musllinux_1_2_aarch64.whl",hashes = {sha256 = "fc53ba868875bfbb66ee447d64d6413c2db91fddcfca57025a0e7ab5b07d5862"}}, - {name = "coverage-7.10.6-cp39-cp39-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/09/05/123e0dba812408c719c319dea05782433246f7aa7b67e60402d90e847545/coverage-7.10.6-cp39-cp39-musllinux_1_2_i686.whl",hashes = {sha256 = "efeda443000aa23f276f4df973cb82beca682fd800bb119d19e80504ffe53ec2"}}, - {name = "coverage-7.10.6-cp39-cp39-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/67/52/d57a42502aef05c6325f28e2e81216c2d9b489040132c18725b7a04d1448/coverage-7.10.6-cp39-cp39-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9702b59d582ff1e184945d8b501ffdd08d2cee38d93a2206aa5f1365ce0b8d78"}}, - {name = "coverage-7.10.6-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/6b/22/7f6fad7dbb37cf99b542c5e157d463bd96b797078b1ec506691bc836f476/coverage-7.10.6-cp39-cp39-win32.whl",hashes = {sha256 = "2195f8e16ba1a44651ca684db2ea2b2d4b5345da12f07d9c22a395202a05b23c"}}, - {name = "coverage-7.10.6-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/62/30/e2fda29bfe335026027e11e6a5e57a764c9df13127b5cf42af4c3e99b937/coverage-7.10.6-cp39-cp39-win_amd64.whl",hashes = {sha256 = "f32ff80e7ef6a5b5b606ea69a36e97b219cd9dc799bcf2963018a4d8f788cfbf"}}, - {name = "coverage-7.10.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl",hashes = {sha256 = "92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3"}}, +sdist = {name = "coverage-7.10.7.tar.gz", url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hashes = {sha256 = "f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239"}} +wheels = [ + {name = "coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520"}}, + {name = "coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360"}}, + {name = "coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e"}}, + {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd"}}, + {name = "coverage-7.10.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl",hashes = {sha256 = "b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2"}}, + {name = "coverage-7.10.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681"}}, + {name = "coverage-7.10.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880"}}, + {name = "coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63"}}, + {name = "coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699"}}, + {name = "coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0"}}, + {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399"}}, + {name = "coverage-7.10.7-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl",hashes = {sha256 = "67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235"}}, + {name = "coverage-7.10.7-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d"}}, + {name = "coverage-7.10.7-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a"}}, + {name = "coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d"}}, + {name = "coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49"}}, + {name = "coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c"}}, + {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f"}}, + {name = "coverage-7.10.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl",hashes = {sha256 = "dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698"}}, + {name = "coverage-7.10.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843"}}, + {name = "coverage-7.10.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546"}}, + {name = "coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c"}}, + {name = "coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0"}}, + {name = "coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999"}}, + {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2"}}, + {name = "coverage-7.10.7-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl",hashes = {sha256 = "2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a"}}, + {name = "coverage-7.10.7-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb"}}, + {name = "coverage-7.10.7-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb"}}, + {name = "coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/13/e4/eb12450f71b542a53972d19117ea5a5cea1cab3ac9e31b0b5d498df1bd5a/coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "7bb3b9ddb87ef7725056572368040c32775036472d5a033679d1fa6c8dc08417"}}, + {name = "coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/37/66/593f9be12fc19fb36711f19a5371af79a718537204d16ea1d36f16bd78d2/coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "18afb24843cbc175687225cab1138c95d262337f5473512010e46831aa0c2973"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/66/80/4c49f7ae09cafdacc73fbc30949ffe77359635c168f4e9ff33c9ebb07838/coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "399a0b6347bcd3822be369392932884b8216d0944049ae22925631a9b3d4ba4c"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a6/90/a64aaacab3b37a17aaedd83e8000142561a29eb262cede42d94a67f7556b/coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "314f2c326ded3f4b09be11bc282eb2fc861184bc95748ae67b360ac962770be7"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/2e/2dda59afd6103b342e096f246ebc5f87a3363b5412609946c120f4e7750d/coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c41e71c9cfb854789dee6fc51e46743a6d138b1803fab6cb860af43265b42ea6"}}, + {name = "coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/53/dc/8d8119c9051d50f3119bb4a75f29f1e4a6ab9415cd1fa8bf22fcc3fb3b5f/coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "bc01f57ca26269c2c706e838f6422e2a8788e41b3e3c65e2f41148212e57cd59"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/b3/edaff9c5d79ee4d4b6d3fe046f2b1d799850425695b789d491a64225d493/coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a6442c59a8ac8b85812ce33bc4d05bde3fb22321fa8294e2a5b487c3505f611b"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/11/25/9a0728564bb05863f7e513e5a594fe5ffef091b325437f5430e8cfb0d530/coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "78a384e49f46b80fb4c901d52d92abe098e78768ed829c673fbb53c498bef73a"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/fd/ca2650443bfbef5b0e74373aac4df67b08180d2f184b482c41499668e258/coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "5e1e9802121405ede4b0133aa4340ad8186a1d2526de5b7c3eca519db7bb89fb"}}, + {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/24/79/f692f125fb4299b6f963b0745124998ebb8e73ecdfce4ceceb06a8c6bec5/coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "d41213ea25a86f69efd1575073d34ea11aabe075604ddf3d148ecfec9e1e96a1"}}, + {name = "coverage-7.10.7-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/5e/75/61b9bbd6c7d24d896bfeec57acba78e0f8deac68e6baf2d4804f7aae1f88/coverage-7.10.7-cp312-cp312-win32.whl",hashes = {sha256 = "77eb4c747061a6af8d0f7bdb31f1e108d172762ef579166ec84542f711d90256"}}, + {name = "coverage-7.10.7-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ca/f3/3bf7905288b45b075918d372498f1cf845b5b579b723c8fd17168018d5f5/coverage-7.10.7-cp312-cp312-win_amd64.whl",hashes = {sha256 = "f51328ffe987aecf6d09f3cd9d979face89a617eacdaea43e7b3080777f647ba"}}, + {name = "coverage-7.10.7-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/5c/44/3e32dbe933979d05cf2dac5e697c8599cfe038aaf51223ab901e208d5a62/coverage-7.10.7-cp312-cp312-win_arm64.whl",hashes = {sha256 = "bda5e34f8a75721c96085903c6f2197dc398c20ffd98df33f866a9c8fd95f4bf"}}, + {name = "coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/5d/c1a17867b0456f2e9ce2d8d4708a4c3a089947d0bec9c66cdf60c9e7739f/coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "a609f9c93113be646f44c2a0256d6ea375ad047005d7f57a5c15f614dc1b2f59"}}, + {name = "coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/54/f0/514dcf4b4e3698b9a9077f084429681bf3aad2b4a72578f89d7f643eb506/coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "65646bb0359386e07639c367a22cf9b5bf6304e8630b565d0626e2bdf329227a"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/20/f6/9626b81d17e2a4b25c63ac1b425ff307ecdeef03d67c9a147673ae40dc36/coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "5f33166f0dfcce728191f520bd2692914ec70fac2713f6bf3ce59c3deacb4699"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/b0/ef/bd8e719c2f7417ba03239052e099b76ea1130ac0cbb183ee1fcaa58aaff3/coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "35f5e3f9e455bb17831876048355dca0f758b6df22f49258cb5a91da23ef437d"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a5/b6/bf054de41ec948b151ae2b79a55c107f5760979538f5fb80c195f2517718/coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4da86b6d62a496e908ac2898243920c7992499c1712ff7c2b6d837cc69d9467e"}}, + {name = "coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/0f/e5/3860756aa6f9318227443c6ce4ed7bf9e70bb7f1447a0353f45ac5c7974b/coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "6b8b09c1fad947c84bbbc95eca841350fad9cbfa5a2d7ca88ac9f8d836c92e23"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/26/0f/bd08bd042854f7fd07b45808927ebcce99a7ed0f2f412d11629883517ac2/coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4376538f36b533b46f8971d3a3e63464f2c7905c9800db97361c43a2b14792ab"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/8e/a7/4777b14de4abcc2e80c6b1d430f5d51eb18ed1d75fca56cbce5f2db9b36e/coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "121da30abb574f6ce6ae09840dae322bef734480ceafe410117627aa54f76d82"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/34/72/17d082b00b53cd45679bad682fac058b87f011fd8b9fe31d77f5f8d3a4e4/coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "88127d40df529336a9836870436fc2751c339fbaed3a836d42c93f3e4bd1d0a2"}}, + {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/7a/92367572eb5bdd6a84bfa278cc7e97db192f9f45b28c94a9ca1a921c3577/coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ba58bbcd1b72f136080c0bccc2400d66cc6115f3f906c499013d065ac33a4b61"}}, + {name = "coverage-7.10.7-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/2f/88/a23cc185f6a805dfc4fdf14a94016835eeb85e22ac3a0e66d5e89acd6462/coverage-7.10.7-cp311-cp311-win32.whl",hashes = {sha256 = "972b9e3a4094b053a4e46832b4bc829fc8a8d347160eb39d03f1690316a99c14"}}, + {name = "coverage-7.10.7-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fe/ef/0b510a399dfca17cec7bc2f05ad8bd78cf55f15c8bc9a73ab20c5c913c2e/coverage-7.10.7-cp311-cp311-win_amd64.whl",hashes = {sha256 = "a7b55a944a7f43892e28ad4bc0561dfd5f0d73e605d1aa5c3c976b52aea121d2"}}, + {name = "coverage-7.10.7-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/7f/023657f301a276e4ba1850f82749bc136f5a7e8768060c2e5d9744a22951/coverage-7.10.7-cp311-cp311-win_arm64.whl",hashes = {sha256 = "736f227fb490f03c6488f9b6d45855f8e0fd749c007f9303ad30efab0e73c05a"}}, + {name = "coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/e5/6c/3a3f7a46888e69d18abe3ccc6fe4cb16cccb1e6a2f99698931dafca489e6/coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "fc04cc7a3db33664e0c2d10eb8990ff6b3536f6842c9590ae8da4c614b9ed05a"}}, + {name = "coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/03/94/952d30f180b1a916c11a56f5c22d3535e943aa22430e9e3322447e520e1c/coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "e201e015644e207139f7e2351980feb7040e6f4b2c2978892f3e3789d1c125e5"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/50/2b/9e0cf8ded1e114bcd8b2fd42792b57f1c4e9e4ea1824cde2af93a67305be/coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "240af60539987ced2c399809bd34f7c78e8abe0736af91c3d7d0e795df633d17"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/19/20/d0384ac06a6f908783d9b6aa6135e41b093971499ec488e47279f5b846e6/coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8421e088bc051361b01c4b3a50fd39a4b9133079a2229978d9d30511fd05231b"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/60/83/5c283cff3d41285f8eab897651585db908a909c572bdc014bcfaf8a8b6ae/coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6be8ed3039ae7f7ac5ce058c308484787c86e8437e72b30bf5e88b8ea10f3c87"}}, + {name = "coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/60/22/02eb98fdc5ff79f423e990d877693e5310ae1eab6cb20ae0b0b9ac45b23b/coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e28299d9f2e889e6d51b1f043f58d5f997c373cc12e6403b90df95b8b047c13e"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b4/bc/25c83bcf3ad141b32cd7dc45485ef3c01a776ca3aa8ef0a93e77e8b5bc43/coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c4e16bd7761c5e454f4efd36f345286d6f7c5fa111623c355691e2755cae3b9e"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3c/b7/95574702888b58c0928a6e982038c596f9c34d52c5e5107f1eef729399b5/coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "b1c81d0e5e160651879755c9c675b974276f135558cf4ba79fee7b8413a515df"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/47/b6/40095c185f235e085df0e0b158f6bd68cc6e1d80ba6c7721dc81d97ec318/coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "606cc265adc9aaedcc84f1f064f0e8736bc45814f15a357e30fca7ecc01504e0"}}, + {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c8/50/4aea0556da7a4b93ec9168420d170b55e2eb50ae21b25062513d020c6861/coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "10b24412692df990dbc34f8fb1b6b13d236ace9dfdd68df5b28c2e39cafbba13"}}, + {name = "coverage-7.10.7-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/6a/28/ea1a84a60828177ae3b100cb6723838523369a44ec5742313ed7db3da160/coverage-7.10.7-cp310-cp310-win32.whl",hashes = {sha256 = "b51dcd060f18c19290d9b8a9dd1e0181538df2ce0717f562fff6cf74d9fc0b5b"}}, + {name = "coverage-7.10.7-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fc/1a/a81d46bbeb3c3fd97b9602ebaa411e076219a150489bcc2c025f151bd52d/coverage-7.10.7-cp310-cp310-win_amd64.whl",hashes = {sha256 = "3a622ac801b17198020f09af3eaf45666b344a0d69fc2a6ffe2ea83aeef1d807"}}, + {name = "coverage-7.10.7-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl",hashes = {sha256 = "f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260"}}, ] marker = "\"test\" in dependency_groups" @@ -340,19 +338,6 @@ wheels = [ {name = "orjson-3.11.3-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/33/ba/29023771f334096f564e48d82ed855a0ed3320389d6748a9c949e25be734/orjson-3.11.3-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f8d902867b699bcd09c176a280b1acdab57f924489033e53d0afe79817da37e6"}}, {name = "orjson-3.11.3-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/39/62/b5a1eca83f54cb3aa11a9645b8a22f08d97dbd13f27f83aae7c6666a0a05/orjson-3.11.3-cp310-cp310-win32.whl",hashes = {sha256 = "bb93562146120bb51e6b154962d3dadc678ed0fce96513fa6bc06599bb6f6edc"}}, {name = "orjson-3.11.3-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e3/c0/7ebfaa327d9a9ed982adc0d9420dbce9a3fec45b60ab32c6308f731333fa/orjson-3.11.3-cp310-cp310-win_amd64.whl",hashes = {sha256 = "976c6f1975032cc327161c65d4194c549f2589d88b105a5e3499429a54479770"}}, - {name = "orjson-3.11.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/99/a6/18d88ccf8e5d8f711310eba9b4f6562f4aa9d594258efdc4dcf8c1550090/orjson-3.11.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "56afaf1e9b02302ba636151cfc49929c1bb66b98794291afd0e5f20fecaf757c"}}, - {name = "orjson-3.11.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/ee/18/e210365a17bf984c89db40c8be65da164b4ce6a866a2a0ae1d6407c2630b/orjson-3.11.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "913f629adef31d2d350d41c051ce7e33cf0fd06a5d1cb28d49b1899b23b903aa"}}, - {name = "orjson-3.11.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/26/43/6b3f8ec15fa910726ed94bd2e618f86313ad1cae7c3c8c6b9b8a3a161814/orjson-3.11.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "e0a23b41f8f98b4e61150a03f83e4f0d566880fe53519d445a962929a4d21045"}}, - {name = "orjson-3.11.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/4a/ed/f41d2406355ce67efdd4ab504732b27bea37b7dbdab3eb86314fe764f1b9/orjson-3.11.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3d721fee37380a44f9d9ce6c701b3960239f4fb3d5ceea7f31cbd43882edaa2f"}}, - {name = "orjson-3.11.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/3e/a1/1be02950f92c82e64602d3d284bd76d9fc82a6b92c9ce2a387e57a825a11/orjson-3.11.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "73b92a5b69f31b1a58c0c7e31080aeaec49c6e01b9522e71ff38d08f15aa56de"}}, - {name = "orjson-3.11.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/39/49/46766ac00c68192b516a15ffc44c2a9789ca3468b8dc8a500422d99bf0dd/orjson-3.11.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "d2489b241c19582b3f1430cc5d732caefc1aaf378d97e7fb95b9e56bed11725f"}}, - {name = "orjson-3.11.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/e1/27fd5e7600fdd82996329d48ee56f6e9e9ae4d31eadbc7f93fd2ff0d8214/orjson-3.11.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "c5189a5dab8b0312eadaf9d58d3049b6a52c454256493a557405e77a3d67ab7f"}}, - {name = "orjson-3.11.3-cp39-cp39-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d8/21/f57ef08799a68c36ef96fe561101afeef735caa80814636b2e18c234e405/orjson-3.11.3-cp39-cp39-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9d8787bdfbb65a85ea76d0e96a3b1bed7bf0fbcb16d40408dc1172ad784a49d2"}}, - {name = "orjson-3.11.3-cp39-cp39-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/cd/84/a3a24306a9dc482e929232c65f5b8c69188136edd6005441d8cc4754f7ea/orjson-3.11.3-cp39-cp39-musllinux_1_2_armv7l.whl",hashes = {sha256 = "8e531abd745f51f8035e207e75e049553a86823d189a51809c078412cefb399a"}}, - {name = "orjson-3.11.3-cp39-cp39-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/11/98/fdae5b2c28bc358e6868e54c8eca7398c93d6a511f0436b61436ad1b04dc/orjson-3.11.3-cp39-cp39-musllinux_1_2_i686.whl",hashes = {sha256 = "8ab962931015f170b97a3dd7bd933399c1bae8ed8ad0fb2a7151a5654b6941c7"}}, - {name = "orjson-3.11.3-cp39-cp39-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/7d/a9/2fe5cd69ed231f3ed88b1ad36a6957e3d2c876eb4b2c6b17b8ae0a6681fc/orjson-3.11.3-cp39-cp39-musllinux_1_2_x86_64.whl",hashes = {sha256 = "124d5ba71fee9c9902c4a7baa9425e663f7f0aecf73d31d54fe3dd357d62c1a7"}}, - {name = "orjson-3.11.3-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/ac/a4/7d4c8aefb45f6c8d7d527d84559a3a7e394b9fd1d424a2b5bcaf75fa68e7/orjson-3.11.3-cp39-cp39-win32.whl",hashes = {sha256 = "22724d80ee5a815a44fc76274bb7ba2e7464f5564aacb6ecddaa9970a83e3225"}}, - {name = "orjson-3.11.3-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9a/1f/1d6a24d22001e96c0afcf1806b6eabee1109aebd2ef20ec6698f6a6012d7/orjson-3.11.3-cp39-cp39-win_amd64.whl",hashes = {sha256 = "215c595c792a87d4407cb72dd5e0f6ee8e694ceeb7f9102b533c5a9bf2a916bb"}}, ] marker = "\"default\" in dependency_groups" @@ -376,76 +361,6 @@ dependencies = [ "tzdata; sys_platform == \"win32\"", ] -[[packages]] -name = "psycopg2-binary" -version = "2.9.10" -requires-python = ">=3.8" -sdist = {name = "psycopg2-binary-2.9.10.tar.gz", url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hashes = {sha256 = "4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}} -wheels = [ - {name = "psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl",hashes = {sha256 = "26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl",hashes = {sha256 = "e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}}, - {name = "psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl",hashes = {sha256 = "27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/49/7d/465cc9795cf76f6d329efdafca74693714556ea3891813701ac1fee87545/psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl",hashes = {sha256 = "880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8b/31/6d225b7b641a1a2148e3ed65e1aa74fc86ba3fee850545e27be9e1de893d/psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/30/b7/a68c2b4bff1cbb1728e3ec864b2d92327c77ad52edcd27922535a8366f68/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/0b/b1/cfedc0e0e6f9ad61f8657fd173b2f831ce261c02a08c0b09c652b127d813/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/18/ed/0a8e4153c9b769f59c02fb5e7914f20f0b2483a19dae7bf2db54b743d0d0/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/10/db/d09da68c6a0cdab41566b74e0a6068a425f077169bed0946559b7348ebe9/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/94/28/4d6f8c255f0dfffb410db2b3f9ac5218d959a66c715c34cac31081e19b95/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/05/f7/20d7bf796593c4fea95e12119d6cc384ff1f6141a24fbb7df5a668d29d29/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/4d/e4/0c407ae919ef626dbdb32835a03b6737013c3cc7240169843965cada2bdf/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/2d/70/aa69c9f69cf09a01da224909ff6ce8b68faeef476f00f7ec377e8f03be70/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/d3/bd/213e59854fafe87ba47814bf413ace0dcee33a89c8c8c814faca6bc7cf3c/psycopg2_binary-2.9.10-cp312-cp312-win32.whl",hashes = {sha256 = "ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64"}}, - {name = "psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/92/29/06261ea000e2dc1e22907dbbc483a1093665509ea586b29b8986a0e56733/psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl",hashes = {sha256 = "18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/9c/8f/9feb01291d0d7a0a4c6a6bab24094135c2b59c6a81943752f632c75896d6/psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl",hashes = {sha256 = "04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/15/30/346e4683532011561cd9c8dfeac6a8153dd96452fee0b12666058ab7893c/psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl",hashes = {sha256 = "1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/66/6e/4efebe76f76aee7ec99166b6c023ff8abdc4e183f7b70913d7c047701b79/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/7f/fd/ff83313f86b50f7ca089b161b8e0a22bb3c319974096093cd50680433fdb/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/e6/c4/bfadd202dcda8333a7ccafdc51c541dbdfce7c2c7cda89fa2374455d795f/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/f1/09f45ac25e704ac954862581f9f9ae21303cc5ded3d0b775532b407f0e90/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9e/2e/9beaea078095cc558f215e38f647c7114987d9febfc25cb2beed7c3582a5/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/01/9e/ef93c5d93f3dc9fc92786ffab39e323b9aed066ba59fdc34cf85e2722271/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a5/f0/049e9631e3268fe4c5a387f6fc27e267ebe199acf1bc1bc9cbde4bd6916c/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/dc/9a/bcb8773b88e45fb5a5ea8339e2104d82c863a3b8558fbb2aadfe66df86b3/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/e2/6b/144336a9bf08a67d217b3af3246abb1d027095dab726f0687f01f43e8c03/psycopg2_binary-2.9.10-cp311-cp311-win32.whl",hashes = {sha256 = "ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392"}}, - {name = "psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/61/69/3b3d7bd583c6d3cbe5100802efa5beacaacc86e37b653fc708bf3d6853b8/psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl",hashes = {sha256 = "ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/7a/81/331257dbf2801cdb82105306042f7a1637cc752f65f2bb688188e0de5f0b/psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl",hashes = {sha256 = "0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e7/9a/7f4f2f031010bbfe6a02b4a15c01e12eb6b9b7b358ab33229f28baadbfc1/psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl",hashes = {sha256 = "3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/e5/57/8ddd4b374fa811a0b0a0f49b6abad1cde9cb34df73ea3348cc283fcd70b4/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/f9/66/d1e52c20d283f1f3a8e7e5c1e06851d432f123ef57b13043b4f9b21ffa1f/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a0/cb/592d44a9546aba78f8a1249021fe7c59d3afb8a0ba51434d6610cc3462b6/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/64/33/c8548560b94b7617f203d7236d6cdf36fe1a5a3645600ada6efd79da946f/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b0/0e/c2da0db5bea88a3be52307f88b75eec72c4de62814cbe9ee600c29c06334/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/d7/774afa1eadb787ddf41aab52d4c62785563e29949613c958955031408ae6/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/5e/ed/440dc3f5991a8c6172a1cde44850ead0e483a375277a1aef7cfcec00af07/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/03/be/2cc8f4282898306732d2ae7b7378ae14e8df3c1231b53579efa056aae887/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/d0/12/fb8e4f485d98c570e00dad5800e9a2349cfe0f71a767c856857160d343a5/psycopg2_binary-2.9.10-cp310-cp310-win32.whl",hashes = {sha256 = "e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b"}}, - {name = "psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/22/4f/217cd2471ecf45d82905dd09085e049af8de6cfdc008b6663c3226dc1c98/psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl",hashes = {sha256 = "3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/bc/e77648009b6e61af327c607543f65fdf25bcfb4100f5a6f3bdb62ddac03c/psycopg2_binary-2.9.10-cp39-cp39-macosx_12_0_x86_64.whl",hashes = {sha256 = "7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/e0/e8/5a12211a1f5b959f3e3ccd342eace60c1f26422f53e06d687821dc268780/psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/47/ed/5932b0458a7fc61237b653df050513c8d18a6f4083cc7f90dcef967f7bce/psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/71/df/8047d85c3d23864aca4613c3be1ea0fe61dbe4e050a89ac189f9dce4403e/psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/f3/de/6157e4ef242920e8f2749f7708d5cc8815414bdd4a27a91996e7cd5c80df/psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/25/f9/0fc49efd2d4d6db3a8d0a3f5749b33a0d3fdd872cad49fbf5bfce1c50027/psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_aarch64.whl",hashes = {sha256 = "79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/57/bc/2ed1bd182219065692ed458d218d311b0b220b20662d25d913bc4e8d3549/psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_i686.whl",hashes = {sha256 = "8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/71/2a/43f77a9b8ee0b10e2de784d97ddc099d9fe0d9eec462a006e4d2cc74756d/psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/57/86/d2943df70469e6afab3b5b8e1367fccc61891f46de436b24ddee6f2c8404/psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/85/21/195d69371330983aa16139e60ba855d0a18164c9295f3a3696be41bbcd54/psycopg2_binary-2.9.10-cp39-cp39-win32.whl",hashes = {sha256 = "3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8"}}, - {name = "psycopg2_binary-2.9.10-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ad/53/73196ebc19d6fbfc22427b982fbc98698b7b9c361e5e7707e3a3247cf06d/psycopg2_binary-2.9.10-cp39-cp39-win_amd64.whl",hashes = {sha256 = "30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "pytest" version = "8.4.2" @@ -499,19 +414,6 @@ dependencies = [ "colorama; platform_system == \"Windows\"", ] -[[packages]] -name = "types-psycopg2" -version = "2.9.21.20250915" -requires-python = ">=3.9" -sdist = {name = "types_psycopg2-2.9.21.20250915.tar.gz", url = "https://files.pythonhosted.org/packages/8f/20/3dcb89df8d1661cf6c4c2d9f84d4ba94dde48559cdcf7b536a380a9c387f/types_psycopg2-2.9.21.20250915.tar.gz", hashes = {sha256 = "bfeb8f54c32490e7b5edc46215ab4163693192bc90407b4a023822de9239f5c8"}} -wheels = [ - {name = "types_psycopg2-2.9.21.20250915-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/93/4d/ebf1c72809a30150ad142074e1ad5101304f7569c0df2fa872906d76d0af/types_psycopg2-2.9.21.20250915-py3-none-any.whl",hashes = {sha256 = "eefe5ccdc693fc086146e84c9ba437bb278efe1ef330b299a0cb71169dc6c55f"}}, -] -marker = "\"types\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "types-tqdm" version = "4.67.0.20250809" @@ -527,19 +429,6 @@ dependencies = [ "types-requests", ] -[[packages]] -name = "xlsxwriter" -version = "3.2.9" -requires-python = ">=3.8" -sdist = {name = "xlsxwriter-3.2.9.tar.gz", url = "https://files.pythonhosted.org/packages/46/2c/c06ef49dc36e7954e55b802a8b231770d286a9758b3d936bd1e04ce5ba88/xlsxwriter-3.2.9.tar.gz", hashes = {sha256 = "254b1c37a368c444eac6e2f867405cc9e461b0ed97a3233b2ac1e574efb4140c"}} -wheels = [ - {name = "xlsxwriter-3.2.9-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3a/0c/3662f4a66880196a590b202f0db82d919dd2f89e99a27fadef91c4a33d41/xlsxwriter-3.2.9-py3-none-any.whl",hashes = {sha256 = "9a5db42bc5dff014806c58a20b9eae7322a134abb6fce3c92c181bfb275ec5b3"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "tomli" version = "2.2.1" @@ -795,55 +684,49 @@ dependencies = [ [[packages]] name = "ruamel-yaml-clib" -version = "0.2.12" +version = "0.2.13" requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.12.tar.gz", url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hashes = {sha256 = "6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl",hashes = {sha256 = "4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl",hashes = {sha256 = "3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl",hashes = {sha256 = "e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl",hashes = {sha256 = "6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl",hashes = {sha256 = "bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl",hashes = {sha256 = "e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5"}}, - {name = "ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl",hashes = {sha256 = "0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl",hashes = {sha256 = "cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl",hashes = {sha256 = "bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4"}}, - {name = "ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl",hashes = {sha256 = "a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl",hashes = {sha256 = "22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl",hashes = {sha256 = "3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da"}}, - {name = "ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl",hashes = {sha256 = "ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/46/ccdef7a84ad745c37cb3d9a81790f28fbc9adf9c237dba682017b123294e/ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl",hashes = {sha256 = "fc4b630cd3fa2cf7fce38afa91d7cfe844a9f75d7f0f36393fa98815e911d987"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/29/09/932360f30ad1b7b79f08757e0a6fb8c5392a52cdcc182779158fe66d25ac/ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux2014_aarch64.whl",hashes = {sha256 = "bc5f1e1c28e966d61d2519f2a3d451ba989f9ea0f2307de7bc45baa526de9e45"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/2a/5b27602e7a4344c1334e26bf4739746206b7a60a8acdba33a61473468b73/ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5a0e060aace4c24dcaf71023bbd7d42674e3b230f7e7b97317baf1e953e5b519"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/da/1c/23497017c554fc06ff5701b29355522cff850f626337fff35d9ab352cb18/ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "e2f1c3765db32be59d18ab3953f43ab62a761327aafc1594a2a1fbe038b8b8a7"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/68/e6/f3d4ff3223f9ea49c3b7169ec0268e42bd49f87c70c0e3e853895e4a7ae2/ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl",hashes = {sha256 = "d85252669dc32f98ebcd5d36768f5d4faeaeaa2d655ac0473be490ecdae3c285"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/84/62/ead07043527642491e5011b143f44b81ef80f1025a96069b7210e0f2f0f3/ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl",hashes = {sha256 = "e143ada795c341b56de9418c58d028989093ee611aa27ffb9b7f609c00d813ed"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/52/b3/fe4d84446f7e4887e3bea7ceff0a7df23790b5ed625f830e79ace88ebefb/ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2c59aa6170b990d8d2719323e628aaf36f3bfbc1c26279c0eeeb24d05d2d11c7"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl",url = "https://files.pythonhosted.org/packages/6e/b3/7feb99a00bfaa5c6868617bb7651308afde85e5a0b23cd187fe5de65feeb/ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl",hashes = {sha256 = "beffaed67936fbbeffd10966a4eb53c402fafd3d6833770516bf7314bc6ffa12"}}, - {name = "ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/07/de635108684b7a5bb06e432b0930c5a04b6c59efe73bd966d8db3cc208f2/ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl",hashes = {sha256 = "040ae85536960525ea62868b642bdb0c2cc6021c9f9d507810c0c604e66f5a7b"}}, +sdist = {name = "ruamel.yaml.clib-0.2.13.tar.gz", url = "https://files.pythonhosted.org/packages/3c/fd/32c91c4d301ebe7931a3c44f7593650613afe14854e3cc9d2764321b7a46/ruamel.yaml.clib-0.2.13.tar.gz", hashes = {sha256 = "8d4f8d7853053a5a19171a0f515f1e14f503bd3e772c4da6bafe7d0893d4f299"}} +wheels = [ + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/30/b5/3bff051bfdc33f8d797a1a025a1dc74fb13703611917f611e62e12061893/ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "817a3d8dbbefc337e9081d9bddd54ee6ef5d5351cccb5240d731d604c1d86d29"}}, + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/51/a3/8f199f9d6ff862b503eae06a4a9ec9f20fc232ee7590287d969ebf5a8859/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "b29e3a746dd774a49ec6412529dc6a7338efe0828230b7c5da2aef3ee6eb7cbc"}}, + {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/fb/47728a32be2e7ac00f854d30b0d39ed62e9eefdff19c024f4e5c49d3341c/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bae8383e02ef5a7c6b44a594746dcdb0994b8bdf4317d2fba3bbafe8262dfa9d"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/9a/21de96f5fc51e495f6ebe87f01a679ec3b9a36082431942d7dc7295175da/ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "b3dae045e57780a6ec39a018220d82931d6cb3e6e8b326a9a804597ffa6f8520"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/26/4203139b2f1fc94b01e5fb5c2e9a5822725baad930ceb869e3525157f1b1/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "f6d476bc7bb9b25d54133f95d0766aaf1662689f6c26e9e08d28a45609a634f2"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/16/db/ec371bb692c404ad1cfad715b89300cca841a4ac31ed3467c66a5911ce01/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5622265f2b64f6933a29a5d8e33385a0c3ef47f509354602d0c28f5d7d126fe3"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/cb/71/230119917102ea682c6a1fa2e322ca18cdd4077342680908999e18fd84cc/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b2ba05d2dbe39435915aa20d53336d55fd0fa6c25eb1c580d60fc1f753e40a41"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/2d/22afc8402474285fc9bf35cb630f6194aecb2c777b304f872dada19ab06c/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",hashes = {sha256 = "a5a43fc6f95c58c1a65cbb7b68b31f9721362e10c5276d3f8db4ccde8e9acb04"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c9/c7/928d0692ac05bb0f05b337e151da28792f25782ae0e2cda1a5bf0dda9dde/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "5ce7178bd66cffe4eb4ce40c2ff525f42ccfa6e2e31eeea27293fe5bd0ae2d93"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b2/2972fae8d9dc10314e39c254638320e1b028511185cebaa96f3382122f40/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "490c5dfaf9f218f335f2f6f7ba52f7ce5460e94d67a42c8dd0096deae7684d23"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/89/e3/fc6c145f7d122a39793f9a8e508ba060a3bc5883065f3f11dbc9011023bd/ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",hashes = {sha256 = "b5e32adbb14ffdb1130c699128070766e5cf781b3b05dd87049c16bb94395212"}}, + {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/95/e5/6cb4654b62b90116962d88cb74419caa3eb5fc50ccbc932d5553adf70812/ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",hashes = {sha256 = "826ce141d368f10a99a4fc6fab332ba4203f63da25828853d7957e76d13f7d41"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/ae/b6b3ed185206af04c779eec77a4a57587278b713b72034957d127307bbef/ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "810500056a0e294131042eca6687a786e82aad817e8e0bc5ce059d2f95b67fef"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/6f/2b/b0307fc587cebabd8faaaeb1476c825fe4dbb5ad2b5c152dfbcc31b258c4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "f8e44b1b583f93a8f4d00e5285d9ea8ccd9524cdd4c54788db2880a11f21287d"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/a9/2ddad6eb03195206aca765b4ff7bd7098c46fbc65957d5ac53f96ef8d6f4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "4d1ab027be86f7d5ccc9b777a22194fd3850012df413f216bf1608768b4daa2f"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/42/a0/ded38d60fc34f69afef6f3e379f896a80d34532bb6b4828e95f7003be610/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "55f01d82d7d96213f0963609876ae841c81e217985c668100c5fb95cc9a564b3"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/3e/49/121067d5621a77913dc0fd473bdf2ec4a515c564806b107d3b1257cd5b14/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",hashes = {sha256 = "031c7cdd5751cda19ddf90e42756ec2ee72a30791c2f65f5f800f9ee929862f0"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/fc/0845929db1840eec6aa6133b8c89941e251c3bc67180aee7d71a30bc1c80/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "ba745411caabc994963729663a7c2d09398795c36dc4b5672ca4fdc445ab6544"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d6/0a/dd0007d41a321edf64c4bda0aab70936281ee213406e6913105499f7d62a/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fb90267cc3748858236b9cedb580191be1d0d218f6cde64e954fa759d90fb08d"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/93/0d/eeed0a9824b14fa089a82247fca96de6b202af84e4093ba2a15afc0b4cb9/ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",hashes = {sha256 = "5188c3212c10fcd14a6de8ce787c0713a49fc5972054703f790cfd9f1d27a90b"}}, + {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/45/c882a32e4b5c0ed6a5b4e0933af427fef48f3aad7259b87f38e33ee20536/ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",hashes = {sha256 = "518b13f9fe601a559a759f3d21cdb2590cb85611934a7c0f09c09dc1a869ec83"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/86/fa6be53f11d1c663a261d137d616bbb326cb937b361a55a00cacf9ba76aa/ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "825a7483da63b9448fdad9778269a5d02e5f64040aa8326fec071e830c2fc49c"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/f1/d26dbf3c53befd01d8b341cb29c555c1e910ef29478b4ebd50d1d67fbc64/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "54707e2200b9e1c34a62af09edd3ea3469a722951365311398458abe36ff45d6"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a8/80/119ce9e40690b7e0dfc6bec41369333593f8738fa4f58dbbffdb9b80339b/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "958b1fc6334cd745db7099a69da4f60503cfbbc05ce1412b1d06c5922cd8314b"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/0b/85/09625df6b3ccf0ae0ddc93c0ab4d89f785debc0ae1e7efa541696b788b6a/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d50c415df5ba918c483a2486a90dd5a3e6df634fca688f71d266e15a618d643f"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/e0/2e/c05050760b20fe10cb17b3fe7efd5d5653baefa862121f5b0825418f3d8b/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "bbdb57e57a5bb3510bfb43496bab44857546c56c7f04bb7bfd0b248388d41c2e"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d7/e0/6cfd5c61070f0e5556a724c753919b8758b86fe89f5b53eb9f53d0506b27/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "df8ef03eb60fc2e1c0570612363091898b97a7b3181422e1b34c3ee22d7e0a9e"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/85/01/14964bd94bbe809497d1affc0625e428803cc9fd21e145b1b2edcbbc3c92/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "89168de27694f7903a1317381525efdf7ea2c377b5b1eeeb927940870a7e8945"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/1d/c0/a39cc7de38b5acc81241dda9888ecabc1ee90fb3ebf9189ddfc65c08555d/ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",hashes = {sha256 = "8cdb4c720137bb7834cf2c09753d5f3468023eebb7f6ad2604ddf920328753dd"}}, + {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1f/7f/d5c1e0279df8dd9ca92138bec8387a07112d97598f668ccb3190d0bc06aa/ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",hashes = {sha256 = "670d8a9c5b22af152863236b7a7fec471aafefc5e89b637b8f98d280cb92a0ce"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/73/88/8d40634f34fd206be8aab060537890ae939f67d3598718426be62493e4fe/ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "a67efad34e15232f03333d4a7cc96b1db8ecb676439b6a3db10d49ffbd3a8606"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/3b/25/9deabe6323318acb61e521e6fdcc92575af7f5d4f716def8c42d0cb0d6b2/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "ce8be9ce9c967a9952e92d9280d18de9ae331284645b50dc32f71ef207ef00e1"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/ce/48e9802811c6fe757aae2387e2feb24bf6964fa9a467c26da6c20daea916/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "e16f9611130aa3695aaff32d956e49b45cef902aa15cf9de18ebf919d6acc153"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/28/f6/dff4b9988da26b994f8bb019344ec44b81699f0abf0515040001d6cce8a3/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3a6afcf136a474703e9c7fa62fab76870775c98a4f59f599fdd24348dca3a229"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/81/bd/80fccf71b3387c2fcde566b3d45c827d8380401ee76907e1639ff297f996/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",hashes = {sha256 = "70328e9afcb83deb689547989e6b79fc8f094964b8b754b44a70ba7e68e523fe"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/d6/80134d4c11bd396d438964de26f9d7d9300e35bc2fbdca1584634f262d0a/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "fc2c45c0b5b7845278148f18a4039b6d8fde3f7266dd00986684453a57d3444a"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/99/a4/903a317cbb13071663ad370a4a16e7ba44e62d057352782d760dcd904a72/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fa3c15cefc29ed3f7ad6ac370bd46d8e431d1fa0ba03eb54912e8c5d826e458e"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/b4/7e/c1e1aa7ffb1716db2e9701b9516ec8c4f9a63e7d5cd54b9cced38260f584/ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",hashes = {sha256 = "e9117696191427cd2c5028878b89012e01cee51b2ae8f5dd440a79d6ba4a1011"}}, + {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f8/1d/067de099bb82c7df5a853989bad5773edf89cc1016a23c6abbcbb28139d2/ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4ba827c038348ebde594788b66a4741ce9606b979b684e3bc1e7d1c11d6ac817"}}, ] marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and \"lint\" in dependency_groups" @@ -965,8 +848,8 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "9edcf2127050cd04b1c55f2c5d0ef0c306790635417a4e7c2a0ed6e601c76e78"} +hashes = {sha256 = "f41cee4895442b905a0fa8fe84189c460dff00eec403795e10a6ff2120675686"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] -requires_python = ">=3.9" +requires_python = ">=3.10" diff --git a/pyproject.toml b/pyproject.toml index 1de1d21..8472ac0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,33 +7,29 @@ name = "ldlite" version = "3.2.0" description = "Lightweight analytics tool for FOLIO services" authors = [ - {name = "Katherine Bargar", email = "kbargar@fivecolleges.edu"}, - {name = "Nassib Nassar", email = "nassib@indexdata.com"}, + { name = "Katherine Bargar", email = "kbargar@fivecolleges.edu" }, + { name = "Nassib Nassar", email = "nassib@indexdata.com" }, ] dependencies = [ - # 0.6.1 was the original pinned dependency version - # 1.4 slightly changes data formats and fails tests - "duckdb>=0.6.1,<1.4", - # 2.9.5 was the original pinned dependency version - "psycopg2-binary>=2.9.5", - # 4.64.1 was the original pinned dependency version - "tqdm>=4.64.1", - # 3.0.6 was the original pinned dependency version - "XlsxWriter>=3.0.6", - # 0.2 has query parameter handling, 0.2.3 is a required bug fix version - "httpx-folio>=0.2.3", - # 3.9 introduces orjson.Fragment - "orjson>=3.9", - # 3.2 changes the sql.SQL.format signature - "psycopg>=3.2.0", + # 0.7.0 makes numpy an optional dependency, the minor version fixes a segfault + # 1.4 has a number of regressions so I'm letting it shake out until some fixes + "duckdb>=0.7.1,<1.4", + # 4.64 is the first release with type stubs + "tqdm>=4.64.0", + # 0.2 has query parameter handling, 0.2.3 is a required bug fix version + "httpx-folio>=0.2.3", + # 3.9 introduces orjson.Fragment + "orjson>=3.9", + # 3.2 changes the sql.SQL.format signature + "psycopg>=3.2.0", ] -requires-python = ">=3.9" +requires-python = ">=3.10" readme = "README.md" -license = {text = "Apache-2.0"} +license = { text = "Apache-2.0" } classifiers = [ - "License :: OSI Approved :: Apache Software License", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", ] [project.urls] @@ -42,19 +38,14 @@ Homepage = "https://github.com/library-data-platform/ldlite" [tool.pytest.ini_options] pythonpath = "src" -addopts = [ - "--import-mode=importlib", -] +addopts = ["--import-mode=importlib"] [tool.mypy] -python_version = "3.9" +python_version = "3.10" strict = true -[[tool.mypy.overrides]] -module = ["xlsxwriter.*"] -ignore_missing_imports = true [tool.ruff] -target-version = "py39" +target-version = "py310" [tool.ruff.lint] select = ["ALL"] fixable = ["ALL"] @@ -63,7 +54,7 @@ pydocstyle.convention = "google" [tool.ruff.lint.per-file-ignores] "examples/*" = ["D", "INP001", "T201", "S106", "ERA001", "PERF203"] "tests/*" = ["D", "S", "INP001", "N813", "PLC0415"] -"src/ldlite/{_csv.py,_jsonx.py,_select.py,_xlsx.py}" = ["S608"] +"src/ldlite/{_csv.py,_jsonx.py,_select.py}" = ["S608"] "src/ldlite/__init__.py" = ["T201"] [tool.ruff.lint.flake8-annotations] mypy-init-return = true @@ -71,29 +62,29 @@ mypy-init-return = true [tool.coverage.run] branch = true include = ["src/**"] -omit = ["src/ldlite/_xlsx.py"] [tool.pdm] distribution = true package-dir = "src" [tool.pdm.scripts] -test.composite = ["rm -f .coverage", "python -m coverage run -m pytest -vv {args}", "python -m coverage report"] -lock.composite = ["rm -f pylock.toml pylock.maximal.toml pylock.minimal.toml", "pdm lock --python=3.9", "pdm lock --lockfile pylock.maximal.toml --python=3.13", "pdm lock --strategy direct_minimal_versions --lockfile pylock.minimal.toml --python=3.9"] -test-install.composite = ["pdm sync --lockfile=pylock.minimal.toml", "pdm sync --lockfile=pylock.toml"] - -[dependency-groups] -lint = [ - "mypy==1.17.0", - "ruff==0.12.5", - "pre-commit-hooks==5.0.0", +test.composite = [ + "rm -f .coverage", + "python -m coverage run -m pytest -vv {args}", + "python -m coverage report", ] -test = [ - "pytest>=8.4.1", - "pytest-cases>=3.9.1", - "coverage>=7.9.2", +lock.composite = [ + "rm -f pylock.toml pylock.maximal.toml pylock.minimal.toml", + "pdm lock --python=3.10", + "pdm lock --lockfile pylock.maximal.toml --python=3.13", + "pdm lock --strategy direct_minimal_versions --lockfile pylock.minimal.toml --python=3.10", ] -types = [ - "types-psycopg2>=2.9.21.20", - "types-tqdm>=4.66.0.5", +test-install.composite = [ + "pdm sync --lockfile=pylock.minimal.toml", + "pdm sync --lockfile=pylock.toml", ] + +[dependency-groups] +lint = ["mypy==1.18.2", "ruff==0.13.1", "pre-commit-hooks==6.0.0"] +test = ["pytest>=8.4.2", "pytest-cases>=3.9.1", "coverage>=7.10.7"] +types = ["types-tqdm>=4.64.0"] diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 4f619d7..4d46edf 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -34,16 +34,12 @@ """ -from __future__ import annotations - -import sqlite3 import sys from itertools import count from typing import TYPE_CHECKING, NoReturn, cast import duckdb import psycopg -import psycopg2 from httpx_folio.auth import FolioParams from tqdm import tqdm @@ -59,7 +55,6 @@ autocommit, sqlid, ) -from ._xlsx import to_xlsx if TYPE_CHECKING: from _typeshed import dbapi @@ -140,15 +135,13 @@ def _connect_db_duckdb( return db.cursor() - def connect_db_postgresql(self, dsn: str) -> psycopg2.extensions.connection: + def connect_db_postgresql(self, dsn: str) -> psycopg.Connection: """Connects to a PostgreSQL database for storing data. The data source name is specified by *dsn*. This method returns a connection to the database which can be used to submit SQL queries. The returned connection defaults to autocommit mode. - This will return a psycopg3 connection in the next major release of LDLite. - Example: db = ld.connect_db_postgresql(dsn='dbname=ld host=localhost user=ldlite') @@ -161,43 +154,11 @@ def connect_db_postgresql(self, dsn: str) -> psycopg2.extensions.connection: lambda: cast("dbapi.DBAPIConnection", psycopg.connect(dsn)), ) - ret_db = psycopg2.connect(dsn) + ret_db = psycopg.connect(dsn) ret_db.rollback() - ret_db.set_session(autocommit=True) + ret_db.set_autocommit(True) return ret_db - def experimental_connect_db_sqlite( - self, - filename: str | None = None, - ) -> sqlite3.Connection: - """Deprecated; this will be removed in the next major release of LDLite. - - Connects to an embedded SQLite database for storing data. - - The optional *filename* designates a local file containing the SQLite - database or where the database will be created if it does not exist. - If *filename* is not specified, the database will be stored in memory - and will not be persisted to disk. - - This method returns a connection to the database which can be used to - submit SQL queries. - - Example: - db = ld.connect_db_sqlite(filename='ldlite.db') - - """ - self.dbtype = DBType.SQLITE - fn = filename if filename is not None else "file::memory:?cache=shared" - self.db = sqlite3.connect(fn) - self._db = DBTypeDatabase( - DBType.SQLITE, - lambda: cast("dbapi.DBAPIConnection", sqlite3.connect(fn)), - ) - - db = sqlite3.connect(fn) - autocommit(db, self.dbtype, True) - return self.db - def _check_folio(self) -> None: if self._folio is None: msg = "connection to folio not configured: use connect_folio()" @@ -242,8 +203,6 @@ def drop_tables(self, table: str) -> None: schema_table = table.strip().split(".") if len(schema_table) != 1 and len(schema_table) != 2: raise ValueError("invalid table name: " + table) - if len(schema_table) == 2 and self.dbtype == DBType.SQLITE: - table = schema_table[0] + "_" + schema_table[1] prefix = Prefix(table) self._db.drop_prefix(prefix) @@ -292,10 +251,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 """Submits a query to a FOLIO module, and transforms and stores the result. The retrieved result is stored in *table* within the reporting - database. the *table* name may include a schema name; - however, if the database is SQLite, which does not support - schemas, the schema name will be added to the table name as a - prefix. + database. the *table* name may include a schema name. The *path* parameter is the request path. @@ -348,8 +304,6 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 if self.db is None or self._db is None: self._check_db() return [] - if len(schema_table) == 2 and self.dbtype == DBType.SQLITE: - table = schema_table[0] + "_" + schema_table[1] prefix = Prefix(table) if not self._quiet: print("ldlite: querying: " + path, file=sys.stderr) @@ -367,6 +321,10 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 if self._verbose: print("ldlite: estimated row count: " + str(total), file=sys.stderr) + class PbarNoop: + def update(self, _: int) -> None: ... + def close(self) -> None: ... + p_count = count(1) processed = 0 pbar: tqdm | PbarNoop # type:ignore[type-arg] @@ -381,11 +339,6 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 bar_format="{desc} {bar}{postfix}", ) else: - - class PbarNoop: - def update(self, _: int) -> None: ... - def close(self) -> None: ... - pbar = PbarNoop() def on_processed() -> bool: @@ -547,43 +500,6 @@ def to_csv(self) -> NoReturn: # pragma: nocover msg = "to_csv() is no longer supported: use export_csv()" raise ValueError(msg) - def export_excel( - self, - filename: str, - table: str, - header: bool = True, - ) -> None: # pragma: nocover - """Deprecated; this will be removed in the next major release of LDLite. - - Export a table in the reporting database to an Excel file. - - All rows of *table* are exported to *filename*, or *filename*.xlsx if - *filename* does not have an extension. - - If *header* is True (the default), the worksheet will begin with a row - containing the column names. - - Example: - ld.export_excel(table='g', filename='g') - - """ - if self.db is None: - self._check_db() - return - - autocommit(self.db, self.dbtype, False) - try: - to_xlsx(self.db, self.dbtype, table, filename, header) - if (pgdb := as_postgres(self.db, self.dbtype)) is not None: - pgdb.rollback() - finally: - autocommit(self.db, self.dbtype, True) - - def to_xlsx(self) -> NoReturn: # pragma: nocover - """Deprecated; use export_excel().""" - msg = "to_xlsx() is no longer supported: use export_excel()" - raise ValueError(msg) - def verbose(self, enable: bool) -> None: """Configures verbose output. diff --git a/src/ldlite/_csv.py b/src/ldlite/_csv.py index 73ac88c..4afec9d 100644 --- a/src/ldlite/_csv.py +++ b/src/ldlite/_csv.py @@ -1,9 +1,7 @@ -from __future__ import annotations - from pathlib import Path from typing import TYPE_CHECKING -from ._sqlx import DBType, as_sqlite, server_cursor, sqlid +from ._sqlx import DBType, server_cursor, sqlid if TYPE_CHECKING: from _typeshed import dbapi @@ -19,8 +17,8 @@ def _escape_csv(field: str) -> str: return b -def to_csv( # noqa: PLR0912 - db: dbapi.DBAPIConnection, +def to_csv( + db: "dbapi.DBAPIConnection", dbtype: DBType, table: str, filename: str, @@ -29,25 +27,15 @@ def to_csv( # noqa: PLR0912 # Read attributes attrs: list[tuple[str, dbapi.DBAPITypeCode]] = [("__id", "NUMBER")] - if sql3db := as_sqlite(db, dbtype): - sql3cur = sql3db.cursor() - try: - sql3cur.execute("PRAGMA table_info(" + sqlid(table) + ")") - t_attrs = [(a[1], a[2]) for a in sql3cur.fetchall()[1:]] + cur = server_cursor(db, dbtype) + try: + cur.execute("SELECT * FROM " + sqlid(table) + " LIMIT 1") + cur.fetchall() + if cur.description is not None: + t_attrs = [(a[0], a[1]) for a in cur.description[1:]] attrs.extend(sorted(t_attrs, key=lambda a: a[0])) - finally: - sql3cur.close() - - else: - cur = server_cursor(db, dbtype) - try: - cur.execute("SELECT * FROM " + sqlid(table) + " LIMIT 1") - cur.fetchall() - if cur.description is not None: - t_attrs = [(a[0], a[1]) for a in cur.description[1:]] - attrs.extend(sorted(t_attrs, key=lambda a: a[0])) - finally: - cur.close() + finally: + cur.close() # Write data cur = server_cursor(db, dbtype) diff --git a/src/ldlite/_database.py b/src/ldlite/_database.py index 6f7ad14..258dedc 100644 --- a/src/ldlite/_database.py +++ b/src/ldlite/_database.py @@ -1,14 +1,11 @@ -from __future__ import annotations - from abc import ABC, abstractmethod +from collections.abc import Callable, Iterator, Sequence from contextlib import closing -from typing import TYPE_CHECKING, Any, Callable, Generic, TypeVar, cast +from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast from psycopg import sql if TYPE_CHECKING: - from collections.abc import Iterator, Sequence - from _typeshed import dbapi DB = TypeVar("DB", bound="dbapi.DBAPIConnection") diff --git a/src/ldlite/_folio.py b/src/ldlite/_folio.py index c7f8046..e8d5aed 100644 --- a/src/ldlite/_folio.py +++ b/src/ldlite/_folio.py @@ -1,9 +1,5 @@ -"""Utilities for connecting to FOLIO.""" - -from __future__ import annotations - +from collections.abc import Iterator from itertools import count -from typing import TYPE_CHECKING import orjson from httpx_folio.factories import ( @@ -13,9 +9,6 @@ ) from httpx_folio.query import QueryParams, QueryType -if TYPE_CHECKING: - from collections.abc import Iterator - _SOURCESTATS = { "/source-storage/records": "/source-storage/records", "/source-storage/stream/records": "/source-storage/records", diff --git a/src/ldlite/_jsonx.py b/src/ldlite/_jsonx.py index 4983e94..ed327e8 100644 --- a/src/ldlite/_jsonx.py +++ b/src/ldlite/_jsonx.py @@ -1,7 +1,4 @@ -from __future__ import annotations - import json -import sqlite3 import uuid from typing import TYPE_CHECKING, Literal, Union @@ -227,7 +224,7 @@ def _compile_attrs( # noqa: C901, PLR0912, PLR0913 def _transform_array_data( # noqa: PLR0913 dbtype: DBType, prefix: str, - cur: dbapi.DBAPICursor, + cur: "dbapi.DBAPICursor", parents: list[tuple[int, str]], jarray: list[JsonValue], newattrs: dict[str, dict[str, Attr]], @@ -290,7 +287,7 @@ def _transform_array_data( # noqa: PLR0913 def _compile_data( # noqa: C901, PLR0912, PLR0913 dbtype: DBType, prefix: str, - cur: dbapi.DBAPICursor, + cur: "dbapi.DBAPICursor", parents: list[tuple[int, str]], jdict: Json, newattrs: dict[str, dict[str, Attr]], @@ -364,7 +361,7 @@ def _compile_data( # noqa: C901, PLR0912, PLR0913 def _transform_data( # noqa: PLR0913 dbtype: DBType, prefix: str, - cur: dbapi.DBAPICursor, + cur: "dbapi.DBAPICursor", parents: list[tuple[int, str]], jdict: Json, newattrs: dict[str, dict[str, Attr]], @@ -404,7 +401,7 @@ def _transform_data( # noqa: PLR0913 def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 - db: dbapi.DBAPIConnection, + db: "dbapi.DBAPIConnection", dbtype: DBType, table: str, total: int, @@ -431,7 +428,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 try: cur.execute( "SELECT " - + ",".join([cast_to_varchar(sqlid(a), dbtype) for a in str_attrs]) + + ",".join([cast_to_varchar(sqlid(a)) for a in str_attrs]) + " FROM " + sqlid(table), ) @@ -526,7 +523,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 try: cur.execute( "SELECT " - + ",".join([cast_to_varchar(sqlid(a), dbtype) for a in json_attrs]) + + ",".join([cast_to_varchar(sqlid(a)) for a in json_attrs]) + " FROM " + sqlid(table), ) @@ -578,7 +575,6 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 except ( RuntimeError, psycopg.Error, - sqlite3.OperationalError, duckdb.CatalogException, ) as e: raise RuntimeError("running JSON transform: " + str(e)) from e @@ -606,7 +602,6 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 except ( RuntimeError, psycopg.Error, - sqlite3.OperationalError, duckdb.CatalogException, ) as e: raise RuntimeError("writing table catalog for JSON transform: " + str(e)) from e diff --git a/src/ldlite/_select.py b/src/ldlite/_select.py index 74eda2f..ad7ce5a 100644 --- a/src/ldlite/_select.py +++ b/src/ldlite/_select.py @@ -1,17 +1,14 @@ -from __future__ import annotations - import sys +from collections.abc import Sequence from typing import TYPE_CHECKING, TextIO from ._sqlx import DBType, server_cursor, sqlid if TYPE_CHECKING: - from collections.abc import Sequence - from _typeshed import dbapi -def _format_attr(attr: tuple[str, dbapi.DBAPITypeCode], width: int) -> str: +def _format_attr(attr: tuple[str, "dbapi.DBAPITypeCode"], width: int) -> str: s = "" a = attr[0] len_a = len(a) @@ -36,7 +33,7 @@ def _rstrip_lines(lines: list[str]) -> list[str]: return [s.rstrip() for s in lines] -def _format_value(value: list[str], dtype: dbapi.DBAPITypeCode) -> list[str]: +def _format_value(value: list[str], dtype: "dbapi.DBAPITypeCode") -> list[str]: if len(value) > 1: return value if dtype in {"bool", 16}: @@ -46,7 +43,7 @@ def _format_value(value: list[str], dtype: dbapi.DBAPITypeCode) -> list[str]: def _format_row( row: Sequence[str], - attrs: list[tuple[str, dbapi.DBAPITypeCode]], + attrs: list[tuple[str, "dbapi.DBAPITypeCode"]], width: list[int], ) -> str: s = "" @@ -82,7 +79,7 @@ def _format_row( def select( # noqa: C901, PLR0912, PLR0913, PLR0915 - db: dbapi.DBAPIConnection, + db: "dbapi.DBAPIConnection", dbtype: DBType, table: str, columns: list[str] | None, diff --git a/src/ldlite/_sqlx.py b/src/ldlite/_sqlx.py index 828bb34..b52fce8 100644 --- a/src/ldlite/_sqlx.py +++ b/src/ldlite/_sqlx.py @@ -1,10 +1,8 @@ -from __future__ import annotations - import secrets -import sqlite3 +from collections.abc import Callable, Iterator from contextlib import closing from enum import Enum -from typing import TYPE_CHECKING, Callable, cast +from typing import TYPE_CHECKING, cast import duckdb import psycopg @@ -13,8 +11,6 @@ from ._database import Database if TYPE_CHECKING: - from collections.abc import Iterator - from _typeshed import dbapi from ._database import Prefix @@ -25,11 +21,10 @@ class DBType(Enum): UNDEFINED = 0 DUCKDB = 1 POSTGRES = 2 - SQLITE = 4 class DBTypeDatabase(Database["dbapi.DBAPIConnection"]): - def __init__(self, dbtype: DBType, factory: Callable[[], dbapi.DBAPIConnection]): + def __init__(self, dbtype: DBType, factory: Callable[[], "dbapi.DBAPIConnection"]): self._dbtype = dbtype super().__init__(factory) @@ -37,13 +32,10 @@ def __init__(self, dbtype: DBType, factory: Callable[[], dbapi.DBAPIConnection]) def _missing_table_error(self) -> tuple[type[Exception], ...]: return ( psycopg.errors.UndefinedTable, - sqlite3.OperationalError, duckdb.CatalogException, ) - def _rollback(self, conn: dbapi.DBAPIConnection) -> None: - if sql3db := as_sqlite(conn, self._dbtype): - sql3db.rollback() + def _rollback(self, conn: "dbapi.DBAPIConnection") -> None: if pgdb := as_postgres(conn, self._dbtype): pgdb.rollback() @@ -60,8 +52,6 @@ def _create_raw_table_sql(self) -> sql.SQL: @property def _truncate_raw_table_sql(self) -> sql.SQL: truncate_sql = "TRUNCATE TABLE {table};" - if self._dbtype == DBType.SQLITE: - truncate_sql = "DELETE FROM {table};" return sql.SQL(truncate_sql) @@ -75,7 +65,7 @@ def _insert_record_sql(self) -> sql.SQL: def ingest_records( self, - prefix: Prefix, + prefix: "Prefix", on_processed: Callable[[], bool], records: Iterator[tuple[int, bytes]], ) -> None: @@ -110,7 +100,7 @@ def ingest_records( def as_duckdb( - db: dbapi.DBAPIConnection, + db: "dbapi.DBAPIConnection", dbtype: DBType, ) -> duckdb.DuckDBPyConnection | None: if dbtype != DBType.DUCKDB: @@ -120,7 +110,7 @@ def as_duckdb( def as_postgres( - db: dbapi.DBAPIConnection, + db: "dbapi.DBAPIConnection", dbtype: DBType, ) -> psycopg.Connection | None: if dbtype != DBType.POSTGRES: @@ -129,30 +119,13 @@ def as_postgres( return cast("psycopg.Connection", db) -def as_sqlite( - db: dbapi.DBAPIConnection, - dbtype: DBType, -) -> sqlite3.Connection | None: - if dbtype != DBType.SQLITE: - return None - - return cast("sqlite3.Connection", db) - - -def autocommit(db: dbapi.DBAPIConnection, dbtype: DBType, enable: bool) -> None: +def autocommit(db: "dbapi.DBAPIConnection", dbtype: DBType, enable: bool) -> None: if (pgdb := as_postgres(db, dbtype)) is not None: pgdb.rollback() pgdb.set_autocommit(enable) - if (sql3db := as_sqlite(db, dbtype)) is not None: - sql3db.rollback() - if enable: - sql3db.isolation_level = None - else: - sql3db.isolation_level = "DEFERRED" - -def server_cursor(db: dbapi.DBAPIConnection, dbtype: DBType) -> dbapi.DBAPICursor: +def server_cursor(db: "dbapi.DBAPIConnection", dbtype: DBType) -> "dbapi.DBAPICursor": if (pgdb := as_postgres(db, dbtype)) is not None: return cast( "dbapi.DBAPICursor", @@ -168,14 +141,12 @@ def sqlid(ident: str) -> str: return ".".join(['"' + s + '"' for s in sp]) -def cast_to_varchar(ident: str, dbtype: DBType) -> str: - if dbtype == DBType.SQLITE: - return "CAST(" + ident + " as TEXT)" +def cast_to_varchar(ident: str) -> str: return ident + "::varchar" def varchar_type(dbtype: DBType) -> str: - if dbtype == DBType.POSTGRES or DBType.SQLITE: + if dbtype == DBType.POSTGRES: return "text" return "varchar" @@ -185,7 +156,7 @@ def encode_sql_str(dbtype: DBType, s: str | bytes) -> str: # noqa: C901, PLR091 s = s.decode("utf-8") b = "E'" if dbtype == DBType.POSTGRES else "'" - if dbtype in (DBType.SQLITE, DBType.DUCKDB): + if dbtype == DBType.DUCKDB: for c in s: if c == "'": b += "''" @@ -213,7 +184,7 @@ def encode_sql_str(dbtype: DBType, s: str | bytes) -> str: # noqa: C901, PLR091 return b -def encode_sql(dbtype: DBType, data: JsonValue) -> str: +def encode_sql(dbtype: DBType, data: "JsonValue") -> str: if data is None: return "NULL" if isinstance(data, str): diff --git a/src/ldlite/_xlsx.py b/src/ldlite/_xlsx.py deleted file mode 100644 index a5d0bfc..0000000 --- a/src/ldlite/_xlsx.py +++ /dev/null @@ -1,87 +0,0 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING - -import xlsxwriter - -from ._sqlx import DBType, server_cursor, sqlid - -if TYPE_CHECKING: - from _typeshed import dbapi - - -def to_xlsx( # noqa: C901, PLR0912, PLR0915 - db: dbapi.DBAPIConnection, - dbtype: DBType, - table: str, - filename: str, - header: bool, -) -> None: - # Read attributes - attrs: list[tuple[str, dbapi.DBAPITypeCode]] = [] - width: list[int] = [] - cur = db.cursor() - try: - cur.execute("SELECT * FROM " + sqlid(table) + " LIMIT 1") - if cur.description is not None: - for a in cur.description: - attrs.append((a[0], a[1])) - width.append(len(a[0])) - finally: - cur.close() - cols = ",".join([sqlid(a[0]) for a in attrs]) - query = ( - "SELECT " - + cols - + " FROM " - + sqlid(table) - + " ORDER BY " - + ",".join([str(i + 1) for i in range(len(attrs))]) - ) - # Scan - cur = server_cursor(db, dbtype) - try: - cur.execute(query) - while True: - row = cur.fetchone() - if row is None: - break - for i, data in enumerate(row): - lines = [""] - if data is not None: - lines = str(data).splitlines() - for _, ln in enumerate(lines): - width[i] = max(width[i], len(ln)) - finally: - cur.close() - # Write data - cur = server_cursor(db, dbtype) - try: - cur.execute(query) - fn = filename if "." in filename else filename + ".xlsx" - workbook = xlsxwriter.Workbook(fn, {"constant_memory": True}) - try: - worksheet = workbook.add_worksheet() - for i, w in enumerate(width): - worksheet.set_column(i, i, w + 2) - if header: - worksheet.freeze_panes(1, 0) - for i, attr in enumerate(attrs): - fmt = workbook.add_format() - fmt.set_bold() - fmt.set_align("center") - worksheet.write(0, i, attr[0], fmt) - row_i = 1 if header else 0 - datafmt = workbook.add_format() - datafmt.set_align("top") - while True: - row = cur.fetchone() - if row is None: - break - for i, data in enumerate(row): - worksheet.write(row_i, i, data, datafmt) - row_i += 1 - finally: - workbook.close() - finally: - cur.close() diff --git a/tests/README.md b/tests/README.md index 79104fe..85b5758 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,6 @@ # Test Setup -Sqlite and Duckdb tests "just work". +Duckdb tests "just work". Postgres tests will be skipped unless you set them up first. The postgres tests expect a database with user/password ldlite/ldlite. diff --git a/tests/test_cases/query_cases.py b/tests/test_cases/query_cases.py index 408b429..9e3725e 100644 --- a/tests/test_cases/query_cases.py +++ b/tests/test_cases/query_cases.py @@ -1,5 +1,3 @@ -from __future__ import annotations - import json from dataclasses import dataclass from typing import Any @@ -180,12 +178,14 @@ def case_table_underexpansion(self) -> QueryCase: ], expected_values={ "prefix__t__sub_objects": ( - ["*"], + [ + "id", + "sub_objects__id", + "sub_objects__value", + ], [ ( - 1, "b096504a-3d54-4664-9bf5-1b872466fd66", - 1, "2b94c631-fca9-4892-a730-03ee529ffe2a", "sub-value", ), @@ -488,15 +488,15 @@ def case_id_generation(self) -> QueryCase: ["__id", "id", "sub_objects__o", "sub_objects__id"], [ ( - 1, + "1", "b096504a-3d54-4664-9bf5-1b872466fd66", - 1, + "1", "2b94c631-fca9-4892-a730-03ee529ffe2a", ), ( - 2, + "2", "b096504a-3d54-4664-9bf5-1b872466fd66", - 2, + "2", "b5d8cdc4-9441-487c-90cf-0c7ec97728eb", ), ], @@ -504,10 +504,10 @@ def case_id_generation(self) -> QueryCase: "prefix__t__sub_objects__sub_sub_objects": ( ["__id", "sub_objects__o", "sub_objects__sub_sub_objects__o"], [ - (1, 1, 1), - (2, 1, 2), - (3, 2, 1), - (4, 2, 2), + ("1", "1", "1"), + ("2", "1", "2"), + ("3", "2", "1"), + ("4", "2", "2"), ], ), }, diff --git a/tests/test_duckdb.py b/tests/test_duckdb.py index ee511a4..5054878 100644 --- a/tests/test_duckdb.py +++ b/tests/test_duckdb.py @@ -67,7 +67,7 @@ def test_query( for table, (cols, values) in tc.expected_values.items(): with duckdb.connect(dsn) as res: - res.execute(f"SELECT {','.join(cols)} FROM {table};") + res.execute(f"SELECT {'::text,'.join(cols)}::text FROM {table};") for v in values: assert res.fetchone() == v diff --git a/tests/test_postgres.py b/tests/test_postgres.py index a08b465..e6d79e9 100644 --- a/tests/test_postgres.py +++ b/tests/test_postgres.py @@ -1,23 +1,20 @@ -from __future__ import annotations - import contextlib +from collections.abc import Callable from difflib import unified_diff from pathlib import Path -from typing import TYPE_CHECKING, Callable, cast +from typing import cast from unittest import mock from unittest.mock import MagicMock -import psycopg2 +import psycopg import pytest +from psycopg import sql from pytest_cases import parametrize_with_cases from tests.test_cases import drop_tables_cases as dtc from tests.test_cases import query_cases as qc from tests.test_cases import to_csv_cases as csvc -if TYPE_CHECKING: - from unittest.mock import MagicMock - @pytest.fixture(scope="session") def pg_dsn(pytestconfig: pytest.Config) -> None | Callable[[str], str]: @@ -27,10 +24,12 @@ def pg_dsn(pytestconfig: pytest.Config) -> None | Callable[[str], str]: def setup(db: str) -> str: base_dsn = f"host={host} user=ldlite password=ldlite" - with contextlib.closing(psycopg2.connect(base_dsn)) as base_conn: + with contextlib.closing(psycopg.connect(base_dsn)) as base_conn: base_conn.autocommit = True with base_conn.cursor() as curr: - curr.execute(f"CREATE DATABASE {db};") + curr.execute( + sql.SQL("CREATE DATABASE {db};").format(db=sql.Identifier(db)), + ) return base_dsn + f" dbname={db}" @@ -61,7 +60,7 @@ def test_drop_tables( ld.query(table=prefix, path="/patched", keep_raw=tc.keep_raw) ld.drop_tables(tc.drop) - with psycopg2.connect(dsn) as conn, conn.cursor() as res: + with psycopg.connect(dsn) as conn, conn.cursor() as res: res.execute( """ SELECT table_name @@ -100,7 +99,7 @@ def test_query( keep_raw=tc.keep_raw, ) - with psycopg2.connect(dsn) as conn: + with psycopg.connect(dsn) as conn: with conn.cursor() as res: res.execute( """ @@ -113,7 +112,14 @@ def test_query( for table, (cols, values) in tc.expected_values.items(): with conn.cursor() as res: - res.execute(f"SELECT {','.join(cols)} FROM {table};") + res.execute( + sql.SQL("SELECT {cols}::text FROM {table};").format( + cols=sql.SQL("::text, ").join( + [sql.Identifier(c) for c in cols], + ), + table=sql.Identifier(table), + ), + ) for v in values: assert res.fetchone() == v @@ -127,10 +133,11 @@ def test_query( assert cast("tuple[int]", res.fetchone())[0] == len(tc.expected_indexes) for t, c in tc.expected_indexes: + # this requires specific formatting to match the postgres strings res.execute(f""" SELECT COUNT(*) FROM pg_indexes WHERE indexdef LIKE 'CREATE INDEX % ON public.{t} USING btree ({c})'; -""") + """) assert cast("tuple[int]", res.fetchone())[0] == 1, f"{t}, {c}" diff --git a/tests/test_sqlite.py b/tests/test_sqlite.py deleted file mode 100644 index e65115a..0000000 --- a/tests/test_sqlite.py +++ /dev/null @@ -1,111 +0,0 @@ -import contextlib -import sqlite3 -from difflib import unified_diff -from pathlib import Path -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from pytest_cases import parametrize_with_cases - -from tests.test_cases import drop_tables_cases as dtc -from tests.test_cases import query_cases as qc -from tests.test_cases import to_csv_cases as csvc - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=dtc.DropTablesCases) -def test_drop_tables( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: dtc.DropTablesCase, -) -> None: - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = f"file:{tc.db}?mode=memory&cache=shared" - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.experimental_connect_db_sqlite(dsn) - - for prefix in tc.values: - ld.query(table=prefix, path="/patched", keep_raw=tc.keep_raw) - ld.drop_tables(tc.drop) - - with sqlite3.connect(dsn) as conn, contextlib.closing(conn.cursor()) as res: - res.execute("SELECT name FROM sqlite_master WHERE type='table';") - assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=qc.QueryTestCases) -def test_query( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: qc.QueryCase, -) -> None: - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = f"file:{tc.db}?mode=memory&cache=shared" - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.experimental_connect_db_sqlite(dsn) - - for prefix in tc.values: - ld.query( - table=prefix, - path="/patched", - json_depth=tc.json_depth, - keep_raw=tc.keep_raw, - ) - - with sqlite3.connect(dsn) as conn: - with contextlib.closing(conn.cursor()) as res: - res.execute("SELECT name FROM sqlite_master WHERE type='table';") - assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) - - for table, (cols, values) in tc.expected_values.items(): - with contextlib.closing(conn.cursor()) as res: - res.execute(f"SELECT {','.join(cols)} FROM {table};") - for v in values: - assert res.fetchone() == v - - assert res.fetchone() is None - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=csvc.ToCsvCases) -def test_to_csv( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: csvc.ToCsvCase, - tmpdir: str, -) -> None: - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = f"file:{tc.db}?mode=memory&cache=shared" - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.experimental_connect_db_sqlite(dsn) - - for prefix in tc.values: - ld.query(table=prefix, path="/patched") - - for table, expected in tc.expected_csvs: - actual = (Path(tmpdir) / table).with_suffix(".csv") - - ld.export_csv(str(actual), table) - - with expected.open("r") as f: - expected_lines = f.readlines() - with actual.open("r") as f: - actual_lines = f.readlines() - - diff = list(unified_diff(expected_lines, actual_lines)) - if len(diff) > 0: - pytest.fail("".join(diff)) From 6f0fbc0cf6655901374dfac136a3761c16ca5d6c Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Tue, 23 Sep 2025 08:57:46 -0400 Subject: [PATCH 02/25] Refactor DBTypeDatabase into duckdb and postgres (#47) In order to make fewer changes for the COPY FROM feature I created a single implementation of Database that utilized DBType. Now that sqlite support is gone I've created two implementations for duckdb and postgres. I wanted to use the dbapi types but duckdb doesn't quite play nicely with them. Doing this refactor makes the next few features easier to implement. I was never happy with the iteration of records and ingestion of records. This moves the __id generation into the database logic away from the iteration logic. I also cleaned up the magic "first record is the total" behavior. As part of this I changed how tqdm was initialized to be closer to how I think it is intended to be used. --- src/ldlite/__init__.py | 97 +++++------ .../{_database.py => _database/__init__.py} | 60 ++++--- src/ldlite/_database/duckdb.py | 44 +++++ src/ldlite/_database/postgres.py | 51 ++++++ src/ldlite/_folio.py | 153 +++++++++++------- src/ldlite/_sqlx.py | 82 ---------- 6 files changed, 258 insertions(+), 229 deletions(-) rename src/ldlite/{_database.py => _database/__init__.py} (82%) create mode 100644 src/ldlite/_database/duckdb.py create mode 100644 src/ldlite/_database/postgres.py diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 4d46edf..9b5bbbd 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -35,7 +35,6 @@ """ import sys -from itertools import count from typing import TYPE_CHECKING, NoReturn, cast import duckdb @@ -44,19 +43,20 @@ from tqdm import tqdm from ._csv import to_csv -from ._database import Prefix +from ._database import Database, Prefix from ._folio import FolioClient from ._jsonx import Attr, transform_json from ._select import select from ._sqlx import ( DBType, - DBTypeDatabase, as_postgres, autocommit, sqlid, ) if TYPE_CHECKING: + from collections.abc import Iterator + from _typeshed import dbapi from httpx_folio.query import QueryType @@ -77,7 +77,7 @@ def __init__(self) -> None: self._quiet = False self.dbtype: DBType = DBType.UNDEFINED self.db: dbapi.DBAPIConnection | None = None - self._db: DBTypeDatabase | None = None + self._db: Database | None = None self._folio: FolioClient | None = None self.page_size = 1000 self._okapi_timeout = 60 @@ -124,14 +124,13 @@ def _connect_db_duckdb( db = ld.connect_db_duckdb(filename='ldlite.db') """ + from ._database.duckdb import DuckDbDatabase # noqa: PLC0415 + self.dbtype = DBType.DUCKDB fn = filename if filename is not None else ":memory:" db = duckdb.connect(database=fn) self.db = cast("dbapi.DBAPIConnection", db.cursor()) - self._db = DBTypeDatabase( - DBType.DUCKDB, - lambda: cast("dbapi.DBAPIConnection", db.cursor()), - ) + self._db = DuckDbDatabase(lambda: db.cursor()) return db.cursor() @@ -146,13 +145,12 @@ def connect_db_postgresql(self, dsn: str) -> psycopg.Connection: db = ld.connect_db_postgresql(dsn='dbname=ld host=localhost user=ldlite') """ + from ._database.postgres import PostgresDatabase # noqa: PLC0415 + self.dbtype = DBType.POSTGRES db = psycopg.connect(dsn) self.db = cast("dbapi.DBAPIConnection", db) - self._db = DBTypeDatabase( - DBType.POSTGRES, - lambda: cast("dbapi.DBAPIConnection", psycopg.connect(dsn)), - ) + self._db = PostgresDatabase(lambda: psycopg.connect(dsn)) ret_db = psycopg.connect(dsn) ret_db.rollback() @@ -200,9 +198,6 @@ def drop_tables(self, table: str) -> None: if self.db is None or self._db is None: self._check_db() return - schema_table = table.strip().split(".") - if len(schema_table) != 1 and len(schema_table) != 2: - raise ValueError("invalid table name: " + table) prefix = Prefix(table) self._db.drop_prefix(prefix) @@ -293,9 +288,6 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 "use json_depth=0 to disable JSON transformation" ) raise ValueError(msg) - schema_table = table.split(".") - if len(schema_table) != 1 and len(schema_table) != 2: - raise ValueError("invalid table name: " + table) if json_depth is None or json_depth < 0 or json_depth > 4: raise ValueError("invalid value for json_depth: " + str(json_depth)) if self._folio is None: @@ -308,57 +300,39 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 if not self._quiet: print("ldlite: querying: " + path, file=sys.stderr) try: - # First get total number of records - records = self._folio.iterate_records( + (total_records, records) = self._folio.iterate_records( path, self._okapi_timeout, self._okapi_max_retries, self.page_size, query=cast("QueryType", query), ) - (total_records, _) = next(records) - total = min(total_records, limit or total_records) + if limit is not None: + total_records = min(total_records, limit) + records = (x for _, x in zip(range(limit), records, strict=False)) if self._verbose: - print("ldlite: estimated row count: " + str(total), file=sys.stderr) - - class PbarNoop: - def update(self, _: int) -> None: ... - def close(self) -> None: ... - - p_count = count(1) - processed = 0 - pbar: tqdm | PbarNoop # type:ignore[type-arg] - if not self._quiet: - pbar = tqdm( - desc="reading", - total=total, - leave=False, - mininterval=3, - smoothing=0, - colour="#A9A9A9", - bar_format="{desc} {bar}{postfix}", + print( + "ldlite: estimated row count: " + str(total_records), + file=sys.stderr, ) - else: - pbar = PbarNoop() - - def on_processed() -> bool: - pbar.update(1) - nonlocal processed - processed = next(p_count) - return True - def on_processed_limit() -> bool: - pbar.update(1) - nonlocal processed, limit - processed = next(p_count) - return limit is None or processed < limit - - self._db.ingest_records( + processed = self._db.ingest_records( prefix, - on_processed_limit if limit is not None else on_processed, - records, + cast( + "Iterator[bytes]", + tqdm( + records, + desc="downloading", + total=total_records, + leave=False, + mininterval=5, + disable=self._quiet, + unit=table.split(".")[-1], + unit_scale=True, + delay=5, + ), + ), ) - pbar.close() self._db.drop_extracted_tables(prefix) newtables = [table] @@ -386,6 +360,13 @@ def on_processed_limit() -> bool: autocommit(self.db, self.dbtype, True) # Create indexes on id columns (for postgres) if self.dbtype == DBType.POSTGRES: + + class PbarNoop: + def update(self, _: int) -> None: ... + def close(self) -> None: ... + + pbar: tqdm | PbarNoop = PbarNoop() # type:ignore[type-arg] + indexable_attrs = [ (t, a) for t, attrs in newattrs.items() diff --git a/src/ldlite/_database.py b/src/ldlite/_database/__init__.py similarity index 82% rename from src/ldlite/_database.py rename to src/ldlite/_database/__init__.py index 258dedc..c0f3ebe 100644 --- a/src/ldlite/_database.py +++ b/src/ldlite/_database/__init__.py @@ -6,15 +6,18 @@ from psycopg import sql if TYPE_CHECKING: - from _typeshed import dbapi - -DB = TypeVar("DB", bound="dbapi.DBAPIConnection") + import duckdb + import psycopg class Prefix: - def __init__(self, table: str): + def __init__(self, prefix: str): self._schema: str | None = None - sandt = table.split(".") + sandt = prefix.split(".") + if len(sandt) > 2: + msg = f"Expected one or two identifiers but got {prefix}" + raise ValueError(msg) + if len(sandt) == 1: (self._prefix,) = sandt else: @@ -42,7 +45,24 @@ def legacy_jtable(self) -> sql.Identifier: return self.identifier(f"{self._prefix}_jtable") -class Database(ABC, Generic[DB]): +class Database(ABC): + @abstractmethod + def drop_prefix(self, prefix: Prefix) -> None: ... + + @abstractmethod + def drop_raw_table(self, prefix: Prefix) -> None: ... + + @abstractmethod + def drop_extracted_tables(self, prefix: Prefix) -> None: ... + + @abstractmethod + def ingest_records(self, prefix: Prefix, records: Iterator[bytes]) -> int: ... + + +DB = TypeVar("DB", bound="duckdb.DuckDBPyConnection | psycopg.Connection") + + +class TypedDatabase(Database, Generic[DB]): def __init__(self, conn_factory: Callable[[], DB]): self._conn_factory = conn_factory @@ -88,7 +108,7 @@ def drop_extracted_tables( @property @abstractmethod - def _missing_table_error(self) -> tuple[type[Exception], ...]: ... + def _missing_table_error(self) -> type[Exception]: ... def _drop_extracted_tables( self, conn: DB, @@ -137,9 +157,6 @@ def _drop_extracted_tables( .as_string(), ) - @property - @abstractmethod - def _truncate_raw_table_sql(self) -> sql.SQL: ... @property @abstractmethod def _create_raw_table_sql(self) -> sql.SQL: ... @@ -162,26 +179,3 @@ def _prepare_raw_table( table=prefix.raw_table_name, ).as_string(), ) - - @property - @abstractmethod - def _insert_record_sql(self) -> sql.SQL: ... - def ingest_records( - self, - prefix: Prefix, - on_processed: Callable[[], bool], - records: Iterator[tuple[int, bytes]], - ) -> None: - with closing(self._conn_factory()) as conn: - self._prepare_raw_table(conn, prefix) - - insert_sql = self._insert_record_sql.format( - table=prefix.raw_table_name, - ).as_string() - with closing(conn.cursor()) as cur: - for pkey, r in records: - cur.execute(insert_sql, (pkey, r.decode())) - if not on_processed(): - break - - conn.commit() diff --git a/src/ldlite/_database/duckdb.py b/src/ldlite/_database/duckdb.py new file mode 100644 index 0000000..ebe5806 --- /dev/null +++ b/src/ldlite/_database/duckdb.py @@ -0,0 +1,44 @@ +from collections.abc import Iterator +from itertools import count + +import duckdb +from psycopg import sql + +from . import Prefix, TypedDatabase + + +class DuckDbDatabase(TypedDatabase[duckdb.DuckDBPyConnection]): + def _rollback(self, conn: duckdb.DuckDBPyConnection) -> None: + pass + + @property + def _missing_table_error(self) -> type[Exception]: + return duckdb.CatalogException + + @property + def _create_raw_table_sql(self) -> sql.SQL: + return sql.SQL("CREATE TABLE IF NOT EXISTS {table} (__id integer, jsonb text);") + + def ingest_records( + self, + prefix: Prefix, + records: Iterator[bytes], + ) -> int: + pkey = count(1) + with self._conn_factory() as conn: + self._prepare_raw_table(conn, prefix) + + insert_sql = ( + sql.SQL("INSERT INTO {table} VALUES(?, ?);") + .format( + table=prefix.raw_table_name, + ) + .as_string() + ) + # duckdb has better performance bulk inserting in a transaction + with conn.begin() as tx, tx.cursor() as cur: + for r in records: + cur.execute(insert_sql, (next(pkey), r.decode())) + tx.commit() + + return next(pkey) - 1 diff --git a/src/ldlite/_database/postgres.py b/src/ldlite/_database/postgres.py new file mode 100644 index 0000000..8008d22 --- /dev/null +++ b/src/ldlite/_database/postgres.py @@ -0,0 +1,51 @@ +from collections.abc import Iterator +from itertools import count + +import psycopg +from psycopg import sql + +from . import Prefix, TypedDatabase + + +class PostgresDatabase(TypedDatabase[psycopg.Connection]): + def _rollback(self, conn: psycopg.Connection) -> None: + conn.rollback() + + @property + def _missing_table_error(self) -> type[Exception]: + return psycopg.errors.UndefinedTable + + @property + def _create_raw_table_sql(self) -> sql.SQL: + return sql.SQL( + "CREATE TABLE IF NOT EXISTS {table} (__id integer, jsonb jsonb);", + ) + + def ingest_records( + self, + prefix: Prefix, + records: Iterator[bytes], + ) -> int: + pkey = count(1) + with self._conn_factory() as conn: + self._prepare_raw_table(conn, prefix) + + with ( + conn.cursor() as cur, + cur.copy( + sql.SQL( + "COPY {table} (__id, jsonb) FROM STDIN (FORMAT BINARY)", + ).format(table=prefix.raw_table_name), + ) as copy, + ): + # postgres jsonb is always version 1 + # and it always goes in front + jver = (1).to_bytes(1, "big") + for r in records: + rb = bytearray() + rb.extend(jver) + rb.extend(r) + copy.write_row((next(pkey).to_bytes(4, "big"), rb)) + + conn.commit() + return next(pkey) - 1 diff --git a/src/ldlite/_folio.py b/src/ldlite/_folio.py index e8d5aed..1fa87fa 100644 --- a/src/ldlite/_folio.py +++ b/src/ldlite/_folio.py @@ -1,5 +1,6 @@ from collections.abc import Iterator from itertools import count +from typing import cast import orjson from httpx_folio.factories import ( @@ -36,23 +37,13 @@ def iterate_records( retries: int, page_size: int, query: QueryType | None = None, - ) -> Iterator[tuple[int, bytes]]: - """Iterates all records for a given path. - - Returns: - A tuple of the autoincrementing key + the json for each record. - The first result will be the total record count. - """ + ) -> tuple[int, Iterator[bytes]]: is_srs = path.lower() in _SOURCESTATS # this is Java's max size of int because we want all the source records params = QueryParams(query, 2_147_483_647 - 1 if is_srs else page_size) - with self._client_factory( - BasicClientOptions( - retries=retries, - timeout=timeout, - ), - ) as client: + client_opts = BasicClientOptions(retries=retries, timeout=timeout) + with self._client_factory(client_opts) as client: res = client.get( path if not is_srs else _SOURCESTATS[path.lower()], params=params.stats(), @@ -60,60 +51,110 @@ def iterate_records( res.raise_for_status() j = orjson.loads(res.text) r = int(j["totalRecords"]) - yield (r, b"") - - if r == 0: - return - - pkey = count(start=1) - if is_srs: - # streaming is a more stable endpoint for source records - with client.stream( - "GET", - _SOURCESTREAM[path.lower()], - params=params.normalized(), - ) as res: - res.raise_for_status() - record = "" - for f in res.iter_lines(): - # HTTPX can return partial json fragments during iteration - # if they contain "newline-ish" characters like U+2028 - record += f - if len(f) == 0 or f[-1] != "}": - continue - yield (next(pkey), orjson.dumps(orjson.Fragment(record))) - record = "" - return - key = next(iter(j.keys())) - nonid_key = ( - # Grab the first key if there isn't an id column - # because we need it to offset page properly - next(iter(j[key][0].keys())) if "id" not in j[key][0] else None + if r == 0: + return (0, iter([])) + + if is_srs: + return (r, self._iterate_records_srs(client_opts, path, params)) + + key = cast("str", next(iter(j.keys()))) + r1 = j[key][0] + if ( + nonid_key := cast("str", next(iter(r1.keys()))) if "id" not in r1 else None + ) or not params.can_page_by_id(): + return ( + r, + self._iterate_records_offset( + client_opts, + path, + params, + key, + nonid_key, + ), ) - last_id: str | None = None + return ( + r, + self._iterate_records_id( + client_opts, + path, + params, + key, + ), + ) + + def _iterate_records_srs( + self, + client_opts: BasicClientOptions, + path: str, + params: QueryParams, + ) -> Iterator[bytes]: + with ( + self._client_factory(client_opts) as client, + client.stream( + "GET", + _SOURCESTREAM[path.lower()], + params=params.normalized(), + ) as res, + ): + res.raise_for_status() + record = "" + for f in res.iter_lines(): + # HTTPX can return partial json fragments during iteration + # if they contain "newline-ish" characters like U+2028 + record += f + if len(f) == 0 or f[-1] != "}": + continue + yield orjson.dumps(orjson.Fragment(record)) + record = "" + + def _iterate_records_offset( + self, + client_opts: BasicClientOptions, + path: str, + params: QueryParams, + key: str, + nonid_key: str | None, + ) -> Iterator[bytes]: + with self._client_factory(client_opts) as client: page = count(start=1) while True: - if nonid_key is not None: - p = params.offset_paging(key=nonid_key, page=next(page)) - elif params.can_page_by_id(): - p = params.id_paging(last_id=last_id) - else: - p = params.offset_paging(page=next(page)) - - res = client.get(path, params=p) + res = client.get( + path, + params=params.offset_paging(page=next(page)) + if nonid_key is None + else params.offset_paging(key=nonid_key, page=next(page)), + ) res.raise_for_status() last = None for r in (o for o in orjson.loads(res.text)[key] if o is not None): last = r - yield (next(pkey), orjson.dumps(r)) + yield orjson.dumps(r) if last is None: return - last_id = last.get( - "id", - "this value is unused because we're offset paging", - ) + def _iterate_records_id( + self, + client_opts: BasicClientOptions, + path: str, + params: QueryParams, + key: str, + ) -> Iterator[bytes]: + with self._client_factory(client_opts) as client: + last_id: str | None = None + while True: + res = client.get(path, params=params.id_paging(last_id=last_id)) + res.raise_for_status() + + last = None + for r in (o for o in orjson.loads(res.text)[key] if o is not None): + last = r + yield orjson.dumps(r) + + if last is None: + return + + last_id = last["id"] diff --git a/src/ldlite/_sqlx.py b/src/ldlite/_sqlx.py index b52fce8..cf2e749 100644 --- a/src/ldlite/_sqlx.py +++ b/src/ldlite/_sqlx.py @@ -1,19 +1,13 @@ import secrets -from collections.abc import Callable, Iterator -from contextlib import closing from enum import Enum from typing import TYPE_CHECKING, cast import duckdb import psycopg -from psycopg import sql - -from ._database import Database if TYPE_CHECKING: from _typeshed import dbapi - from ._database import Prefix from ._jsonx import JsonValue @@ -23,82 +17,6 @@ class DBType(Enum): POSTGRES = 2 -class DBTypeDatabase(Database["dbapi.DBAPIConnection"]): - def __init__(self, dbtype: DBType, factory: Callable[[], "dbapi.DBAPIConnection"]): - self._dbtype = dbtype - super().__init__(factory) - - @property - def _missing_table_error(self) -> tuple[type[Exception], ...]: - return ( - psycopg.errors.UndefinedTable, - duckdb.CatalogException, - ) - - def _rollback(self, conn: "dbapi.DBAPIConnection") -> None: - if pgdb := as_postgres(conn, self._dbtype): - pgdb.rollback() - - @property - def _create_raw_table_sql(self) -> sql.SQL: - create_sql = "CREATE TABLE IF NOT EXISTS {table} (__id integer, jsonb text);" - if self._dbtype == DBType.POSTGRES: - create_sql = ( - "CREATE TABLE IF NOT EXISTS {table} (__id integer, jsonb jsonb);" - ) - - return sql.SQL(create_sql) - - @property - def _truncate_raw_table_sql(self) -> sql.SQL: - truncate_sql = "TRUNCATE TABLE {table};" - - return sql.SQL(truncate_sql) - - @property - def _insert_record_sql(self) -> sql.SQL: - insert_sql = "INSERT INTO {table} VALUES(?, ?);" - if self._dbtype == DBType.POSTGRES: - insert_sql = "INSERT INTO {table} VALUES(%s, %s);" - - return sql.SQL(insert_sql) - - def ingest_records( - self, - prefix: "Prefix", - on_processed: Callable[[], bool], - records: Iterator[tuple[int, bytes]], - ) -> None: - if self._dbtype != DBType.POSTGRES: - super().ingest_records(prefix, on_processed, records) - return - - with closing(self._conn_factory()) as conn: - self._prepare_raw_table(conn, prefix) - - if pgconn := as_postgres(conn, self._dbtype): - with ( - pgconn.cursor() as cur, - cur.copy( - sql.SQL( - "COPY {table} (__id, jsonb) FROM STDIN (FORMAT BINARY)", - ).format(table=prefix.raw_table_name), - ) as copy, - ): - # postgres jsonb is always version 1 - # and it always goes in front - jver = (1).to_bytes(1, "big") - for pkey, r in records: - rb = bytearray() - rb.extend(jver) - rb.extend(r) - copy.write_row((pkey.to_bytes(4, "big"), rb)) - if not on_processed(): - break - - pgconn.commit() - - def as_duckdb( db: "dbapi.DBAPIConnection", dbtype: DBType, From e4a66f7e32bc0830abd09cbda92f446ff3a1b723 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Tue, 23 Sep 2025 13:09:59 -0400 Subject: [PATCH 03/25] Add a system schema and load history table (#48) In order to do the transformations more efficiently I'll need to create some custom functions. I've created a system schema for them to live in. Now that there's a place to put stuff I've also introduced a table recording load history for each table which will allow users and administrators to have a better understanding of how LDLite is running. The test case setup is getting pretty gnarly and should maybe be reworked at some point. It would also be nice to have the End to End tests be run against postgres and duckdb. --- src/ldlite/__init__.py | 24 +++++++-- src/ldlite/_database/__init__.py | 75 ++++++++++++++++++++++++-- src/ldlite/_database/postgres.py | 5 ++ src/ldlite/_jsonx.py | 10 ++-- tests/test_cases/base.py | 31 ++++++----- tests/test_cases/load_history_cases.py | 74 +++++++++++++++++++++++++ tests/test_duckdb.py | 72 ++++++++++++++++++++++++- tests/test_postgres.py | 61 ++++++++++++++++++++- 8 files changed, 326 insertions(+), 26 deletions(-) create mode 100644 tests/test_cases/load_history_cases.py diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 9b5bbbd..3e3c4e1 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -35,6 +35,7 @@ """ import sys +from datetime import datetime, timezone from typing import TYPE_CHECKING, NoReturn, cast import duckdb @@ -43,7 +44,7 @@ from tqdm import tqdm from ._csv import to_csv -from ._database import Database, Prefix +from ._database import Database, LoadHistory, Prefix from ._folio import FolioClient from ._jsonx import Attr, transform_json from ._select import select @@ -150,7 +151,7 @@ def connect_db_postgresql(self, dsn: str) -> psycopg.Connection: self.dbtype = DBType.POSTGRES db = psycopg.connect(dsn) self.db = cast("dbapi.DBAPIConnection", db) - self._db = PostgresDatabase(lambda: psycopg.connect(dsn)) + self._db = PostgresDatabase(dsn) ret_db = psycopg.connect(dsn) ret_db.rollback() @@ -296,6 +297,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 if self.db is None or self._db is None: self._check_db() return [] + start = datetime.now(timezone.utc) prefix = Prefix(table) if not self._quiet: print("ldlite: querying: " + path, file=sys.stderr) @@ -333,13 +335,15 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 ), ), ) + download = datetime.now(timezone.utc) + scan = datetime.now(timezone.utc) self._db.drop_extracted_tables(prefix) newtables = [table] newattrs = {} if json_depth > 0: autocommit(self.db, self.dbtype, False) - jsontables, jsonattrs = transform_json( + (jsontables, jsonattrs, scan) = transform_json( self.db, self.dbtype, table, @@ -357,6 +361,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 self._db.drop_raw_table(prefix) finally: + transformed = datetime.now(timezone.utc) autocommit(self.db, self.dbtype, True) # Create indexes on id columns (for postgres) if self.dbtype == DBType.POSTGRES: @@ -398,6 +403,19 @@ def close(self) -> None: ... cur.close() pbar.update(1) pbar.close() + index = datetime.now(timezone.utc) + self._db.record_history( + LoadHistory( + prefix, + query if query and isinstance(query, str) else None, + start, + download, + scan, + transformed, + index, + processed, + ), + ) # Return table names if not self._quiet: print("ldlite: created tables: " + ", ".join(newtables), file=sys.stderr) diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py index c0f3ebe..5229176 100644 --- a/src/ldlite/_database/__init__.py +++ b/src/ldlite/_database/__init__.py @@ -1,6 +1,9 @@ +import datetime from abc import ABC, abstractmethod from collections.abc import Callable, Iterator, Sequence from contextlib import closing +from dataclasses import dataclass +from datetime import timezone from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast from psycopg import sql @@ -27,22 +30,38 @@ def __init__(self, prefix: str): def schema_name(self) -> sql.Identifier | None: return None if self._schema is None else sql.Identifier(self._schema) - def identifier(self, table: str) -> sql.Identifier: + def _identifier(self, table: str) -> sql.Identifier: if self._schema is None: return sql.Identifier(table) return sql.Identifier(self._schema, table) + @property + def load_history_key(self) -> str: + return (self._schema or "public") + "." + self._prefix + @property def raw_table_name(self) -> sql.Identifier: - return self.identifier(self._prefix) + return self._identifier(self._prefix) @property def catalog_table_name(self) -> sql.Identifier: - return self.identifier(f"{self._prefix}__tcatalog") + return self._identifier(f"{self._prefix}__tcatalog") @property def legacy_jtable(self) -> sql.Identifier: - return self.identifier(f"{self._prefix}_jtable") + return self._identifier(f"{self._prefix}_jtable") + + +@dataclass(frozen=True) +class LoadHistory: + table_name: Prefix + query: str | None + start: datetime.datetime + download: datetime.datetime + scan: datetime.datetime + transform: datetime.datetime + index: datetime.datetime + total: int class Database(ABC): @@ -58,6 +77,9 @@ def drop_extracted_tables(self, prefix: Prefix) -> None: ... @abstractmethod def ingest_records(self, prefix: Prefix, records: Iterator[bytes]) -> int: ... + @abstractmethod + def record_history(self, history: LoadHistory) -> None: ... + DB = TypeVar("DB", bound="duckdb.DuckDBPyConnection | psycopg.Connection") @@ -65,6 +87,20 @@ def ingest_records(self, prefix: Prefix, records: Iterator[bytes]) -> int: ... class TypedDatabase(Database, Generic[DB]): def __init__(self, conn_factory: Callable[[], DB]): self._conn_factory = conn_factory + with closing(self._conn_factory()) as conn, conn.cursor() as cur: + cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') + cur.execute(""" +CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history" ( + "table_name" TEXT UNIQUE + ,"query" TEXT + ,"start_utc" TIMESTAMP + ,"download_complete_utc" TIMESTAMP + ,"scan_complete_utc" TIMESTAMP + ,"transformation_complete_utc" TIMESTAMP + ,"index_complete_utc" TIMESTAMP + ,"row_count" INTEGER +);""") + conn.commit() @abstractmethod def _rollback(self, conn: DB) -> None: ... @@ -76,6 +112,10 @@ def drop_prefix( with closing(self._conn_factory()) as conn: self._drop_extracted_tables(conn, prefix) self._drop_raw_table(conn, prefix) + conn.execute( + 'DELETE FROM "ldlite_system"."load_history" WHERE "table_name" = $1', + (prefix.load_history_key,), + ) conn.commit() def drop_raw_table( @@ -179,3 +219,30 @@ def _prepare_raw_table( table=prefix.raw_table_name, ).as_string(), ) + + def record_history(self, history: LoadHistory) -> None: + with closing(self._conn_factory()) as conn, conn.cursor() as cur: + cur.execute( + """ +INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7,$8) +ON CONFLICT ("table_name") DO UPDATE SET + "query" = EXCLUDED."query" + ,"start_utc" = EXCLUDED."start_utc" + ,"download_complete_utc" = EXCLUDED."download_complete_utc" + ,"scan_complete_utc" = EXCLUDED."scan_complete_utc" + ,"transformation_complete_utc" = EXCLUDED."transformation_complete_utc" + ,"index_complete_utc" = EXCLUDED."index_complete_utc" + ,"row_count" = EXCLUDED."row_count" +""", + ( + history.table_name.load_history_key, + history.query, + history.start.astimezone(timezone.utc), + history.download.astimezone(timezone.utc), + history.scan.astimezone(timezone.utc), + history.transform.astimezone(timezone.utc), + history.index.astimezone(timezone.utc), + history.total, + ), + ) + conn.commit() diff --git a/src/ldlite/_database/postgres.py b/src/ldlite/_database/postgres.py index 8008d22..adccf37 100644 --- a/src/ldlite/_database/postgres.py +++ b/src/ldlite/_database/postgres.py @@ -8,6 +8,11 @@ class PostgresDatabase(TypedDatabase[psycopg.Connection]): + def __init__(self, dsn: str): + # RawCursor lets us use $1, $2, etc to use the + # same sql between duckdb and postgres + super().__init__(lambda: psycopg.connect(dsn, cursor_factory=psycopg.RawCursor)) + def _rollback(self, conn: psycopg.Connection) -> None: conn.rollback() diff --git a/src/ldlite/_jsonx.py b/src/ldlite/_jsonx.py index ed327e8..d96b69c 100644 --- a/src/ldlite/_jsonx.py +++ b/src/ldlite/_jsonx.py @@ -1,5 +1,6 @@ import json import uuid +from datetime import datetime, timezone from typing import TYPE_CHECKING, Literal, Union import duckdb @@ -407,7 +408,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 total: int, quiet: bool, max_depth: int, -) -> tuple[list[str], dict[str, dict[str, Attr]]]: +) -> tuple[list[str], dict[str, dict[str, Attr]], datetime]: # Scan all fields for JSON data # First get a list of the string attributes str_attrs: list[str] = [] @@ -420,7 +421,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 cur.close() # Scan data for JSON objects if len(str_attrs) == 0: - return [], {} + return [], {}, datetime.now(timezone.utc) json_attrs: list[str] = [] json_attrs_set: set[str] = set() newattrs: dict[str, dict[str, Attr]] = {} @@ -511,6 +512,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 finally: cur.close() db.commit() + scan = datetime.now(timezone.utc) # Set all row IDs to 1 row_ids = {} for t in newattrs: @@ -518,7 +520,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 # Run transformation # Select only JSON columns if len(json_attrs) == 0: - return [], {} + return [], {}, scan cur = server_cursor(db, dbtype) try: cur.execute( @@ -608,4 +610,4 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 finally: cur.close() db.commit() - return sorted([*list(newattrs.keys()), tcatalog]), newattrs + return sorted([*list(newattrs.keys()), tcatalog]), newattrs, scan diff --git a/tests/test_cases/base.py b/tests/test_cases/base.py index c908912..2977256 100644 --- a/tests/test_cases/base.py +++ b/tests/test_cases/base.py @@ -1,7 +1,7 @@ import json from dataclasses import dataclass from functools import cached_property -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, cast from unittest.mock import MagicMock from uuid import uuid4 @@ -11,7 +11,7 @@ @dataclass(frozen=True) class EndToEndTestCase: - values: dict[str, list[dict[str, Any]]] + values: dict[str, list[dict[str, Any]] | list[list[dict[str, Any]]]] @cached_property def db(self) -> str: @@ -33,20 +33,27 @@ def patch_request_get( httpx_post_mock.return_value.cookies.__getitem__.return_value = "token" side_effects = [] - for values in self.values.values(): - key = next(iter(values[0].keys())) + for vsource in self.values.values(): + list_values = ( + [cast("list[dict[str, Any]]", vsource)] + if isinstance(vsource[0], dict) + else cast("list[list[dict[str, Any]]]", vsource) + ) + + key = next(iter(list_values[0][0].keys())) total_mock = MagicMock() total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' - value_mocks = [] - for v in values: - value_mock = MagicMock() - value_mock.text = json.dumps(v) - value_mocks.append(value_mock) + for values in list_values: + value_mocks = [] + for v in values: + value_mock = MagicMock() + value_mock.text = json.dumps(v) + value_mocks.append(value_mock) - end_mock = MagicMock() - end_mock.text = f'{{"{key}": [] }}' + end_mock = MagicMock() + end_mock.text = f'{{"{key}": [] }}' - side_effects.extend([total_mock, *value_mocks, end_mock]) + side_effects.extend([total_mock, *value_mocks, end_mock]) client_get_mock.side_effect = side_effects diff --git a/tests/test_cases/load_history_cases.py b/tests/test_cases/load_history_cases.py new file mode 100644 index 0000000..44fa6df --- /dev/null +++ b/tests/test_cases/load_history_cases.py @@ -0,0 +1,74 @@ +from dataclasses import dataclass + +from pytest_cases import parametrize + +from .base import EndToEndTestCase + + +@dataclass(frozen=True) +class LoadHistoryCase(EndToEndTestCase): + queries: dict[str, list[str | None | dict[str, str]]] + expected_loads: dict[str, tuple[str | None, int]] + + +class LoadHistoryTestCases: + @parametrize(query=[None, "poline.id=*A"]) + def case_one_load(self, query: str | None) -> LoadHistoryCase: + return LoadHistoryCase( + values={ + "prefix": [ + { + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + { + "id": "b096504a-9999-4664-9bf5-1b872466fd66", + "value": "value-2", + }, + ], + }, + ], + }, + queries={"prefix": [query]}, + expected_loads={ + "public.prefix": (query, 2), + }, + ) + + def case_two_loads(self) -> LoadHistoryCase: + return LoadHistoryCase( + values={ + "prefix": [ + [ + { + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + ], + }, + ], + [ + { + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + { + "id": "b096504a-9999-4664-9bf5-1b872466fd66", + "value": "value-2", + }, + ], + }, + ], + ], + }, + queries={"prefix": [None, "a query"]}, + expected_loads={ + "public.prefix": ("a query", 2), + }, + ) diff --git a/tests/test_duckdb.py b/tests/test_duckdb.py index 5054878..bbab397 100644 --- a/tests/test_duckdb.py +++ b/tests/test_duckdb.py @@ -1,5 +1,6 @@ from difflib import unified_diff from pathlib import Path +from typing import Any, cast from unittest import mock from unittest.mock import MagicMock @@ -8,6 +9,7 @@ from pytest_cases import parametrize_with_cases from tests.test_cases import drop_tables_cases as dtc +from tests.test_cases import load_history_cases as lhc from tests.test_cases import query_cases as qc from tests.test_cases import to_csv_cases as csvc @@ -33,9 +35,26 @@ def test_drop_tables( ld.drop_tables(tc.drop) with duckdb.connect(dsn) as res: - res.execute("SHOW TABLES;") + res.execute( + """ + SELECT table_name + FROM information_schema.tables + WHERE table_schema='main' + """, + ) assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) + res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + assert (ud := res.fetchone()) is not None + assert ud[0] == len(tc.values) - 1 + res.execute( + 'SELECT COUNT(*) FROM "ldlite_system"."load_history" ' + 'WHERE "table_name" = $1', + (tc.drop,), + ) + assert (d := res.fetchone()) is not None + assert d[0] == 0 + @mock.patch("httpx_folio.auth.httpx.post") @mock.patch("httpx_folio.factories.httpx.Client.get") @@ -62,7 +81,13 @@ def test_query( ) with duckdb.connect(dsn) as res: - res.execute("SHOW TABLES;") + res.execute( + """ + SELECT table_name + FROM information_schema.tables + WHERE table_schema='main' + """, + ) assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) for table, (cols, values) in tc.expected_values.items(): @@ -107,3 +132,46 @@ def test_to_csv( diff = list(unified_diff(expected_lines, actual_lines)) if len(diff) > 0: pytest.fail("".join(diff)) + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=lhc.LoadHistoryTestCases) +def test_history( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: lhc.LoadHistoryCase, +) -> None: + from ldlite import LDLite as uut + + ld = uut() + tc.patch_request_get(ld, httpx_post_mock, client_get_mock) + dsn = f":memory:{tc.db}" + ld.connect_folio("https://doesnt.matter", "", "", "") + ld.connect_db(dsn) + + for prefix, calls in cast( + "dict[str, list[list[dict[str, Any]]]]", + tc.values, + ).items(): + for i in range(len(calls)): + ld.query( + table=prefix, + path="/patched", + query=tc.queries[prefix][i], + ) + + with duckdb.connect(dsn) as res: + res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + assert (ud := res.fetchone()) is not None + assert ud[0] == len(tc.expected_loads) + + for tn, (q, t) in tc.expected_loads.items(): + res.execute( + 'SELECT * FROM "ldlite_system"."load_history" WHERE "table_name" = $1', + (tn,), + ) + assert (d := res.fetchone()) is not None + assert d[1] == q + assert d[7] == t + assert d[6] > d[5] > d[4] > d[3] > d[2] diff --git a/tests/test_postgres.py b/tests/test_postgres.py index e6d79e9..d58d8b0 100644 --- a/tests/test_postgres.py +++ b/tests/test_postgres.py @@ -2,7 +2,7 @@ from collections.abc import Callable from difflib import unified_diff from pathlib import Path -from typing import cast +from typing import Any, cast from unittest import mock from unittest.mock import MagicMock @@ -12,6 +12,7 @@ from pytest_cases import parametrize_with_cases from tests.test_cases import drop_tables_cases as dtc +from tests.test_cases import load_history_cases as lhc from tests.test_cases import query_cases as qc from tests.test_cases import to_csv_cases as csvc @@ -70,6 +71,17 @@ def test_drop_tables( ) assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) + res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + assert (ud := res.fetchone()) is not None + assert ud[0] == len(tc.values) - 1 + res.execute( + 'SELECT COUNT(*) FROM "ldlite_system"."load_history"' + 'WHERE "table_name" = %s', + (tc.drop,), + ) + assert (d := res.fetchone()) is not None + assert d[0] == 0 + @mock.patch("httpx_folio.auth.httpx.post") @mock.patch("httpx_folio.factories.httpx.Client.get") @@ -178,3 +190,50 @@ def test_to_csv( diff = list(unified_diff(expected_lines, actual_lines)) if len(diff) > 0: pytest.fail("".join(diff)) + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=lhc.LoadHistoryTestCases) +def test_history( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + pg_dsn: None | Callable[[str], str], + tc: lhc.LoadHistoryCase, +) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + from ldlite import LDLite as uut + + ld = uut() + tc.patch_request_get(ld, httpx_post_mock, client_get_mock) + dsn = pg_dsn(tc.db) + ld.connect_folio("https://doesnt.matter", "", "", "") + ld.connect_db_postgresql(dsn) + + for prefix, calls in cast( + "dict[str, list[list[dict[str, Any]]]]", + tc.values, + ).items(): + for i in range(len(calls)): + ld.query( + table=prefix, + path="/patched", + query=tc.queries[prefix][i], + ) + + with psycopg.connect(dsn) as conn, conn.cursor() as res: + res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + assert (ud := res.fetchone()) is not None + assert ud[0] == len(tc.expected_loads) + + for tn, (q, t) in tc.expected_loads.items(): + res.execute( + 'SELECT * FROM "ldlite_system"."load_history" WHERE "table_name" = %s', + (tn,), + ) + assert (d := res.fetchone()) is not None + assert d[1] == q + assert d[7] == t + assert d[6] > d[5] > d[4] > d[3] > d[2] From 2611adc8417179e5830971c1f57b25aba5e10377 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Tue, 23 Sep 2025 15:26:02 -0400 Subject: [PATCH 04/25] Remove rollback from drop_tables logic (#49) LDLite has always used exceptions for normal program logic around the dropping tables out of the catalog in case the catalog didn't exist. It leads to broken connections requiring rollbacks and I haven't been happy with the implementation of it as rollback works differently with pg and duckdb. This now checks for the catalog tables before trying to query them which cleans up the abstract base class. As part of cleaning up the prefix object I removed the default schema from the key if there is no schema. --- src/ldlite/_database/__init__.py | 107 ++++++++++++++----------- src/ldlite/_database/duckdb.py | 9 +-- src/ldlite/_database/postgres.py | 9 +-- tests/test_cases/load_history_cases.py | 28 ++++++- tests/test_duckdb.py | 1 + tests/test_postgres.py | 1 + 6 files changed, 94 insertions(+), 61 deletions(-) diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py index 5229176..b287c79 100644 --- a/src/ldlite/_database/__init__.py +++ b/src/ldlite/_database/__init__.py @@ -15,7 +15,7 @@ class Prefix: def __init__(self, prefix: str): - self._schema: str | None = None + self.schema: str | None = None sandt = prefix.split(".") if len(sandt) > 2: msg = f"Expected one or two identifiers but got {prefix}" @@ -24,32 +24,43 @@ def __init__(self, prefix: str): if len(sandt) == 1: (self._prefix,) = sandt else: - (self._schema, self._prefix) = sandt - - @property - def schema_name(self) -> sql.Identifier | None: - return None if self._schema is None else sql.Identifier(self._schema) + (self.schema, self._prefix) = sandt def _identifier(self, table: str) -> sql.Identifier: - if self._schema is None: + if self.schema is None: return sql.Identifier(table) - return sql.Identifier(self._schema, table) + return sql.Identifier(self.schema, table) @property - def load_history_key(self) -> str: - return (self._schema or "public") + "." + self._prefix + def schema_identifier(self) -> sql.Identifier | None: + return None if self.schema is None else sql.Identifier(self.schema) @property - def raw_table_name(self) -> sql.Identifier: + def raw_table_identifier(self) -> sql.Identifier: return self._identifier(self._prefix) @property - def catalog_table_name(self) -> sql.Identifier: - return self._identifier(f"{self._prefix}__tcatalog") + def catalog_table_name(self) -> str: + return f"{self._prefix}__tcatalog" + + @property + def catalog_table_identifier(self) -> sql.Identifier: + return self._identifier(self.catalog_table_name) + + @property + def legacy_jtable_name(self) -> str: + return f"{self._prefix}_jtable" @property - def legacy_jtable(self) -> sql.Identifier: - return self._identifier(f"{self._prefix}_jtable") + def legacy_jtable_identifier(self) -> sql.Identifier: + return self._identifier(self.legacy_jtable_name) + + @property + def load_history_key(self) -> str: + if self.schema is None: + return self._prefix + + return self.schema + "." + self._prefix @dataclass(frozen=True) @@ -102,8 +113,9 @@ def __init__(self, conn_factory: Callable[[], DB]): );""") conn.commit() + @property @abstractmethod - def _rollback(self, conn: DB) -> None: ... + def _default_schema(self) -> str: ... def drop_prefix( self, @@ -134,7 +146,7 @@ def _drop_raw_table( with closing(conn.cursor()) as cur: cur.execute( sql.SQL("DROP TABLE IF EXISTS {table};") - .format(table=prefix.raw_table_name) + .format(table=prefix.raw_table_identifier) .as_string(), ) @@ -146,9 +158,6 @@ def drop_extracted_tables( self._drop_extracted_tables(conn, prefix) conn.commit() - @property - @abstractmethod - def _missing_table_error(self) -> type[Exception]: ... def _drop_extracted_tables( self, conn: DB, @@ -156,28 +165,32 @@ def _drop_extracted_tables( ) -> None: tables: list[Sequence[Sequence[Any]]] = [] with closing(conn.cursor()) as cur: - try: - cur.execute( - sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.catalog_table_name) - .as_string(), - ) - except self._missing_table_error: - self._rollback(conn) - else: - tables.extend(cur.fetchall()) - - with closing(conn.cursor()) as cur: - try: - cur.execute( - sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.legacy_jtable) - .as_string(), - ) - except self._missing_table_error: - self._rollback(conn) - else: - tables.extend(cur.fetchall()) + cur.execute( + """ +SELECT table_name FROM information_schema.tables +WHERE table_schema = $1 and table_name IN ($2, $3);""", + ( + prefix.schema or self._default_schema, + prefix.catalog_table_name, + prefix.legacy_jtable_name, + ), + ) + for (tname,) in cur.fetchall(): + if tname == prefix.catalog_table_name: + cur.execute( + sql.SQL("SELECT table_name FROM {catalog};") + .format(catalog=prefix.catalog_table_identifier) + .as_string(), + ) + tables.extend(cur.fetchall()) + + if tname == prefix.legacy_jtable_name: + cur.execute( + sql.SQL("SELECT table_name FROM {catalog};") + .format(catalog=prefix.legacy_jtable_identifier) + .as_string(), + ) + tables.extend(cur.fetchall()) with closing(conn.cursor()) as cur: for (et,) in tables: @@ -188,12 +201,12 @@ def _drop_extracted_tables( ) cur.execute( sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.catalog_table_name) + .format(catalog=prefix.catalog_table_identifier) .as_string(), ) cur.execute( sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.legacy_jtable) + .format(catalog=prefix.legacy_jtable_identifier) .as_string(), ) @@ -206,17 +219,17 @@ def _prepare_raw_table( prefix: Prefix, ) -> None: with closing(conn.cursor()) as cur: - if prefix.schema_name is not None: + if prefix.schema_identifier is not None: cur.execute( sql.SQL("CREATE SCHEMA IF NOT EXISTS {schema};") - .format(schema=prefix.schema_name) + .format(schema=prefix.schema_identifier) .as_string(), ) self._drop_raw_table(conn, prefix) with closing(conn.cursor()) as cur: cur.execute( self._create_raw_table_sql.format( - table=prefix.raw_table_name, + table=prefix.raw_table_identifier, ).as_string(), ) diff --git a/src/ldlite/_database/duckdb.py b/src/ldlite/_database/duckdb.py index ebe5806..0676875 100644 --- a/src/ldlite/_database/duckdb.py +++ b/src/ldlite/_database/duckdb.py @@ -8,12 +8,9 @@ class DuckDbDatabase(TypedDatabase[duckdb.DuckDBPyConnection]): - def _rollback(self, conn: duckdb.DuckDBPyConnection) -> None: - pass - @property - def _missing_table_error(self) -> type[Exception]: - return duckdb.CatalogException + def _default_schema(self) -> str: + return "main" @property def _create_raw_table_sql(self) -> sql.SQL: @@ -31,7 +28,7 @@ def ingest_records( insert_sql = ( sql.SQL("INSERT INTO {table} VALUES(?, ?);") .format( - table=prefix.raw_table_name, + table=prefix.raw_table_identifier, ) .as_string() ) diff --git a/src/ldlite/_database/postgres.py b/src/ldlite/_database/postgres.py index adccf37..479018d 100644 --- a/src/ldlite/_database/postgres.py +++ b/src/ldlite/_database/postgres.py @@ -13,12 +13,9 @@ def __init__(self, dsn: str): # same sql between duckdb and postgres super().__init__(lambda: psycopg.connect(dsn, cursor_factory=psycopg.RawCursor)) - def _rollback(self, conn: psycopg.Connection) -> None: - conn.rollback() - @property - def _missing_table_error(self) -> type[Exception]: - return psycopg.errors.UndefinedTable + def _default_schema(self) -> str: + return "public" @property def _create_raw_table_sql(self) -> sql.SQL: @@ -40,7 +37,7 @@ def ingest_records( cur.copy( sql.SQL( "COPY {table} (__id, jsonb) FROM STDIN (FORMAT BINARY)", - ).format(table=prefix.raw_table_name), + ).format(table=prefix.raw_table_identifier), ) as copy, ): # postgres jsonb is always version 1 diff --git a/tests/test_cases/load_history_cases.py b/tests/test_cases/load_history_cases.py index 44fa6df..ed1727b 100644 --- a/tests/test_cases/load_history_cases.py +++ b/tests/test_cases/load_history_cases.py @@ -33,7 +33,31 @@ def case_one_load(self, query: str | None) -> LoadHistoryCase: }, queries={"prefix": [query]}, expected_loads={ - "public.prefix": (query, 2), + "prefix": (query, 2), + }, + ) + + def case_schema_load(self) -> LoadHistoryCase: + return LoadHistoryCase( + values={ + "schema.prefix": [ + { + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + { + "id": "b096504a-9999-4664-9bf5-1b872466fd66", + "value": "value-2", + }, + ], + }, + ], + }, + queries={"schema.prefix": [None]}, + expected_loads={ + "schema.prefix": (None, 2), }, ) @@ -69,6 +93,6 @@ def case_two_loads(self) -> LoadHistoryCase: }, queries={"prefix": [None, "a query"]}, expected_loads={ - "public.prefix": ("a query", 2), + "prefix": ("a query", 2), }, ) diff --git a/tests/test_duckdb.py b/tests/test_duckdb.py index bbab397..1c3f8ea 100644 --- a/tests/test_duckdb.py +++ b/tests/test_duckdb.py @@ -29,6 +29,7 @@ def test_drop_tables( dsn = f":memory:{tc.db}" ld.connect_folio("https://doesnt.matter", "", "", "") ld.connect_db(dsn) + ld.drop_tables(tc.drop) for prefix in tc.values: ld.query(table=prefix, path="/patched", keep_raw=tc.keep_raw) diff --git a/tests/test_postgres.py b/tests/test_postgres.py index d58d8b0..1489869 100644 --- a/tests/test_postgres.py +++ b/tests/test_postgres.py @@ -56,6 +56,7 @@ def test_drop_tables( dsn = pg_dsn(tc.db) ld.connect_folio("https://doesnt.matter", "", "", "") ld.connect_db_postgresql(dsn) + ld.drop_tables(tc.drop) for prefix in tc.values: ld.query(table=prefix, path="/patched", keep_raw=tc.keep_raw) From 40effc9d154dbb70f5f37d31a187ee30fd0eb8b0 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Wed, 24 Sep 2025 14:06:13 -0400 Subject: [PATCH 05/25] Refactor test structure (#50) The tests had been setup with all the cases in one location, then each database having its own file to arrange/act/assert based on those cases. A few things precipitated an inversion where now the test cases are split up among files and the test logic is shared between databases. 1. There's no sqlite so it is easier to make one database call 1. We added a 4th type of test with history and are about to add many many more for the transformation rework 1. The test setup was getting hard to even understand and modify 1. The end to end tests would be nice to have running on postgres As part of this refactor the slow-running integration tests are now filterable based on the Integration name. I've also mad the end to end tests run against both duckdb and postgres. There's also lots of misc database and sql cleanup pieces in tests where I wasn't using the libraries in the best ways before. --- tests/README.md | 16 +- tests/conftest.py | 25 + .../basic.csv | 0 .../datatypes.csv | 0 .../escaped_chars.csv | 0 .../sorting.csv | 0 tests/mock_response_case.py | 76 ++ tests/test___init__.py | 160 ++-- tests/test_cases/base.py | 59 -- tests/test_cases/drop_tables_cases.py | 62 -- tests/test_cases/load_history_cases.py | 98 --- tests/test_cases/query_cases.py | 605 --------------- tests/test_cases/to_csv_cases.py | 100 --- tests/test_drop_tables.py | 172 +++++ tests/test_duckdb.py | 178 ----- tests/test_endtoend.py | 240 ++++-- tests/test_export_csv.py | 171 +++++ tests/test_load_history.py | 179 +++++ tests/test_postgres.py | 240 ------ tests/test_query.py | 698 ++++++++++++++++++ 20 files changed, 1576 insertions(+), 1503 deletions(-) rename tests/{test_cases/to_csv_samples => export_csv_samples}/basic.csv (100%) rename tests/{test_cases/to_csv_samples => export_csv_samples}/datatypes.csv (100%) rename tests/{test_cases/to_csv_samples => export_csv_samples}/escaped_chars.csv (100%) rename tests/{test_cases/to_csv_samples => export_csv_samples}/sorting.csv (100%) create mode 100644 tests/mock_response_case.py delete mode 100644 tests/test_cases/base.py delete mode 100644 tests/test_cases/drop_tables_cases.py delete mode 100644 tests/test_cases/load_history_cases.py delete mode 100644 tests/test_cases/query_cases.py delete mode 100644 tests/test_cases/to_csv_cases.py create mode 100644 tests/test_drop_tables.py delete mode 100644 tests/test_duckdb.py create mode 100644 tests/test_export_csv.py create mode 100644 tests/test_load_history.py delete mode 100644 tests/test_postgres.py create mode 100644 tests/test_query.py diff --git a/tests/README.md b/tests/README.md index 85b5758..8d31d04 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,4 +1,18 @@ -# Test Setup +# Tests + +## Running tests + +There is a pdm script which runs tests with code coverage `pdm run test`. Any additional parameters will be passed through to pytest. + +The -k parameter filters tests. Some useful examples: +``` +pdm run test -k "Integration" +pdm run test --pg-host 172.17.0.3 -k "postgres and not Integration" +pdm run test -k "drop_tables and not postgres" +pdm run test -k "duckdb" +``` + +## Test Setup Duckdb tests "just work". Postgres tests will be skipped unless you set them up first. diff --git a/tests/conftest.py b/tests/conftest.py index b9ccef2..38a7e5d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,10 @@ +import contextlib +from collections.abc import Callable + +import psycopg import pytest from httpx_folio.auth import FolioParams +from psycopg import sql def pytest_addoption(parser: pytest.Parser) -> None: @@ -24,3 +29,23 @@ def folio_params(pytestconfig: pytest.Config) -> tuple[bool, FolioParams]: pytestconfig.getoption("folio_password") or "admin", ), ) + + +@pytest.fixture(scope="session") +def pg_dsn(pytestconfig: pytest.Config) -> None | Callable[[str], str]: + host = pytestconfig.getoption("pg_host") + if host is None: + return None + + def setup(db: str) -> str: + base_dsn = f"host={host} user=ldlite password=ldlite" + with contextlib.closing(psycopg.connect(base_dsn)) as base_conn: + base_conn.autocommit = True + with base_conn.cursor() as curr: + curr.execute( + sql.SQL("CREATE DATABASE {db};").format(db=sql.Identifier(db)), + ) + + return base_dsn + f" dbname={db}" + + return setup diff --git a/tests/test_cases/to_csv_samples/basic.csv b/tests/export_csv_samples/basic.csv similarity index 100% rename from tests/test_cases/to_csv_samples/basic.csv rename to tests/export_csv_samples/basic.csv diff --git a/tests/test_cases/to_csv_samples/datatypes.csv b/tests/export_csv_samples/datatypes.csv similarity index 100% rename from tests/test_cases/to_csv_samples/datatypes.csv rename to tests/export_csv_samples/datatypes.csv diff --git a/tests/test_cases/to_csv_samples/escaped_chars.csv b/tests/export_csv_samples/escaped_chars.csv similarity index 100% rename from tests/test_cases/to_csv_samples/escaped_chars.csv rename to tests/export_csv_samples/escaped_chars.csv diff --git a/tests/test_cases/to_csv_samples/sorting.csv b/tests/export_csv_samples/sorting.csv similarity index 100% rename from tests/test_cases/to_csv_samples/sorting.csv rename to tests/export_csv_samples/sorting.csv diff --git a/tests/mock_response_case.py b/tests/mock_response_case.py new file mode 100644 index 0000000..353be9e --- /dev/null +++ b/tests/mock_response_case.py @@ -0,0 +1,76 @@ +import json +from dataclasses import dataclass +from functools import cached_property +from typing import TYPE_CHECKING +from unittest.mock import MagicMock +from uuid import uuid4 + +if TYPE_CHECKING: + import ldlite + + +@dataclass(frozen=True) +class Call: + prefix: str + returns: "ldlite._jsonx.Json | list[ldlite._jsonx.Json]" + + # duplicate of LDLite.query default params + query: str | dict[str, str] | None = None + json_depth: int = 3 + limit: int | None = None + keep_raw: bool = True + + @property + def returns_list(self) -> list["ldlite._jsonx.Json"]: + if isinstance(self.returns, list): + return self.returns + + return [self.returns] + + +@dataclass(frozen=True) +class MockedResponseTestCase: + calls: Call | list[Call] + + @property + def calls_list(self) -> list[Call]: + if isinstance(self.calls, list): + return self.calls + + return [self.calls] + + @cached_property + def db(self) -> str: + db = "db" + str(uuid4()).split("-")[0] + print(db) # noqa: T201 + return db + + def patch_request_get( + self, + ld: "ldlite.LDLite", + httpx_post_mock: MagicMock, + client_get_mock: MagicMock, + ) -> None: + # leave tqdm out of it + ld.quiet(enable=True) + + httpx_post_mock.return_value.cookies.__getitem__.return_value = "token" + + side_effects = [] + for call in self.calls_list: + key = next(iter(call.returns_list[0].keys())) + total_mock = MagicMock() + total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' + + value_mocks = [] + for v in call.returns_list: + value_mock = MagicMock() + value_mock.text = json.dumps(v) + value_mocks.append(value_mock) + + end_mock = MagicMock() + end_mock.text = f'{{"{key}": [] }}' + + side_effects.extend([total_mock, *value_mocks, end_mock]) + + client_get_mock.side_effect = side_effects diff --git a/tests/test___init__.py b/tests/test___init__.py index e880ebf..e363ed4 100644 --- a/tests/test___init__.py +++ b/tests/test___init__.py @@ -7,78 +7,6 @@ from pytest_cases import parametrize_with_cases -def test_ok_legacy(folio_params: tuple[bool, FolioParams]) -> None: - from ldlite import LDLite as uut - - ld = uut() - ld.connect_folio(*astuple(folio_params[1])) - ld.connect_db() - ld.query(table="g", path="/groups", query="cql.allRecords=1 sortby id") - ld.select(table="g__t") - - -def test_ok_limit(folio_params: tuple[bool, FolioParams]) -> None: - from ldlite import LDLite as uut - - ld = uut() - db = ld.connect_db() - - ld.connect_folio(*astuple(folio_params[1])) - ld.page_size = 2 - ld.query(table="g", path="/groups", query="cql.allRecords=1 sortby id", limit=5) - - db.execute("SELECT COUNT(DISTINCT COLUMNS(*)) FROM g__t;") - actual = cast("tuple[int]", db.fetchone())[0] - assert actual == 5 - - -def test_ok_trailing_slash(folio_params: tuple[bool, FolioParams]) -> None: - if folio_params[0]: - pytest.skip("Specify an okapi environment with --folio-base-url to run") - - from ldlite import LDLite as uut - - ld = uut() - params = astuple(folio_params[1]) - ld.connect_folio(*[params[0] + "/", *params[1:]]) - ld.connect_db() - ld.query(table="g", path="/groups") - ld.select(table="g__t") - - -def test_ok(folio_params: tuple[bool, FolioParams]) -> None: - from ldlite import LDLite as uut - - ld = uut() - ld.connect_folio(*astuple(folio_params[1])) - ld.connect_db() - ld.query(table="g", path="/groups") - ld.select(table="g__t") - - -def test_no_connect_folio() -> None: - from ldlite import LDLite as uut - - ld = uut() - ld.connect_db() - with pytest.raises(RuntimeError): - ld.query(table="g", path="/groups") - - -def test_no_connect_db() -> None: - from ldlite import LDLite as uut - - ld = uut() - ld.connect_folio( - url="https://folio-etesting-snapshot-kong.ci.folio.org", - tenant="diku", - user="diku_admin", - password="admin", - ) - with pytest.raises(RuntimeError): - ld.query(table="g", path="/groups") - - @dataclass(frozen=True) class FolioConnectionCase: expected: type[Exception] @@ -116,14 +44,82 @@ def case_password(self) -> FolioConnectionCase: ) -@parametrize_with_cases("tc", cases=FolioConnectionCases) -def test_bad_folio_connection( - folio_params: tuple[bool, FolioParams], - tc: FolioConnectionCase, -) -> None: - from ldlite import LDLite as uut +class TestIntegration: + def test_ok_legacy(self, folio_params: tuple[bool, FolioParams]) -> None: + from ldlite import LDLite as uut + + ld = uut() + ld.connect_folio(*astuple(folio_params[1])) + ld.connect_db() + ld.query(table="g", path="/groups", query="cql.allRecords=1 sortby id") + ld.select(table="g__t") + + def test_ok_limit(self, folio_params: tuple[bool, FolioParams]) -> None: + from ldlite import LDLite as uut + + ld = uut() + db = ld.connect_db() + + ld.connect_folio(*astuple(folio_params[1])) + ld.page_size = 2 + ld.query(table="g", path="/groups", query="cql.allRecords=1 sortby id", limit=5) + + db.execute("SELECT COUNT(DISTINCT COLUMNS(*)) FROM g__t;") + actual = cast("tuple[int]", db.fetchone())[0] + assert actual == 5 + + def test_ok_trailing_slash(self, folio_params: tuple[bool, FolioParams]) -> None: + if folio_params[0]: + pytest.skip("Specify an okapi environment with --folio-base-url to run") + + from ldlite import LDLite as uut - ld = uut() - params = astuple(folio_params[1]) - with pytest.raises(tc.expected): - ld.connect_folio(*[*params[: tc.index], tc.value, *params[tc.index + 1 :]]) + ld = uut() + params = astuple(folio_params[1]) + ld.connect_folio(*[params[0] + "/", *params[1:]]) + ld.connect_db() + ld.query(table="g", path="/groups") + ld.select(table="g__t") + + def test_ok(self, folio_params: tuple[bool, FolioParams]) -> None: + from ldlite import LDLite as uut + + ld = uut() + ld.connect_folio(*astuple(folio_params[1])) + ld.connect_db() + ld.query(table="g", path="/groups") + ld.select(table="g__t") + + def test_no_connect_folio(self) -> None: + from ldlite import LDLite as uut + + ld = uut() + ld.connect_db() + with pytest.raises(RuntimeError): + ld.query(table="g", path="/groups") + + def test_no_connect_db(self) -> None: + from ldlite import LDLite as uut + + ld = uut() + ld.connect_folio( + url="https://folio-etesting-snapshot-kong.ci.folio.org", + tenant="diku", + user="diku_admin", + password="admin", + ) + with pytest.raises(RuntimeError): + ld.query(table="g", path="/groups") + + @parametrize_with_cases("tc", cases=FolioConnectionCases) + def test_bad_folio_connection( + self, + folio_params: tuple[bool, FolioParams], + tc: FolioConnectionCase, + ) -> None: + from ldlite import LDLite as uut + + ld = uut() + params = astuple(folio_params[1]) + with pytest.raises(tc.expected): + ld.connect_folio(*[*params[: tc.index], tc.value, *params[tc.index + 1 :]]) diff --git a/tests/test_cases/base.py b/tests/test_cases/base.py deleted file mode 100644 index 2977256..0000000 --- a/tests/test_cases/base.py +++ /dev/null @@ -1,59 +0,0 @@ -import json -from dataclasses import dataclass -from functools import cached_property -from typing import TYPE_CHECKING, Any, cast -from unittest.mock import MagicMock -from uuid import uuid4 - -if TYPE_CHECKING: - import ldlite - - -@dataclass(frozen=True) -class EndToEndTestCase: - values: dict[str, list[dict[str, Any]] | list[list[dict[str, Any]]]] - - @cached_property - def db(self) -> str: - db = "db" + str(uuid4()).split("-")[0] - print(db) # noqa: T201 - return db - - def patch_request_get( - self, - ld: "ldlite.LDLite", - httpx_post_mock: MagicMock, - client_get_mock: MagicMock, - ) -> None: - # iteration hack - ld.page_size = 1 - # leave tqdm out of it - ld.quiet(enable=True) - - httpx_post_mock.return_value.cookies.__getitem__.return_value = "token" - - side_effects = [] - for vsource in self.values.values(): - list_values = ( - [cast("list[dict[str, Any]]", vsource)] - if isinstance(vsource[0], dict) - else cast("list[list[dict[str, Any]]]", vsource) - ) - - key = next(iter(list_values[0][0].keys())) - total_mock = MagicMock() - total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' - - for values in list_values: - value_mocks = [] - for v in values: - value_mock = MagicMock() - value_mock.text = json.dumps(v) - value_mocks.append(value_mock) - - end_mock = MagicMock() - end_mock.text = f'{{"{key}": [] }}' - - side_effects.extend([total_mock, *value_mocks, end_mock]) - - client_get_mock.side_effect = side_effects diff --git a/tests/test_cases/drop_tables_cases.py b/tests/test_cases/drop_tables_cases.py deleted file mode 100644 index e67c3b0..0000000 --- a/tests/test_cases/drop_tables_cases.py +++ /dev/null @@ -1,62 +0,0 @@ -from dataclasses import dataclass - -from pytest_cases import parametrize - -from .base import EndToEndTestCase - - -@dataclass(frozen=True) -class DropTablesCase(EndToEndTestCase): - drop: str - expected_tables: list[str] - keep_raw: bool - - -class DropTablesCases: - @parametrize(keep_raw=[True, False]) - def case_one_table(self, keep_raw: bool) -> DropTablesCase: - return DropTablesCase( - drop="prefix", - values={"prefix": [{"purchaseOrders": [{"id": "1"}]}]}, - expected_tables=[], - keep_raw=keep_raw, - ) - - @parametrize(keep_raw=[True, False]) - def case_two_tables(self, keep_raw: bool) -> DropTablesCase: - return DropTablesCase( - drop="prefix", - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "1", - "subObjects": [{"id": "2"}, {"id": "3"}], - }, - ], - }, - ], - }, - expected_tables=[], - keep_raw=keep_raw, - ) - - @parametrize(keep_raw=[True, False]) - def case_separate_table(self, keep_raw: bool) -> DropTablesCase: - expected_tables = [ - "notdropped__t", - "notdropped__tcatalog", - ] - if keep_raw: - expected_tables = ["notdropped", *expected_tables] - - return DropTablesCase( - drop="prefix", - values={ - "prefix": [{"purchaseOrders": [{"id": "1"}]}], - "notdropped": [{"purchaseOrders": [{"id": "1"}]}], - }, - expected_tables=expected_tables, - keep_raw=keep_raw, - ) diff --git a/tests/test_cases/load_history_cases.py b/tests/test_cases/load_history_cases.py deleted file mode 100644 index ed1727b..0000000 --- a/tests/test_cases/load_history_cases.py +++ /dev/null @@ -1,98 +0,0 @@ -from dataclasses import dataclass - -from pytest_cases import parametrize - -from .base import EndToEndTestCase - - -@dataclass(frozen=True) -class LoadHistoryCase(EndToEndTestCase): - queries: dict[str, list[str | None | dict[str, str]]] - expected_loads: dict[str, tuple[str | None, int]] - - -class LoadHistoryTestCases: - @parametrize(query=[None, "poline.id=*A"]) - def case_one_load(self, query: str | None) -> LoadHistoryCase: - return LoadHistoryCase( - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - }, - { - "id": "b096504a-9999-4664-9bf5-1b872466fd66", - "value": "value-2", - }, - ], - }, - ], - }, - queries={"prefix": [query]}, - expected_loads={ - "prefix": (query, 2), - }, - ) - - def case_schema_load(self) -> LoadHistoryCase: - return LoadHistoryCase( - values={ - "schema.prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - }, - { - "id": "b096504a-9999-4664-9bf5-1b872466fd66", - "value": "value-2", - }, - ], - }, - ], - }, - queries={"schema.prefix": [None]}, - expected_loads={ - "schema.prefix": (None, 2), - }, - ) - - def case_two_loads(self) -> LoadHistoryCase: - return LoadHistoryCase( - values={ - "prefix": [ - [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - }, - ], - }, - ], - [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - }, - { - "id": "b096504a-9999-4664-9bf5-1b872466fd66", - "value": "value-2", - }, - ], - }, - ], - ], - }, - queries={"prefix": [None, "a query"]}, - expected_loads={ - "prefix": ("a query", 2), - }, - ) diff --git a/tests/test_cases/query_cases.py b/tests/test_cases/query_cases.py deleted file mode 100644 index 9e3725e..0000000 --- a/tests/test_cases/query_cases.py +++ /dev/null @@ -1,605 +0,0 @@ -import json -from dataclasses import dataclass -from typing import Any - -from pytest_cases import parametrize - -from .base import EndToEndTestCase - - -@dataclass(frozen=True) -class QueryCase(EndToEndTestCase): - json_depth: int - expected_tables: list[str] - expected_values: dict[str, tuple[list[str], list[tuple[Any, ...]]]] - expected_indexes: list[tuple[str, str]] | None = None - keep_raw: bool = True - - -class QueryTestCases: - @parametrize(json_depth=range(1, 2)) - def case_one_table(self, json_depth: int) -> QueryCase: - return QueryCase( - json_depth=json_depth, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - }, - ], - }, - ], - }, - expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], - expected_values={ - "prefix__t": ( - ["id", "value"], - [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], - ), - "prefix__tcatalog": (["table_name"], [("prefix__t",)]), - }, - expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), - ("prefix__t", "id"), - ], - ) - - @parametrize(json_depth=range(2, 3)) - def case_two_tables(self, json_depth: int) -> QueryCase: - return QueryCase( - json_depth=json_depth, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - "subObjects": [ - { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value-1", - }, - { - "id": "f5bda109-a719-4f72-b797-b9c22f45e4e1", - "value": "sub-value-2", - }, - ], - }, - ], - }, - ], - }, - expected_tables=[ - "prefix", - "prefix__t", - "prefix__t__sub_objects", - "prefix__tcatalog", - ], - expected_values={ - "prefix__t": ( - ["id", "value"], - [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], - ), - "prefix__t__sub_objects": ( - ["id", "sub_objects__id", "sub_objects__value"], - [ - ( - "b096504a-3d54-4664-9bf5-1b872466fd66", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - "sub-value-1", - ), - ( - "b096504a-3d54-4664-9bf5-1b872466fd66", - "f5bda109-a719-4f72-b797-b9c22f45e4e1", - "sub-value-2", - ), - ], - ), - "prefix__tcatalog": ( - ["table_name"], - [("prefix__t",), ("prefix__t__sub_objects",)], - ), - }, - expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), - ("prefix__t", "id"), - ("prefix__t__sub_objects", "__id"), - ("prefix__t__sub_objects", "id"), - ("prefix__t__sub_objects", "sub_objects__o"), - ("prefix__t__sub_objects", "sub_objects__id"), - ], - ) - - @parametrize(json_depth=range(1)) - def case_table_no_expansion(self, json_depth: int) -> QueryCase: - return QueryCase( - json_depth=json_depth, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - "subObjects": [ - { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - }, - ], - }, - ], - }, - ], - }, - expected_tables=["prefix"], - expected_values={}, - ) - - def case_table_underexpansion(self) -> QueryCase: - return QueryCase( - json_depth=2, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "subObjects": [ - { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - "subSubObjects": [ - { - "id": ( - "2b94c631-fca9-4892-a730-03ee529ffe2a" - ), - "value": "sub-sub-value", - }, - ], - }, - ], - }, - ], - }, - ], - }, - expected_tables=[ - "prefix", - "prefix__t", - "prefix__t__sub_objects", - "prefix__tcatalog", - ], - expected_values={ - "prefix__t__sub_objects": ( - [ - "id", - "sub_objects__id", - "sub_objects__value", - ], - [ - ( - "b096504a-3d54-4664-9bf5-1b872466fd66", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - "sub-value", - ), - ], - ), - "prefix__tcatalog": ( - ["table_name"], - [("prefix__t",), ("prefix__t__sub_objects",)], - ), - }, - ) - - @parametrize(json_depth=range(3, 4)) - def case_three_tables(self, json_depth: int) -> QueryCase: - return QueryCase( - json_depth=json_depth, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - "subObjects": [ - { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - "subSubObjects": [ - { - "id": ( - "2b94c631-fca9-4892-a730-03ee529ffe2a" - ), - "value": "sub-sub-value", - }, - ], - }, - ], - }, - ], - }, - ], - }, - expected_tables=[ - "prefix", - "prefix__t", - "prefix__t__sub_objects", - "prefix__t__sub_objects__sub_sub_objects", - "prefix__tcatalog", - ], - expected_values={ - "prefix__t__sub_objects__sub_sub_objects": ( - [ - "id", - "sub_objects__id", - "sub_objects__sub_sub_objects__id", - "sub_objects__sub_sub_objects__value", - ], - [ - ( - "b096504a-3d54-4664-9bf5-1b872466fd66", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - "sub-sub-value", - ), - ], - ), - "prefix__tcatalog": ( - ["table_name"], - [ - ("prefix__t",), - ("prefix__t__sub_objects",), - ("prefix__t__sub_objects__sub_sub_objects",), - ], - ), - }, - expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), - ("prefix__t", "id"), - ("prefix__t__sub_objects", "__id"), - ("prefix__t__sub_objects", "id"), - ("prefix__t__sub_objects", "sub_objects__o"), - ("prefix__t__sub_objects", "sub_objects__id"), - ("prefix__t__sub_objects__sub_sub_objects", "__id"), - ("prefix__t__sub_objects__sub_sub_objects", "id"), - ("prefix__t__sub_objects__sub_sub_objects", "sub_objects__o"), - ("prefix__t__sub_objects__sub_sub_objects", "sub_objects__id"), - ( - "prefix__t__sub_objects__sub_sub_objects", - "sub_objects__sub_sub_objects__o", - ), - ( - "prefix__t__sub_objects__sub_sub_objects", - "sub_objects__sub_sub_objects__id", - ), - ], - ) - - def case_nested_object(self) -> QueryCase: - return QueryCase( - json_depth=2, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - "subObject": { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - }, - }, - ], - }, - ], - }, - expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], - expected_values={ - "prefix__t": ( - ["id", "value", "sub_object__id", "sub_object__value"], - [ - ( - "b096504a-3d54-4664-9bf5-1b872466fd66", - "value", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - "sub-value", - ), - ], - ), - "prefix__tcatalog": ( - ["table_name"], - [("prefix__t",)], - ), - }, - expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), - ("prefix__t", "id"), - ("prefix__t", "sub_object__id"), - ], - ) - - def case_doubly_nested_object(self) -> QueryCase: - return QueryCase( - json_depth=3, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - "subObject": { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - "subSubObject": { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-sub-value", - }, - }, - }, - ], - }, - ], - }, - expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], - expected_values={ - "prefix__t": ( - [ - "id", - "value", - "sub_object__id", - "sub_object__sub_sub_object__id", - "sub_object__sub_sub_object__value", - ], - [ - ( - "b096504a-3d54-4664-9bf5-1b872466fd66", - "value", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - "sub-sub-value", - ), - ], - ), - "prefix__tcatalog": ( - ["table_name"], - [("prefix__t",)], - ), - }, - expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), - ("prefix__t", "id"), - ("prefix__t", "sub_object__id"), - ("prefix__t", "sub_object__sub_sub_object__id"), - ], - ) - - def case_nested_object_underexpansion(self) -> QueryCase: - return QueryCase( - json_depth=1, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - "subObject": { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - }, - }, - ], - }, - ], - }, - expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], - expected_values={ - "prefix__t": ( - ["id", "value", "sub_object"], - [ - ( - "b096504a-3d54-4664-9bf5-1b872466fd66", - "value", - json.dumps( - { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - }, - indent=4, - ), - ), - ], - ), - "prefix__tcatalog": ( - ["table_name"], - [("prefix__t",)], - ), - }, - ) - - def case_id_generation(self) -> QueryCase: - return QueryCase( - json_depth=4, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "subObjects": [ - { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "subSubObjects": [ - { - "id": ( - "2b94c631-fca9-4892-a730-03ee529ffe2a" - ), - }, - { - "id": ( - "8516a913-8bf7-55a4-ab71-417aba9171c9" - ), - }, - ], - }, - { - "id": "b5d8cdc4-9441-487c-90cf-0c7ec97728eb", - "subSubObjects": [ - { - "id": ( - "13a24cc8-a15c-4158-abbd-4abf25c8815a" - ), - }, - { - "id": ( - "37344879-09ce-4cd8-976f-bf1a57c0cfa6" - ), - }, - ], - }, - ], - }, - ], - }, - ], - }, - expected_tables=[ - "prefix", - "prefix__t", - "prefix__t__sub_objects", - "prefix__t__sub_objects__sub_sub_objects", - "prefix__tcatalog", - ], - expected_values={ - "prefix__t__sub_objects": ( - ["__id", "id", "sub_objects__o", "sub_objects__id"], - [ - ( - "1", - "b096504a-3d54-4664-9bf5-1b872466fd66", - "1", - "2b94c631-fca9-4892-a730-03ee529ffe2a", - ), - ( - "2", - "b096504a-3d54-4664-9bf5-1b872466fd66", - "2", - "b5d8cdc4-9441-487c-90cf-0c7ec97728eb", - ), - ], - ), - "prefix__t__sub_objects__sub_sub_objects": ( - ["__id", "sub_objects__o", "sub_objects__sub_sub_objects__o"], - [ - ("1", "1", "1"), - ("2", "1", "2"), - ("3", "2", "1"), - ("4", "2", "2"), - ], - ), - }, - ) - - def case_indexing_id_like(self) -> QueryCase: - return QueryCase( - json_depth=4, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "otherId": "b096504a-3d54-4664-9bf5-1b872466fd66", - "anIdButWithADifferentEnding": ( - "b096504a-3d54-4664-9bf5-1b872466fd66" - ), - }, - ], - }, - ], - }, - expected_tables=[ - "prefix", - "prefix__t", - "prefix__tcatalog", - ], - expected_values={}, - expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), - ("prefix__t", "id"), - ("prefix__t", "other_id"), - ("prefix__t", "an_id_but_with_a_different_ending"), - ], - ) - - @parametrize(json_depth=range(1, 2)) - def case_drop_raw(self, json_depth: int) -> QueryCase: - return QueryCase( - json_depth=json_depth, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - }, - ], - }, - ], - }, - expected_tables=["prefix__t", "prefix__tcatalog"], - expected_values={ - "prefix__t": ( - ["id", "value"], - [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], - ), - "prefix__tcatalog": (["table_name"], [("prefix__t",)]), - }, - expected_indexes=[ - ("prefix__t", "__id"), - ("prefix__t", "id"), - ], - keep_raw=False, - ) - - # this case should be testing the FolioClient class - # but it isn't setup to mock the data properly right now - def case_null_records(self) -> QueryCase: - return QueryCase( - json_depth=1, - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "b096504a-3d54-4664-9bf5-1b872466fd66", - "value": "value", - }, - None, - ], - }, - ], - }, - expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], - expected_values={}, - expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), - ("prefix__t", "id"), - ], - ) diff --git a/tests/test_cases/to_csv_cases.py b/tests/test_cases/to_csv_cases.py deleted file mode 100644 index baf2d9c..0000000 --- a/tests/test_cases/to_csv_cases.py +++ /dev/null @@ -1,100 +0,0 @@ -from dataclasses import dataclass -from pathlib import Path - -from .base import EndToEndTestCase - -_SAMPLE_PATH = Path() / "tests" / "test_cases" / "to_csv_samples" - - -@dataclass(frozen=True) -class ToCsvCase(EndToEndTestCase): - expected_csvs: list[tuple[str, Path]] - - -class ToCsvCases: - def case_basic(self) -> ToCsvCase: - return ToCsvCase( - values={"prefix": [{"purchaseOrders": [{"id": "id", "val": "value"}]}]}, - expected_csvs=[("prefix__t", _SAMPLE_PATH / "basic.csv")], - ) - - def case_datatypes(self) -> ToCsvCase: - return ToCsvCase( - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "id", - "string": "string", - "integer": 1, - "numeric": 1.1, - "boolean": True, - "uuid": "6a31a12a-9570-405c-af20-6abf2992859c", - }, - ], - }, - ], - }, - expected_csvs=[("prefix__t", _SAMPLE_PATH / "datatypes.csv")], - ) - - def case_escaped_chars(self) -> ToCsvCase: - return ToCsvCase( - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "id", - "comma": "Double, double toil and trouble", - "doubleQuote": 'Cry "Havoc!" a horse', - "newLine": """To be -or not -to be""", - "singleQuote": "Cry 'Havoc!' a horse", - }, - { - "id": "id", - "comma": "Z", - "doubleQuote": "Z", - "newLine": "Z", - "singleQuote": "Z", - }, - ], - }, - ], - }, - expected_csvs=[("prefix__t", _SAMPLE_PATH / "escaped_chars.csv")], - ) - - def case_sorting(self) -> ToCsvCase: - return ToCsvCase( - values={ - "prefix": [ - { - "purchaseOrders": [ - { - "id": "id", - "C": "YY", - "B": "XX", - "A": "ZZ", - }, - { - "id": "id", - "C": "Y", - "B": "XX", - "A": "ZZ", - }, - { - "id": "id", - "C": "Y", - "B": "X", - "A": "Z", - }, - ], - }, - ], - }, - expected_csvs=[("prefix__t", _SAMPLE_PATH / "sorting.csv")], - ) diff --git a/tests/test_drop_tables.py b/tests/test_drop_tables.py new file mode 100644 index 0000000..a0d1d42 --- /dev/null +++ b/tests/test_drop_tables.py @@ -0,0 +1,172 @@ +from collections.abc import Callable +from contextlib import closing +from dataclasses import dataclass +from typing import TYPE_CHECKING, cast +from unittest import mock +from unittest.mock import MagicMock + +import duckdb +import psycopg +import pytest +from pytest_cases import parametrize, parametrize_with_cases + +from .mock_response_case import Call, MockedResponseTestCase + +if TYPE_CHECKING: + from _typeshed import dbapi + + import ldlite + + +@dataclass(frozen=True) +class DropTablesTC(MockedResponseTestCase): + drop: str + expected_tables: list[str] + + +@parametrize(keep_raw=[True, False]) +def case_one_table(keep_raw: bool) -> DropTablesTC: + return DropTablesTC( + Call( + "prefix", + returns={"purchaseOrders": [{"id": "1"}]}, + keep_raw=keep_raw, + ), + drop="prefix", + expected_tables=[], + ) + + +@parametrize(keep_raw=[True, False]) +def case_two_tables(keep_raw: bool) -> DropTablesTC: + return DropTablesTC( + Call( + "prefix", + returns={ + "purchaseOrders": [ + { + "id": "1", + "subObjects": [{"id": "2"}, {"id": "3"}], + }, + ], + }, + keep_raw=keep_raw, + ), + drop="prefix", + expected_tables=[], + ) + + +@parametrize(keep_raw=[True, False]) +def case_separate_table(keep_raw: bool) -> DropTablesTC: + expected_tables = [ + "notdropped__t", + "notdropped__tcatalog", + ] + if keep_raw: + expected_tables = ["notdropped", *expected_tables] + + return DropTablesTC( + [ + Call( + "prefix", + returns={"purchaseOrders": [{"id": "1"}]}, + keep_raw=keep_raw, + ), + Call( + "notdropped", + returns={"purchaseOrders": [{"id": "1"}]}, + keep_raw=keep_raw, + ), + ], + drop="prefix", + expected_tables=expected_tables, + ) + + +def _arrange( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: DropTablesTC, +) -> "ldlite.LDLite": + from ldlite import LDLite + + uut = LDLite() + tc.patch_request_get(uut, httpx_post_mock, client_get_mock) + uut.connect_folio("https://doesnt.matter", "", "", "") + return uut + + +def _act(uut: "ldlite.LDLite", tc: DropTablesTC) -> None: + uut.drop_tables(tc.drop) + for call in tc.calls_list: + uut.query(table=call.prefix, path="/patched", keep_raw=call.keep_raw) + uut.drop_tables(tc.drop) + + +def _assert( + conn: "dbapi.DBAPIConnection", + res_schema: str, # TODO: have schema be part of tc + tc: DropTablesTC, +) -> None: + with closing(conn.cursor()) as cur: + cur.execute( + """ + SELECT table_name + FROM information_schema.tables + WHERE table_schema=$1 + """, + (res_schema,), + ) + assert sorted([r[0] for r in cur.fetchall()]) == sorted(tc.expected_tables) + + cur.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + assert (ud := cur.fetchone()) is not None + assert ud[0] == len(tc.calls_list) - 1 + cur.execute( + 'SELECT COUNT(*) FROM "ldlite_system"."load_history" ' + 'WHERE "table_name" = $1', + (tc.drop,), + ) + assert (d := cur.fetchone()) is not None + assert d[0] == 0 + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_duckdb( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: DropTablesTC, +) -> None: + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = f":memory:{tc.db}" + uut.connect_db(dsn) + + _act(uut, tc) + + with duckdb.connect(dsn) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "main", tc) + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_postgres( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + pg_dsn: None | Callable[[str], str], + tc: DropTablesTC, +) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = pg_dsn(tc.db) + uut.connect_db_postgresql(dsn) + + _act(uut, tc) + + with psycopg.connect(dsn, cursor_factory=psycopg.RawCursor) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "public", tc) diff --git a/tests/test_duckdb.py b/tests/test_duckdb.py deleted file mode 100644 index 1c3f8ea..0000000 --- a/tests/test_duckdb.py +++ /dev/null @@ -1,178 +0,0 @@ -from difflib import unified_diff -from pathlib import Path -from typing import Any, cast -from unittest import mock -from unittest.mock import MagicMock - -import duckdb -import pytest -from pytest_cases import parametrize_with_cases - -from tests.test_cases import drop_tables_cases as dtc -from tests.test_cases import load_history_cases as lhc -from tests.test_cases import query_cases as qc -from tests.test_cases import to_csv_cases as csvc - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=dtc.DropTablesCases) -def test_drop_tables( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: dtc.DropTablesCase, -) -> None: - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = f":memory:{tc.db}" - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db(dsn) - ld.drop_tables(tc.drop) - - for prefix in tc.values: - ld.query(table=prefix, path="/patched", keep_raw=tc.keep_raw) - ld.drop_tables(tc.drop) - - with duckdb.connect(dsn) as res: - res.execute( - """ - SELECT table_name - FROM information_schema.tables - WHERE table_schema='main' - """, - ) - assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) - - res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') - assert (ud := res.fetchone()) is not None - assert ud[0] == len(tc.values) - 1 - res.execute( - 'SELECT COUNT(*) FROM "ldlite_system"."load_history" ' - 'WHERE "table_name" = $1', - (tc.drop,), - ) - assert (d := res.fetchone()) is not None - assert d[0] == 0 - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=qc.QueryTestCases) -def test_query( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: qc.QueryCase, -) -> None: - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = f":memory:{tc.db}" - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db(dsn) - - for prefix in tc.values: - ld.query( - table=prefix, - path="/patched", - json_depth=tc.json_depth, - keep_raw=tc.keep_raw, - ) - - with duckdb.connect(dsn) as res: - res.execute( - """ - SELECT table_name - FROM information_schema.tables - WHERE table_schema='main' - """, - ) - assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) - - for table, (cols, values) in tc.expected_values.items(): - with duckdb.connect(dsn) as res: - res.execute(f"SELECT {'::text,'.join(cols)}::text FROM {table};") - for v in values: - assert res.fetchone() == v - - assert res.fetchone() is None - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=csvc.ToCsvCases) -def test_to_csv( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: csvc.ToCsvCase, - tmpdir: str, -) -> None: - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = f":memory:{tc.db}" - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db(dsn) - - for prefix in tc.values: - ld.query(table=prefix, path="/patched") - - for table, expected in tc.expected_csvs: - actual = (Path(tmpdir) / table).with_suffix(".csv") - - ld.export_csv(str(actual), table) - - with expected.open("r") as f: - expected_lines = f.readlines() - with actual.open("r") as f: - actual_lines = f.readlines() - - diff = list(unified_diff(expected_lines, actual_lines)) - if len(diff) > 0: - pytest.fail("".join(diff)) - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=lhc.LoadHistoryTestCases) -def test_history( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: lhc.LoadHistoryCase, -) -> None: - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = f":memory:{tc.db}" - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db(dsn) - - for prefix, calls in cast( - "dict[str, list[list[dict[str, Any]]]]", - tc.values, - ).items(): - for i in range(len(calls)): - ld.query( - table=prefix, - path="/patched", - query=tc.queries[prefix][i], - ) - - with duckdb.connect(dsn) as res: - res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') - assert (ud := res.fetchone()) is not None - assert ud[0] == len(tc.expected_loads) - - for tn, (q, t) in tc.expected_loads.items(): - res.execute( - 'SELECT * FROM "ldlite_system"."load_history" WHERE "table_name" = $1', - (tn,), - ) - assert (d := res.fetchone()) is not None - assert d[1] == q - assert d[7] == t - assert d[6] > d[5] > d[4] > d[3] > d[2] diff --git a/tests/test_endtoend.py b/tests/test_endtoend.py index d8aada2..6768101 100644 --- a/tests/test_endtoend.py +++ b/tests/test_endtoend.py @@ -1,82 +1,166 @@ -from dataclasses import astuple -from typing import cast +from collections.abc import Callable +from contextlib import closing +from dataclasses import astuple, dataclass +from typing import TYPE_CHECKING, cast +from uuid import uuid4 import pytest from httpx_folio.factories import FolioParams, default_client_factory from httpx_folio.query import QueryParams, QueryType -from pytest_cases import parametrize - - -@parametrize( - tc=[ - # no id column - (True, "/finance/ledger-rollovers-logs", None), - # finicky about sorting - (True, "/notes", "title=Key Permissions"), - # id descending - (False, "/invoice/invoices", "vendorId==e0* sortBy id desc"), - # non id sort - (False, "/groups", "cql.allRecords=1 sortBy group desc"), - ], -) -def test_endtoend( - folio_params: tuple[bool, FolioParams], - tc: tuple[bool, str, QueryType], -) -> None: - (non_snapshot_data, endpoint, query) = tc - if non_snapshot_data and folio_params[0]: - pytest.skip( - "Specify an environment having data with --folio-base-url to run", - ) - - from ldlite import LDLite as uut - - ld = uut() - db = ld.connect_db() - - ld.page_size = 3 - ld.connect_folio(*astuple(folio_params[1])) - ld.query(table="test", path=endpoint, query=query) # type:ignore[arg-type] - - with default_client_factory(folio_params[1])() as client: - res = client.get( - endpoint, - params=QueryParams(query).stats(), - ) - res.raise_for_status() - - expected = res.json()["totalRecords"] - assert expected > 3 - - db.execute("SELECT COUNT(DISTINCT COLUMNS(*)) FROM test__t;") - actual = cast("tuple[int]", db.fetchone())[0] - - assert actual == expected - - -@parametrize( - srs=[ - "/source-storage/records", - "/source-storage/stream/records", - "/source-storage/source-records", - "/source-storage/stream/source-records", - ], -) -def test_endtoend_srs(folio_params: tuple[bool, FolioParams], srs: str) -> None: - from ldlite import LDLite as uut - - ld = uut() - db = ld.connect_db() - - ld.connect_folio(*astuple(folio_params[1])) - ld.query(table="test", path=srs, limit=10) - - db.execute("SELECT COUNT(DISTINCT COLUMNS(*)) FROM test__t;") - actual = cast("tuple[int]", db.fetchone())[0] - - # snapshot a variable number of records - assert actual >= 1 - if folio_params[0]: - assert actual <= 10 - else: - assert actual == 10 +from pytest_cases import parametrize, parametrize_with_cases + +if TYPE_CHECKING: + import ldlite + + +@dataclass(frozen=True) +class NonSrsCase: + snapshot_ok: bool + path: str + query: str | dict[str, str] | None + + +class NonSrsCases: + def case_no_id_col(self) -> NonSrsCase: + return NonSrsCase(False, "/finance/ledger-rollovers-logs", None) + + def case_finicky_sorting(self) -> NonSrsCase: + return NonSrsCase(False, "/notes", "title=Key Permissions") + + def case_id_descending(self) -> NonSrsCase: + return NonSrsCase(True, "/invoice/invoices", "vendorId==e0* sortBy id desc") + + def case_non_id_sort(self) -> NonSrsCase: + return NonSrsCase(True, "/groups", "cql.allRecords=1 sortBy group desc") + + +SrsCases = [ + "/source-storage/records", + "/source-storage/stream/records", + "/source-storage/source-records", + "/source-storage/stream/source-records", +] + + +class TestIntegration: + def _arrange( + self, + folio_params: tuple[bool, FolioParams], + snapshot_ok: bool = True, + ) -> "ldlite.LDLite": + if not snapshot_ok and folio_params[0]: + pytest.skip( + "Specify an environment having data with --folio-base-url to run", + ) + + from ldlite import LDLite + + uut = LDLite() + uut.page_size = 3 + uut.connect_folio(*astuple(folio_params[1])) + return uut + + def _nonsrs_assert( + self, + uut: "ldlite.LDLite", + folio_params: tuple[bool, FolioParams], + tc: NonSrsCase, + ) -> None: + with default_client_factory(folio_params[1])() as client: + res = client.get( + tc.path, + params=QueryParams(cast("QueryType", tc.query)).stats(), + ) + res.raise_for_status() + + expected = res.json()["totalRecords"] + assert expected > 3 + + if uut.db is None: + pytest.fail("No active database connection.") + + with closing(uut.db.cursor()) as cur: + cur.execute("SELECT COUNT(*) FROM (SELECT DISTINCT * FROM test__t) t;") + actual = cast("tuple[int]", cur.fetchone())[0] + + assert actual == expected + + @parametrize_with_cases("tc", cases=NonSrsCases) + def test_nonsrs_duckdb( + self, + folio_params: tuple[bool, FolioParams], + tc: NonSrsCase, + ) -> None: + uut = self._arrange(folio_params, tc.snapshot_ok) + uut.connect_db() + + uut.query(table="test", path=tc.path, query=tc.query) + self._nonsrs_assert(uut, folio_params, tc) + + @parametrize_with_cases("tc", cases=NonSrsCases) + def test_nonsrs_postgres( + self, + folio_params: tuple[bool, FolioParams], + pg_dsn: None | Callable[[str], str], + tc: NonSrsCase, + ) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + uut = self._arrange(folio_params, tc.snapshot_ok) + db = "db" + str(uuid4()).split("-")[0] + print(db) # noqa: T201 + dsn = pg_dsn(db) + uut.connect_db_postgresql(dsn) + + uut.query(table="test", path=tc.path, query=tc.query) + + self._nonsrs_assert(uut, folio_params, tc) + + def _srs_assert(self, uut: "ldlite.LDLite", is_snapshot: bool) -> None: + if uut.db is None: + pytest.fail("No active database connection.") + + with closing(uut.db.cursor()) as cur: + cur.execute("SELECT COUNT(*) FROM (SELECT DISTINCT * FROM test__t) t;") + actual = cast("tuple[int]", cur.fetchone())[0] + + # snapshot has a variable number of records + assert actual >= 1 + if is_snapshot: + assert actual <= 10 + else: + assert actual == 10 + + @parametrize(path=SrsCases) + def test_srs_duckdb( + self, + folio_params: tuple[bool, FolioParams], + path: str, + ) -> None: + uut = self._arrange(folio_params) + uut.connect_db() + + uut.query(table="test", path=path, limit=10) + + self._srs_assert(uut, folio_params[0]) + + @parametrize(path=SrsCases) + def test_srs_postgres( + self, + folio_params: tuple[bool, FolioParams], + pg_dsn: None | Callable[[str], str], + path: str, + ) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + uut = self._arrange(folio_params) + db = "db" + str(uuid4()).split("-")[0] + print(db) # noqa: T201 + dsn = pg_dsn(db) + uut.connect_db_postgresql(dsn) + + uut.query(table="test", path=path, limit=10) + + self._srs_assert(uut, folio_params[0]) diff --git a/tests/test_export_csv.py b/tests/test_export_csv.py new file mode 100644 index 0000000..55aaae2 --- /dev/null +++ b/tests/test_export_csv.py @@ -0,0 +1,171 @@ +from collections.abc import Callable +from dataclasses import dataclass +from difflib import unified_diff +from pathlib import Path +from typing import TYPE_CHECKING +from unittest import mock +from unittest.mock import MagicMock + +import pytest +from pytest_cases import parametrize_with_cases + +from .mock_response_case import Call, MockedResponseTestCase + +if TYPE_CHECKING: + import ldlite + +_SAMPLE_PATH = Path() / "tests" / "export_csv_samples" + + +@dataclass(frozen=True) +class ExportCsvTC(MockedResponseTestCase): + expected_csvs: list[tuple[str, Path]] + + +def case_basic() -> ExportCsvTC: + return ExportCsvTC( + Call("prefix", returns={"purchaseOrders": [{"id": "id", "val": "value"}]}), + expected_csvs=[("prefix__t", _SAMPLE_PATH / "basic.csv")], + ) + + +def case_datatypes() -> ExportCsvTC: + return ExportCsvTC( + Call( + "prefix", + returns={ + "purchaseOrders": [ + { + "id": "id", + "string": "string", + "integer": 1, + "numeric": 1.1, + "boolean": True, + "uuid": "6a31a12a-9570-405c-af20-6abf2992859c", + }, + ], + }, + ), + expected_csvs=[("prefix__t", _SAMPLE_PATH / "datatypes.csv")], + ) + + +def case_escaped_chars() -> ExportCsvTC: + return ExportCsvTC( + Call( + "prefix", + returns={ + "purchaseOrders": [ + { + "id": "id", + "comma": "Double, double toil and trouble", + "doubleQuote": 'Cry "Havoc!" a horse', + "newLine": """To be +or not +to be""", + "singleQuote": "Cry 'Havoc!' a horse", + }, + { + "id": "id", + "comma": "Z", + "doubleQuote": "Z", + "newLine": "Z", + "singleQuote": "Z", + }, + ], + }, + ), + expected_csvs=[("prefix__t", _SAMPLE_PATH / "escaped_chars.csv")], + ) + + +def case_sorting() -> ExportCsvTC: + return ExportCsvTC( + Call( + "prefix", + returns={ + "purchaseOrders": [ + {"id": "id", "C": "YY", "B": "XX", "A": "ZZ"}, + {"id": "id", "C": "Y", "B": "XX", "A": "ZZ"}, + {"id": "id", "C": "Y", "B": "X", "A": "Z"}, + ], + }, + ), + expected_csvs=[("prefix__t", _SAMPLE_PATH / "sorting.csv")], + ) + + +def _arrange( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: ExportCsvTC, +) -> "ldlite.LDLite": + from ldlite import LDLite + + uut = LDLite() + tc.patch_request_get(uut, httpx_post_mock, client_get_mock) + uut.connect_folio("https://doesnt.matter", "", "", "") + return uut + + +def _act(uut: "ldlite.LDLite", tc: ExportCsvTC) -> None: + for call in tc.calls_list: + uut.query(table=call.prefix, path="/patched") + + +def _assert( + uut: "ldlite.LDLite", + tc: ExportCsvTC, + tmpdir: str, +) -> None: + for table, expected in tc.expected_csvs: + actual = (Path(tmpdir) / table).with_suffix(".csv") + + uut.export_csv(str(actual), table) + + with expected.open("r") as f: + expected_lines = f.readlines() + with actual.open("r") as f: + actual_lines = f.readlines() + + diff = list(unified_diff(expected_lines, actual_lines)) + if len(diff) > 0: + pytest.fail("".join(diff)) + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_duckdb( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: ExportCsvTC, + tmpdir: str, +) -> None: + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = f":memory:{tc.db}" + uut.connect_db(dsn) + + _act(uut, tc) + _assert(uut, tc, tmpdir) + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_postgres( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + pg_dsn: None | Callable[[str], str], + tc: ExportCsvTC, + tmpdir: str, +) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = pg_dsn(tc.db) + uut.connect_db_postgresql(dsn) + + _act(uut, tc) + _assert(uut, tc, tmpdir) diff --git a/tests/test_load_history.py b/tests/test_load_history.py new file mode 100644 index 0000000..1db5f34 --- /dev/null +++ b/tests/test_load_history.py @@ -0,0 +1,179 @@ +from collections.abc import Callable +from contextlib import closing +from dataclasses import dataclass +from typing import TYPE_CHECKING, cast +from unittest import mock +from unittest.mock import MagicMock + +import duckdb +import psycopg +import pytest +from pytest_cases import parametrize, parametrize_with_cases + +from .mock_response_case import Call, MockedResponseTestCase + +if TYPE_CHECKING: + from _typeshed import dbapi + + import ldlite + + +@dataclass(frozen=True) +class LoadHistoryTC(MockedResponseTestCase): + expected_loads: dict[str, tuple[str | None, int]] + + +@parametrize(query=[None, "poline.id=*A"]) +def case_one_load(query: str | None) -> LoadHistoryTC: + return LoadHistoryTC( + Call( + "prefix", + query=query, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + { + "id": "b096504a-9999-4664-9bf5-1b872466fd66", + "value": "value-2", + }, + ], + }, + ), + expected_loads={"prefix": (query, 2)}, + ) + + +def case_schema_load() -> LoadHistoryTC: + return LoadHistoryTC( + Call( + "schema.prefix", + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + { + "id": "b096504a-9999-4664-9bf5-1b872466fd66", + "value": "value-2", + }, + ], + }, + ), + expected_loads={"schema.prefix": (None, 2)}, + ) + + +def case_two_loads() -> LoadHistoryTC: + return LoadHistoryTC( + [ + Call( + "prefix", + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + ], + }, + ), + Call( + "prefix", + query="a query", + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + { + "id": "b096504a-9999-4664-9bf5-1b872466fd66", + "value": "value-2", + }, + ], + }, + ), + ], + expected_loads={"prefix": ("a query", 2)}, + ) + + +def _arrange( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: LoadHistoryTC, +) -> "ldlite.LDLite": + from ldlite import LDLite + + uut = LDLite() + tc.patch_request_get(uut, httpx_post_mock, client_get_mock) + uut.connect_folio("https://doesnt.matter", "", "", "") + return uut + + +def _act(uut: "ldlite.LDLite", tc: LoadHistoryTC) -> None: + for call in tc.calls_list: + uut.query(table=call.prefix, path="/patched", query=call.query) + + +def _assert( + conn: "dbapi.DBAPIConnection", + tc: LoadHistoryTC, +) -> None: + with closing(conn.cursor()) as cur: + cur.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + assert (ud := cur.fetchone()) is not None + assert ud[0] == len(tc.expected_loads) + + for tn, (q, t) in tc.expected_loads.items(): + cur.execute( + 'SELECT * FROM "ldlite_system"."load_history" WHERE "table_name" = $1', + (tn,), + ) + assert (d := cur.fetchone()) is not None + assert d[1] == q + assert d[7] == t + assert d[6] > d[5] > d[4] > d[3] > d[2] + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_duckdb( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: LoadHistoryTC, +) -> None: + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = f":memory:{tc.db}" + uut.connect_db(dsn) + + _act(uut, tc) + with duckdb.connect(dsn) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), tc) + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_postgres( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + pg_dsn: None | Callable[[str], str], + tc: LoadHistoryTC, +) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = pg_dsn(tc.db) + uut.connect_db_postgresql(dsn) + + _act(uut, tc) + + with psycopg.connect(dsn, cursor_factory=psycopg.RawCursor) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), tc) diff --git a/tests/test_postgres.py b/tests/test_postgres.py deleted file mode 100644 index 1489869..0000000 --- a/tests/test_postgres.py +++ /dev/null @@ -1,240 +0,0 @@ -import contextlib -from collections.abc import Callable -from difflib import unified_diff -from pathlib import Path -from typing import Any, cast -from unittest import mock -from unittest.mock import MagicMock - -import psycopg -import pytest -from psycopg import sql -from pytest_cases import parametrize_with_cases - -from tests.test_cases import drop_tables_cases as dtc -from tests.test_cases import load_history_cases as lhc -from tests.test_cases import query_cases as qc -from tests.test_cases import to_csv_cases as csvc - - -@pytest.fixture(scope="session") -def pg_dsn(pytestconfig: pytest.Config) -> None | Callable[[str], str]: - host = pytestconfig.getoption("pg_host") - if host is None: - return None - - def setup(db: str) -> str: - base_dsn = f"host={host} user=ldlite password=ldlite" - with contextlib.closing(psycopg.connect(base_dsn)) as base_conn: - base_conn.autocommit = True - with base_conn.cursor() as curr: - curr.execute( - sql.SQL("CREATE DATABASE {db};").format(db=sql.Identifier(db)), - ) - - return base_dsn + f" dbname={db}" - - return setup - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=dtc.DropTablesCases) -def test_drop_tables( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - pg_dsn: None | Callable[[str], str], - tc: dtc.DropTablesCase, -) -> None: - if pg_dsn is None: - pytest.skip("Specify the pg host using --pg-host to run") - - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = pg_dsn(tc.db) - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db_postgresql(dsn) - ld.drop_tables(tc.drop) - - for prefix in tc.values: - ld.query(table=prefix, path="/patched", keep_raw=tc.keep_raw) - ld.drop_tables(tc.drop) - - with psycopg.connect(dsn) as conn, conn.cursor() as res: - res.execute( - """ - SELECT table_name - FROM information_schema.tables - WHERE table_schema='public' - """, - ) - assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) - - res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') - assert (ud := res.fetchone()) is not None - assert ud[0] == len(tc.values) - 1 - res.execute( - 'SELECT COUNT(*) FROM "ldlite_system"."load_history"' - 'WHERE "table_name" = %s', - (tc.drop,), - ) - assert (d := res.fetchone()) is not None - assert d[0] == 0 - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=qc.QueryTestCases) -def test_query( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - pg_dsn: None | Callable[[str], str], - tc: qc.QueryCase, -) -> None: - if pg_dsn is None: - pytest.skip("Specify the pg host using --pg-host to run") - - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = pg_dsn(tc.db) - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db_postgresql(dsn) - - for prefix in tc.values: - ld.query( - table=prefix, - path="/patched", - json_depth=tc.json_depth, - keep_raw=tc.keep_raw, - ) - - with psycopg.connect(dsn) as conn: - with conn.cursor() as res: - res.execute( - """ - SELECT table_name - FROM information_schema.tables - WHERE table_schema='public' - """, - ) - assert sorted([r[0] for r in res.fetchall()]) == sorted(tc.expected_tables) - - for table, (cols, values) in tc.expected_values.items(): - with conn.cursor() as res: - res.execute( - sql.SQL("SELECT {cols}::text FROM {table};").format( - cols=sql.SQL("::text, ").join( - [sql.Identifier(c) for c in cols], - ), - table=sql.Identifier(table), - ), - ) - for v in values: - assert res.fetchone() == v - - assert res.fetchone() is None - - if tc.expected_indexes is not None: - with conn.cursor() as res: - res.execute( - "SELECT COUNT(*) FROM pg_indexes WHERE schemaname = 'public';", - ) - assert cast("tuple[int]", res.fetchone())[0] == len(tc.expected_indexes) - - for t, c in tc.expected_indexes: - # this requires specific formatting to match the postgres strings - res.execute(f""" -SELECT COUNT(*) FROM pg_indexes -WHERE indexdef LIKE 'CREATE INDEX % ON public.{t} USING btree ({c})'; - """) - assert cast("tuple[int]", res.fetchone())[0] == 1, f"{t}, {c}" - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=csvc.ToCsvCases) -def test_to_csv( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - pg_dsn: None | Callable[[str], str], - tc: csvc.ToCsvCase, - tmpdir: str, -) -> None: - if pg_dsn is None: - pytest.skip("Specify the pg host using --pg-host to run") - - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = pg_dsn(tc.db) - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db_postgresql(dsn) - - for prefix in tc.values: - ld.query(table=prefix, path="/patched") - - for table, expected in tc.expected_csvs: - actual = (Path(tmpdir) / table).with_suffix(".csv") - - ld.export_csv(str(actual), table) - - with expected.open("r") as f: - expected_lines = f.readlines() - with actual.open("r") as f: - actual_lines = f.readlines() - - diff = list(unified_diff(expected_lines, actual_lines)) - if len(diff) > 0: - pytest.fail("".join(diff)) - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=lhc.LoadHistoryTestCases) -def test_history( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - pg_dsn: None | Callable[[str], str], - tc: lhc.LoadHistoryCase, -) -> None: - if pg_dsn is None: - pytest.skip("Specify the pg host using --pg-host to run") - - from ldlite import LDLite as uut - - ld = uut() - tc.patch_request_get(ld, httpx_post_mock, client_get_mock) - dsn = pg_dsn(tc.db) - ld.connect_folio("https://doesnt.matter", "", "", "") - ld.connect_db_postgresql(dsn) - - for prefix, calls in cast( - "dict[str, list[list[dict[str, Any]]]]", - tc.values, - ).items(): - for i in range(len(calls)): - ld.query( - table=prefix, - path="/patched", - query=tc.queries[prefix][i], - ) - - with psycopg.connect(dsn) as conn, conn.cursor() as res: - res.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') - assert (ud := res.fetchone()) is not None - assert ud[0] == len(tc.expected_loads) - - for tn, (q, t) in tc.expected_loads.items(): - res.execute( - 'SELECT * FROM "ldlite_system"."load_history" WHERE "table_name" = %s', - (tn,), - ) - assert (d := res.fetchone()) is not None - assert d[1] == q - assert d[7] == t - assert d[6] > d[5] > d[4] > d[3] > d[2] diff --git a/tests/test_query.py b/tests/test_query.py new file mode 100644 index 0000000..fbc8ceb --- /dev/null +++ b/tests/test_query.py @@ -0,0 +1,698 @@ +import json +from collections.abc import Callable +from contextlib import closing +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, cast +from unittest import mock +from unittest.mock import MagicMock + +import duckdb +import psycopg +import pytest +from psycopg import sql +from pytest_cases import parametrize, parametrize_with_cases + +from .mock_response_case import Call, MockedResponseTestCase + +if TYPE_CHECKING: + from _typeshed import dbapi + + import ldlite + + +@dataclass(frozen=True) +class QueryTC(MockedResponseTestCase): + expected_tables: list[str] + expected_values: dict[str, tuple[list[str], list[tuple[Any, ...]]]] + expected_indexes: list[tuple[str, str]] | None = None + + +@parametrize(json_depth=range(1, 2)) +def case_one_table(json_depth: int) -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=json_depth, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + ], + }, + ), + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + ["id", "value"], + [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], + ), + "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ], + ) + + +@parametrize(json_depth=range(2, 3)) +def case_two_tables(json_depth: int) -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=json_depth, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + "subObjects": [ + { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value-1", + }, + { + "id": "f5bda109-a719-4f72-b797-b9c22f45e4e1", + "value": "sub-value-2", + }, + ], + }, + ], + }, + ), + expected_tables=[ + "prefix", + "prefix__t", + "prefix__t__sub_objects", + "prefix__tcatalog", + ], + expected_values={ + "prefix__t": ( + ["id", "value"], + [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], + ), + "prefix__t__sub_objects": ( + ["id", "sub_objects__id", "sub_objects__value"], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "sub-value-1", + ), + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "f5bda109-a719-4f72-b797-b9c22f45e4e1", + "sub-value-2", + ), + ], + ), + "prefix__tcatalog": ( + ["table_name"], + [("prefix__t",), ("prefix__t__sub_objects",)], + ), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ("prefix__t__sub_objects", "__id"), + ("prefix__t__sub_objects", "id"), + ("prefix__t__sub_objects", "sub_objects__o"), + ("prefix__t__sub_objects", "sub_objects__id"), + ], + ) + + +@parametrize(json_depth=range(1)) +def case_table_no_expansion(json_depth: int) -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=json_depth, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + "subObjects": [ + { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value", + }, + ], + }, + ], + }, + ), + expected_tables=["prefix"], + expected_values={}, + ) + + +def case_table_underexpansion() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=2, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "subObjects": [ + { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value", + "subSubObjects": [ + { + "id": ("2b94c631-fca9-4892-a730-03ee529ffe2a"), + "value": "sub-sub-value", + }, + ], + }, + ], + }, + ], + }, + ), + expected_tables=[ + "prefix", + "prefix__t", + "prefix__t__sub_objects", + "prefix__tcatalog", + ], + expected_values={ + "prefix__t__sub_objects": ( + [ + "id", + "sub_objects__id", + "sub_objects__value", + ], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "sub-value", + ), + ], + ), + "prefix__tcatalog": ( + ["table_name"], + [("prefix__t",), ("prefix__t__sub_objects",)], + ), + }, + ) + + +@parametrize(json_depth=range(3, 4)) +def case_three_tables(json_depth: int) -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=json_depth, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + "subObjects": [ + { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value", + "subSubObjects": [ + { + "id": ("2b94c631-fca9-4892-a730-03ee529ffe2a"), + "value": "sub-sub-value", + }, + ], + }, + ], + }, + ], + }, + ), + expected_tables=[ + "prefix", + "prefix__t", + "prefix__t__sub_objects", + "prefix__t__sub_objects__sub_sub_objects", + "prefix__tcatalog", + ], + expected_values={ + "prefix__t__sub_objects__sub_sub_objects": ( + [ + "id", + "sub_objects__id", + "sub_objects__sub_sub_objects__id", + "sub_objects__sub_sub_objects__value", + ], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "sub-sub-value", + ), + ], + ), + "prefix__tcatalog": ( + ["table_name"], + [ + ("prefix__t",), + ("prefix__t__sub_objects",), + ("prefix__t__sub_objects__sub_sub_objects",), + ], + ), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ("prefix__t__sub_objects", "__id"), + ("prefix__t__sub_objects", "id"), + ("prefix__t__sub_objects", "sub_objects__o"), + ("prefix__t__sub_objects", "sub_objects__id"), + ("prefix__t__sub_objects__sub_sub_objects", "__id"), + ("prefix__t__sub_objects__sub_sub_objects", "id"), + ("prefix__t__sub_objects__sub_sub_objects", "sub_objects__o"), + ("prefix__t__sub_objects__sub_sub_objects", "sub_objects__id"), + ( + "prefix__t__sub_objects__sub_sub_objects", + "sub_objects__sub_sub_objects__o", + ), + ( + "prefix__t__sub_objects__sub_sub_objects", + "sub_objects__sub_sub_objects__id", + ), + ], + ) + + +def case_nested_object() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=2, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + "subObject": { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value", + }, + }, + ], + }, + ), + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + ["id", "value", "sub_object__id", "sub_object__value"], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "value", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "sub-value", + ), + ], + ), + "prefix__tcatalog": ( + ["table_name"], + [("prefix__t",)], + ), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ("prefix__t", "sub_object__id"), + ], + ) + + +def case_doubly_nested_object() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=3, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + "subObject": { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value", + "subSubObject": { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-sub-value", + }, + }, + }, + ], + }, + ), + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + [ + "id", + "value", + "sub_object__id", + "sub_object__sub_sub_object__id", + "sub_object__sub_sub_object__value", + ], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "value", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "sub-sub-value", + ), + ], + ), + "prefix__tcatalog": ( + ["table_name"], + [("prefix__t",)], + ), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ("prefix__t", "sub_object__id"), + ("prefix__t", "sub_object__sub_sub_object__id"), + ], + ) + + +def case_nested_object_underexpansion() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=1, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + "subObject": { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value", + }, + }, + ], + }, + ), + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + ["id", "value", "sub_object"], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "value", + json.dumps( + { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "value": "sub-value", + }, + indent=4, + ), + ), + ], + ), + "prefix__tcatalog": ( + ["table_name"], + [("prefix__t",)], + ), + }, + ) + + +def case_id_generation() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=4, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "subObjects": [ + { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "subSubObjects": [ + { + "id": ("2b94c631-fca9-4892-a730-03ee529ffe2a"), + }, + { + "id": ("8516a913-8bf7-55a4-ab71-417aba9171c9"), + }, + ], + }, + { + "id": "b5d8cdc4-9441-487c-90cf-0c7ec97728eb", + "subSubObjects": [ + { + "id": ("13a24cc8-a15c-4158-abbd-4abf25c8815a"), + }, + { + "id": ("37344879-09ce-4cd8-976f-bf1a57c0cfa6"), + }, + ], + }, + ], + }, + ], + }, + ), + expected_tables=[ + "prefix", + "prefix__t", + "prefix__t__sub_objects", + "prefix__t__sub_objects__sub_sub_objects", + "prefix__tcatalog", + ], + expected_values={ + "prefix__t__sub_objects": ( + ["__id", "id", "sub_objects__o", "sub_objects__id"], + [ + ( + "1", + "b096504a-3d54-4664-9bf5-1b872466fd66", + "1", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + ), + ( + "2", + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2", + "b5d8cdc4-9441-487c-90cf-0c7ec97728eb", + ), + ], + ), + "prefix__t__sub_objects__sub_sub_objects": ( + ["__id", "sub_objects__o", "sub_objects__sub_sub_objects__o"], + [ + ("1", "1", "1"), + ("2", "1", "2"), + ("3", "2", "1"), + ("4", "2", "2"), + ], + ), + }, + ) + + +def case_indexing_id_like() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=4, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "otherId": "b096504a-3d54-4664-9bf5-1b872466fd66", + "anIdButWithADifferentEnding": ( + "b096504a-3d54-4664-9bf5-1b872466fd66" + ), + }, + ], + }, + ), + expected_tables=[ + "prefix", + "prefix__t", + "prefix__tcatalog", + ], + expected_values={}, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ("prefix__t", "other_id"), + ("prefix__t", "an_id_but_with_a_different_ending"), + ], + ) + + +@parametrize(json_depth=range(1, 2)) +def case_drop_raw(json_depth: int) -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=json_depth, + keep_raw=False, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + ], + }, + ), + expected_tables=["prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + ["id", "value"], + [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], + ), + "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + }, + expected_indexes=[ + ("prefix__t", "__id"), + ("prefix__t", "id"), + ], + ) + + +# this case should be testing the FolioClient class +# but it isn't setup to mock the data properly right now +def case_null_records() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=1, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + None, + ], + }, + ), + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={}, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ], + ) + + +def _arrange( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: QueryTC, +) -> "ldlite.LDLite": + from ldlite import LDLite + + uut = LDLite() + tc.patch_request_get(uut, httpx_post_mock, client_get_mock) + uut.connect_folio("https://doesnt.matter", "", "", "") + return uut + + +def _act(uut: "ldlite.LDLite", tc: QueryTC) -> None: + for call in tc.calls_list: + uut.query( + table=call.prefix, + path="/patched", + json_depth=call.json_depth, + keep_raw=call.keep_raw, + ) + + +def _assert( + conn: "dbapi.DBAPIConnection", + res_schema: str, # TODO: have schema be part of tc + tc: QueryTC, +) -> None: + with closing(conn.cursor()) as cur: + cur.execute( + """ + SELECT table_name + FROM information_schema.tables + WHERE table_schema=$1 + """, + (res_schema,), + ) + assert sorted([r[0] for r in cur.fetchall()]) == sorted(tc.expected_tables) + + for table, (cols, values) in tc.expected_values.items(): + cur.execute( + sql.SQL("SELECT {cols}::text FROM {table};") + .format( + cols=sql.SQL("::text, ").join( + [sql.Identifier(c) for c in cols], + ), + table=sql.Identifier(table), + ) + .as_string(), + ) + for v in values: + assert cur.fetchone() == v + + assert cur.fetchone() is None + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_duckdb( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + tc: QueryTC, +) -> None: + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = f":memory:{tc.db}" + uut.connect_db(dsn) + + _act(uut, tc) + + with duckdb.connect(dsn) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "main", tc) + + +@mock.patch("httpx_folio.auth.httpx.post") +@mock.patch("httpx_folio.factories.httpx.Client.get") +@parametrize_with_cases("tc", cases=".") +def test_postgres( + client_get_mock: MagicMock, + httpx_post_mock: MagicMock, + pg_dsn: None | Callable[[str], str], + tc: QueryTC, +) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + uut = _arrange(client_get_mock, httpx_post_mock, tc) + dsn = pg_dsn(tc.db) + uut.connect_db_postgresql(dsn) + + _act(uut, tc) + + with psycopg.connect(dsn, cursor_factory=psycopg.RawCursor) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "public", tc) From 177ee4dbc1fdda29d3bb4242c9865abeade8d985 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Wed, 24 Sep 2025 18:12:43 +0000 Subject: [PATCH 06/25] Dont track scanning time separately --- src/ldlite/__init__.py | 4 +--- src/ldlite/_database/__init__.py | 6 +----- src/ldlite/_jsonx.py | 10 ++++------ tests/test_load_history.py | 4 ++-- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 3e3c4e1..938ce8e 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -336,14 +336,13 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 ), ) download = datetime.now(timezone.utc) - scan = datetime.now(timezone.utc) self._db.drop_extracted_tables(prefix) newtables = [table] newattrs = {} if json_depth > 0: autocommit(self.db, self.dbtype, False) - (jsontables, jsonattrs, scan) = transform_json( + (jsontables, jsonattrs) = transform_json( self.db, self.dbtype, table, @@ -410,7 +409,6 @@ def close(self) -> None: ... query if query and isinstance(query, str) else None, start, download, - scan, transformed, index, processed, diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py index b287c79..a3115a3 100644 --- a/src/ldlite/_database/__init__.py +++ b/src/ldlite/_database/__init__.py @@ -69,7 +69,6 @@ class LoadHistory: query: str | None start: datetime.datetime download: datetime.datetime - scan: datetime.datetime transform: datetime.datetime index: datetime.datetime total: int @@ -106,7 +105,6 @@ def __init__(self, conn_factory: Callable[[], DB]): ,"query" TEXT ,"start_utc" TIMESTAMP ,"download_complete_utc" TIMESTAMP - ,"scan_complete_utc" TIMESTAMP ,"transformation_complete_utc" TIMESTAMP ,"index_complete_utc" TIMESTAMP ,"row_count" INTEGER @@ -237,12 +235,11 @@ def record_history(self, history: LoadHistory) -> None: with closing(self._conn_factory()) as conn, conn.cursor() as cur: cur.execute( """ -INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7,$8) +INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7) ON CONFLICT ("table_name") DO UPDATE SET "query" = EXCLUDED."query" ,"start_utc" = EXCLUDED."start_utc" ,"download_complete_utc" = EXCLUDED."download_complete_utc" - ,"scan_complete_utc" = EXCLUDED."scan_complete_utc" ,"transformation_complete_utc" = EXCLUDED."transformation_complete_utc" ,"index_complete_utc" = EXCLUDED."index_complete_utc" ,"row_count" = EXCLUDED."row_count" @@ -252,7 +249,6 @@ def record_history(self, history: LoadHistory) -> None: history.query, history.start.astimezone(timezone.utc), history.download.astimezone(timezone.utc), - history.scan.astimezone(timezone.utc), history.transform.astimezone(timezone.utc), history.index.astimezone(timezone.utc), history.total, diff --git a/src/ldlite/_jsonx.py b/src/ldlite/_jsonx.py index d96b69c..ed327e8 100644 --- a/src/ldlite/_jsonx.py +++ b/src/ldlite/_jsonx.py @@ -1,6 +1,5 @@ import json import uuid -from datetime import datetime, timezone from typing import TYPE_CHECKING, Literal, Union import duckdb @@ -408,7 +407,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 total: int, quiet: bool, max_depth: int, -) -> tuple[list[str], dict[str, dict[str, Attr]], datetime]: +) -> tuple[list[str], dict[str, dict[str, Attr]]]: # Scan all fields for JSON data # First get a list of the string attributes str_attrs: list[str] = [] @@ -421,7 +420,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 cur.close() # Scan data for JSON objects if len(str_attrs) == 0: - return [], {}, datetime.now(timezone.utc) + return [], {} json_attrs: list[str] = [] json_attrs_set: set[str] = set() newattrs: dict[str, dict[str, Attr]] = {} @@ -512,7 +511,6 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 finally: cur.close() db.commit() - scan = datetime.now(timezone.utc) # Set all row IDs to 1 row_ids = {} for t in newattrs: @@ -520,7 +518,7 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 # Run transformation # Select only JSON columns if len(json_attrs) == 0: - return [], {}, scan + return [], {} cur = server_cursor(db, dbtype) try: cur.execute( @@ -610,4 +608,4 @@ def transform_json( # noqa: C901, PLR0912, PLR0913, PLR0915 finally: cur.close() db.commit() - return sorted([*list(newattrs.keys()), tcatalog]), newattrs, scan + return sorted([*list(newattrs.keys()), tcatalog]), newattrs diff --git a/tests/test_load_history.py b/tests/test_load_history.py index 1db5f34..98a7e3e 100644 --- a/tests/test_load_history.py +++ b/tests/test_load_history.py @@ -136,8 +136,8 @@ def _assert( ) assert (d := cur.fetchone()) is not None assert d[1] == q - assert d[7] == t - assert d[6] > d[5] > d[4] > d[3] > d[2] + assert d[6] == t + assert d[5] > d[4] > d[3] > d[2] @mock.patch("httpx_folio.auth.httpx.post") From 6997b430a835274e39dbd26e69dc9a3ce049ee68 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Fri, 26 Sep 2025 19:05:30 +0000 Subject: [PATCH 07/25] Raise minimum version of duckdb to 0.9 --- pylock.maximal.toml | 40 +++++++------ pylock.minimal.toml | 138 +++++++++++++++++++++++--------------------- pylock.toml | 97 ++++++++++++++++--------------- pyproject.toml | 4 +- 4 files changed, 145 insertions(+), 134 deletions(-) diff --git a/pylock.maximal.toml b/pylock.maximal.toml index 3323bb4..49c1df7 100644 --- a/pylock.maximal.toml +++ b/pylock.maximal.toml @@ -493,22 +493,24 @@ dependencies = [ [[packages]] name = "ruamel-yaml-clib" -version = "0.2.13" +version = "0.2.14" requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.13.tar.gz", url = "https://files.pythonhosted.org/packages/3c/fd/32c91c4d301ebe7931a3c44f7593650613afe14854e3cc9d2764321b7a46/ruamel.yaml.clib-0.2.13.tar.gz", hashes = {sha256 = "8d4f8d7853053a5a19171a0f515f1e14f503bd3e772c4da6bafe7d0893d4f299"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/30/b5/3bff051bfdc33f8d797a1a025a1dc74fb13703611917f611e62e12061893/ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "817a3d8dbbefc337e9081d9bddd54ee6ef5d5351cccb5240d731d604c1d86d29"}}, - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/51/a3/8f199f9d6ff862b503eae06a4a9ec9f20fc232ee7590287d969ebf5a8859/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "b29e3a746dd774a49ec6412529dc6a7338efe0828230b7c5da2aef3ee6eb7cbc"}}, - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/fb/47728a32be2e7ac00f854d30b0d39ed62e9eefdff19c024f4e5c49d3341c/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bae8383e02ef5a7c6b44a594746dcdb0994b8bdf4317d2fba3bbafe8262dfa9d"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/9a/21de96f5fc51e495f6ebe87f01a679ec3b9a36082431942d7dc7295175da/ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "b3dae045e57780a6ec39a018220d82931d6cb3e6e8b326a9a804597ffa6f8520"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/26/4203139b2f1fc94b01e5fb5c2e9a5822725baad930ceb869e3525157f1b1/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "f6d476bc7bb9b25d54133f95d0766aaf1662689f6c26e9e08d28a45609a634f2"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/16/db/ec371bb692c404ad1cfad715b89300cca841a4ac31ed3467c66a5911ce01/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5622265f2b64f6933a29a5d8e33385a0c3ef47f509354602d0c28f5d7d126fe3"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/cb/71/230119917102ea682c6a1fa2e322ca18cdd4077342680908999e18fd84cc/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b2ba05d2dbe39435915aa20d53336d55fd0fa6c25eb1c580d60fc1f753e40a41"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/2d/22afc8402474285fc9bf35cb630f6194aecb2c777b304f872dada19ab06c/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",hashes = {sha256 = "a5a43fc6f95c58c1a65cbb7b68b31f9721362e10c5276d3f8db4ccde8e9acb04"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c9/c7/928d0692ac05bb0f05b337e151da28792f25782ae0e2cda1a5bf0dda9dde/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "5ce7178bd66cffe4eb4ce40c2ff525f42ccfa6e2e31eeea27293fe5bd0ae2d93"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b2/2972fae8d9dc10314e39c254638320e1b028511185cebaa96f3382122f40/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "490c5dfaf9f218f335f2f6f7ba52f7ce5460e94d67a42c8dd0096deae7684d23"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/89/e3/fc6c145f7d122a39793f9a8e508ba060a3bc5883065f3f11dbc9011023bd/ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",hashes = {sha256 = "b5e32adbb14ffdb1130c699128070766e5cf781b3b05dd87049c16bb94395212"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/95/e5/6cb4654b62b90116962d88cb74419caa3eb5fc50ccbc932d5553adf70812/ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",hashes = {sha256 = "826ce141d368f10a99a4fc6fab332ba4203f63da25828853d7957e76d13f7d41"}}, +sdist = {name = "ruamel.yaml.clib-0.2.14.tar.gz", url = "https://files.pythonhosted.org/packages/d8/e9/39ec4d4b3f91188fad1842748f67d4e749c77c37e353c4e545052ee8e893/ruamel.yaml.clib-0.2.14.tar.gz", hashes = {sha256 = "803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e"}} +wheels = [ + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/21/e2/a59ff65c26aaf21a24eb38df777cb9af5d87ba8fc8107c163c2da9d1e85e/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "7df6f6e9d0e33c7b1d435defb185095386c469109de723d514142632a7b9d07f"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6b/fa/3234f913fe9a6525a7b97c6dad1f51e72b917e6872e051a5e2ffd8b16fbb/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "70eda7703b8126f5e52fcf276e6c0f40b0d314674f896fc58c47b0aef2b9ae83"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/ec/4edbf17ac2c87fa0845dd366ef8d5852b96eb58fcd65fc1ecf5fe27b4641/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "a0cb71ccc6ef9ce36eecb6272c81afdc2f565950cdcec33ae8e6cd8f7fc86f27"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/18/b0e1fafe59051de9e79cdd431863b03593ecfa8341c110affad7c8121efc/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e7cb9ad1d525d40f7d87b6df7c0ff916a66bc52cb61b66ac1b2a16d0c1b07640"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/d7/ae/e3811f05415594025e96000349d3400978adaed88d8f98d494352d9761ee/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/06/7d51f4688d6d72bb72fa74254e1593c4f5ebd0036be5b41fe39315b275e9/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/08/b4499234a420ef42960eeb05585df5cc7eb25ccb8c980490b079e6367050/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/ba/1975a27dedf1c4c33306ee67c948121be8710b19387aada29e2f139c43ee/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/20/15/8a19a13d27f3bd09fa18813add8380a29115a47b553845f08802959acbce/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/19/ee/8d6146a079ad21e534b5083c9ee4a4c8bec42f79cf87594b60978286b39a/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a9/f5/426b714abdc222392e68f3b8ad323930d05a214a27c7e7a0f06c69126401/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",hashes = {sha256 = "f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",hashes = {sha256 = "090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78"}}, ] marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and python_version >= \"3.13\" and \"lint\" in dependency_groups" @@ -530,11 +532,11 @@ dependencies = [] [[packages]] name = "anyio" -version = "4.10.0" +version = "4.11.0" requires-python = ">=3.9" -sdist = {name = "anyio-4.10.0.tar.gz", url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hashes = {sha256 = "3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}} +sdist = {name = "anyio-4.11.0.tar.gz", url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hashes = {sha256 = "82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}} wheels = [ - {name = "anyio-4.10.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl",hashes = {sha256 = "60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}}, + {name = "anyio-4.11.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl",hashes = {sha256 = "0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -643,7 +645,7 @@ marker = "sys_platform == \"win32\" and python_version >= \"3.13\" and \"default dependencies = [] [tool.pdm] -hashes = {sha256 = "f41cee4895442b905a0fa8fe84189c460dff00eec403795e10a6ff2120675686"} +hashes = {sha256 = "a3b22dcb6e46e060513881b655a5824b61606a56fcce33d669d58321ed9c947f"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.minimal.toml b/pylock.minimal.toml index c1512f5..4cc3ad0 100644 --- a/pylock.minimal.toml +++ b/pylock.minimal.toml @@ -106,27 +106,26 @@ dependencies = [] [[packages]] name = "duckdb" -version = "0.7.1" -sdist = {name = "duckdb-0.7.1.tar.gz", url = "https://files.pythonhosted.org/packages/17/1f/50d7128d768910e7d1304476144fa75e5ee477bc5ce55c517418a7aa89aa/duckdb-0.7.1.tar.gz", hashes = {sha256 = "a7db6da0366b239ea1e4541fcc19556b286872f5015c9a54c2e347146e25a2ad"}} -wheels = [ - {name = "duckdb-0.7.1-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/f0/50/b18438bd9b50613c77085b49d63c2220d40959dac157c87e1af396209c55/duckdb-0.7.1-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "54606dfd24d7181d3098030ca6858f6be52f3ccbf42fff05f7587f2d9cdf4343"}}, - {name = "duckdb-0.7.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/0a/56/69188b534126e6492d7bb99db84734690c12d05e29d362c8def9d169732e/duckdb-0.7.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "bd9367ae650b6605ffe00412183cf0edb688a5fc9fbb03ed757e8310e7ec3b6c"}}, - {name = "duckdb-0.7.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e9/68/6a34414619ac36b8f8e88bf6ea83b54f2966e4d948d199ec9b733c4716f6/duckdb-0.7.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "aaf33aeb543c7816bd915cd10141866d54f92f698e1b5712de9d8b7076da19df"}}, - {name = "duckdb-0.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/3f/f3/8fe095ceead5bbc3c15fd92322d4c20f2fefccac2cee32777303c6b396e0/duckdb-0.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "2e56b0329c38c0356b40449917bab6fce6ac27d356257b9a9da613d2a0f064e0"}}, - {name = "duckdb-0.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/25/d6/adf293922cc3bbf03de6efa4f15f773d3ccb0a84fb2aec902a25e6d924b5/duckdb-0.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "604b8b476d6cc6bf91625d8c2722ef9c50c402b3d64bc518c838d6c279e6d93b"}}, - {name = "duckdb-0.7.1-cp311-cp311-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/6d/f9/a8561235b2796fc5d616254c2f614c8ebb362c18480b37b8abe74631874c/duckdb-0.7.1-cp311-cp311-musllinux_1_1_i686.whl",hashes = {sha256 = "32a268508c6d7fdc99d5442736051de74c28a5166c4cc3dcbbf35d383299b941"}}, - {name = "duckdb-0.7.1-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/e0/37/165030849faf8c123c8c7393260ed7779bd8a0ac60d57bb61f72fafaadab/duckdb-0.7.1-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "90794406fa2111414877ee9db154fef940911f3920c312c1cf69947621737c8d"}}, - {name = "duckdb-0.7.1-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/7c/65/8114a523f9d369c7ba0b1aba9ac5695357767568f080b5fde4c5d3b1a502/duckdb-0.7.1-cp311-cp311-win32.whl",hashes = {sha256 = "bf20c5ee62cbbf10b39ebdfd70d454ce914e70545c7cb6cb78cb5befef96328a"}}, - {name = "duckdb-0.7.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a0/0e/97a3f1d717bb4969b9a6fe86c7c3e2c4050d36a5d992a5a8dcbfb00da867/duckdb-0.7.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "bb2700785cab37cd1e7a76c4547a5ab0f8a7c28ad3f3e4d02a8fae52be223090"}}, - {name = "duckdb-0.7.1-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/17/4c/49928ee4b0b7a4ac5466f8caa2b0b6d51b8547bcea9692ffac0bf1948f1f/duckdb-0.7.1-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "3e0170be6cc315c179169dfa3e06485ef7009ef8ce399cd2908f29105ef2c67b"}}, - {name = "duckdb-0.7.1-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/08/4a/180fa637efc60e89cfdfa38103dfce03dfead171db05bd75a0b8f18ae0c8/duckdb-0.7.1-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "6360d41023e726646507d5479ba60960989a09f04527b36abeef3643c61d8c48"}}, - {name = "duckdb-0.7.1-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/9b/85c6c8262a76196218fd9fff36e2f59ea04dcc5773ff5e296c79f4053951/duckdb-0.7.1-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "578c269d7aa27184e8d45421694f89deda3f41fe6bd2a8ce48b262b9fc975326"}}, - {name = "duckdb-0.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/5f/db/dbfddb1c320b593a3539ec698a20a5741ddcc1acb81d5dd19a485f815633/duckdb-0.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "36aae9a923c9f78da1cf3fcf75873f62d32ea017d4cef7c706d16d3eca527ca2"}}, - {name = "duckdb-0.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/72/808bf4a16321fc92abf5a14cd67338466bd14e21e3397f61c93cb3b5139c/duckdb-0.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "630e0122a02f19bb1fafae00786350b2c31ae8422fce97c827bd3686e7c386af"}}, - {name = "duckdb-0.7.1-cp310-cp310-musllinux_1_1_i686.whl",url = "https://files.pythonhosted.org/packages/22/ea/ccc3f7082d8a1b8627107d612988a7dc6a44b70862c10728f3e8d5e23b3a/duckdb-0.7.1-cp310-cp310-musllinux_1_1_i686.whl",hashes = {sha256 = "9b9ca2d294725e523ce207bc37f28787478ae6f7a223e2cf3a213a2d498596c3"}}, - {name = "duckdb-0.7.1-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/a0/3d/931fd20729506f5c83fa5f3e58df960d4f378440d7a8bef736f1508869a4/duckdb-0.7.1-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "0bd89f388205b6c99b62650169efe9a02933555ee1d46ddf79fbd0fb9e62652b"}}, - {name = "duckdb-0.7.1-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/e3/ad/068cd08e8aa30f10e480a2ce323709293b83e75c0b66c6be0a42c313abdc/duckdb-0.7.1-cp310-cp310-win32.whl",hashes = {sha256 = "a9e987565a268fd8da9f65e54621d28f39c13105b8aee34c96643074babe6d9c"}}, - {name = "duckdb-0.7.1-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1e/2d/a45ef237d190e9811a4461afea431f56a99032a7204a74aee23d4598e6bc/duckdb-0.7.1-cp310-cp310-win_amd64.whl",hashes = {sha256 = "5d986b5ad1307b069309f9707c0c5051323e29865aefa059eb6c3b22dc9751b6"}}, +version = "0.9.2" +requires-python = ">=3.7.0" +sdist = {name = "duckdb-0.9.2.tar.gz", url = "https://files.pythonhosted.org/packages/5d/ca/cabff918b84235618710cafb2f45d7ee84b4224c131b16db4c69f2cd1ef9/duckdb-0.9.2.tar.gz", hashes = {sha256 = "3843afeab7c3fc4a4c0b53686a4cc1d9cdbdadcbb468d60fef910355ecafd447"}} +wheels = [ + {name = "duckdb-0.9.2-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/2f/92/8b2b73603efd6eec2db9b6d0a087a2005c357798963ed16595b38aa2e03d/duckdb-0.9.2-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "061a9ea809811d6e3025c5de31bc40e0302cfb08c08feefa574a6491e882e7e8"}}, + {name = "duckdb-0.9.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/32/2d/63769dcd6a35e639a7a3e0a8e9f14a14c180cc31605d62b9d283098ab2d8/duckdb-0.9.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "a43f93be768af39f604b7b9b48891f9177c9282a408051209101ff80f7450d8f"}}, + {name = "duckdb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d7/de/134a8310d18166f1ceb915038259bc0a0bb538d5f4d5a43bfc9632282486/duckdb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "ac29c8c8f56fff5a681f7bf61711ccb9325c5329e64f23cb7ff31781d7b50773"}}, + {name = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/21/92/07e21a3ec8ca88ab0e0ceaa87818a3e2dc9f2f93c1da9d34131828fc325f/duckdb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "b14d98d26bab139114f62ade81350a5342f60a168d94b27ed2c706838f949eda"}}, + {name = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/f9/71/cc6be43546540a7b480734be2e1822f31d51d7d3112ead13ffe0f8cf364d/duckdb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "796a995299878913e765b28cc2b14c8e44fae2f54ab41a9ee668c18449f5f833"}}, + {name = "duckdb-0.9.2-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/6e/f8088f2fd623e6a48846c3dd9adde67f520cee7ff4393d22a05be9c93d87/duckdb-0.9.2-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "6cb64ccfb72c11ec9c41b3cb6181b6fd33deccceda530e94e1c362af5f810ba1"}}, + {name = "duckdb-0.9.2-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/c7/79/12c98e0caf0b9231ec498f568afafddca67af8a6851f4583415ebd0febfd/duckdb-0.9.2-cp311-cp311-win32.whl",hashes = {sha256 = "930740cb7b2cd9e79946e1d3a8f66e15dc5849d4eaeff75c8788d0983b9256a5"}}, + {name = "duckdb-0.9.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a6/7a/e15904563fa63d7d3cc542a697377486ddea8ba4914810391812ffefc9b1/duckdb-0.9.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "c28f13c45006fd525001b2011cdf91fa216530e9751779651e66edc0e446be50"}}, + {name = "duckdb-0.9.2-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/c1/a2/82dfe2b377bbed986a20611775dae98cc31f5d9a47f378df039c3c66ae1f/duckdb-0.9.2-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "aadcea5160c586704c03a8a796c06a8afffbefefb1986601104a60cb0bfdb5ab"}}, + {name = "duckdb-0.9.2-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/7e/61/1708bbd29d04164b295ddedf2e30ecd82be4edac9babd0b45dfa268380e3/duckdb-0.9.2-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "08215f17147ed83cbec972175d9882387366de2ed36c21cbe4add04b39a5bcb4"}}, + {name = "duckdb-0.9.2-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/53/d7/ee3abe18d69db7beca6d47b95ede600a64a529a9e1a237bb4fcce37d74ea/duckdb-0.9.2-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "ee6c2a8aba6850abef5e1be9dbc04b8e72a5b2c2b67f77892317a21fae868fe7"}}, + {name = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/ec/ac/67f340d936a2754c64aa20d3b0bcee01a6ce195820b2794c9acbe2601a44/duckdb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "1ff49f3da9399900fd58b5acd0bb8bfad22c5147584ad2427a78d937e11ec9d0"}}, + {name = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/7c/d5/7688cdc1b57c9ada17b6f6143a923606294b462e4b15e3ac249c04649bde/duckdb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "dd5ac5baf8597efd2bfa75f984654afcabcd698342d59b0e265a0bc6f267b3f0"}}, + {name = "duckdb-0.9.2-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/ea/8e/a22bad5f552468190f1aafa2618a38e4a2f2d595a09660bc257613a97458/duckdb-0.9.2-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "81c6df905589a1023a27e9712edb5b724566587ef280a0c66a7ec07c8083623b"}}, + {name = "duckdb-0.9.2-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/40/39/6cb9719ff3ccd2fab7eb5f1524377d428c2af5128c13d594ca54aaddc3fa/duckdb-0.9.2-cp310-cp310-win32.whl",hashes = {sha256 = "a298cd1d821c81d0dec8a60878c4b38c1adea04a9675fb6306c8f9083bbf314d"}}, + {name = "duckdb-0.9.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1c/95/b0abc7155dda6fe7ac60a4493fe7b62228e6c54ff8c5ef8ffe9bb14bb499/duckdb-0.9.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "492a69cd60b6cb4f671b51893884cdc5efc4c3b2eb76057a007d2a2295427173"}}, ] marker = "\"default\" in dependency_groups" @@ -620,49 +619,54 @@ dependencies = [ [[packages]] name = "ruamel-yaml-clib" -version = "0.2.13" +version = "0.2.14" requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.13.tar.gz", url = "https://files.pythonhosted.org/packages/3c/fd/32c91c4d301ebe7931a3c44f7593650613afe14854e3cc9d2764321b7a46/ruamel.yaml.clib-0.2.13.tar.gz", hashes = {sha256 = "8d4f8d7853053a5a19171a0f515f1e14f503bd3e772c4da6bafe7d0893d4f299"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/30/b5/3bff051bfdc33f8d797a1a025a1dc74fb13703611917f611e62e12061893/ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "817a3d8dbbefc337e9081d9bddd54ee6ef5d5351cccb5240d731d604c1d86d29"}}, - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/51/a3/8f199f9d6ff862b503eae06a4a9ec9f20fc232ee7590287d969ebf5a8859/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "b29e3a746dd774a49ec6412529dc6a7338efe0828230b7c5da2aef3ee6eb7cbc"}}, - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/fb/47728a32be2e7ac00f854d30b0d39ed62e9eefdff19c024f4e5c49d3341c/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bae8383e02ef5a7c6b44a594746dcdb0994b8bdf4317d2fba3bbafe8262dfa9d"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/9a/21de96f5fc51e495f6ebe87f01a679ec3b9a36082431942d7dc7295175da/ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "b3dae045e57780a6ec39a018220d82931d6cb3e6e8b326a9a804597ffa6f8520"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/26/4203139b2f1fc94b01e5fb5c2e9a5822725baad930ceb869e3525157f1b1/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "f6d476bc7bb9b25d54133f95d0766aaf1662689f6c26e9e08d28a45609a634f2"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/16/db/ec371bb692c404ad1cfad715b89300cca841a4ac31ed3467c66a5911ce01/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5622265f2b64f6933a29a5d8e33385a0c3ef47f509354602d0c28f5d7d126fe3"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/cb/71/230119917102ea682c6a1fa2e322ca18cdd4077342680908999e18fd84cc/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b2ba05d2dbe39435915aa20d53336d55fd0fa6c25eb1c580d60fc1f753e40a41"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/2d/22afc8402474285fc9bf35cb630f6194aecb2c777b304f872dada19ab06c/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",hashes = {sha256 = "a5a43fc6f95c58c1a65cbb7b68b31f9721362e10c5276d3f8db4ccde8e9acb04"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c9/c7/928d0692ac05bb0f05b337e151da28792f25782ae0e2cda1a5bf0dda9dde/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "5ce7178bd66cffe4eb4ce40c2ff525f42ccfa6e2e31eeea27293fe5bd0ae2d93"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b2/2972fae8d9dc10314e39c254638320e1b028511185cebaa96f3382122f40/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "490c5dfaf9f218f335f2f6f7ba52f7ce5460e94d67a42c8dd0096deae7684d23"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/89/e3/fc6c145f7d122a39793f9a8e508ba060a3bc5883065f3f11dbc9011023bd/ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",hashes = {sha256 = "b5e32adbb14ffdb1130c699128070766e5cf781b3b05dd87049c16bb94395212"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/95/e5/6cb4654b62b90116962d88cb74419caa3eb5fc50ccbc932d5553adf70812/ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",hashes = {sha256 = "826ce141d368f10a99a4fc6fab332ba4203f63da25828853d7957e76d13f7d41"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/ae/b6b3ed185206af04c779eec77a4a57587278b713b72034957d127307bbef/ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "810500056a0e294131042eca6687a786e82aad817e8e0bc5ce059d2f95b67fef"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/6f/2b/b0307fc587cebabd8faaaeb1476c825fe4dbb5ad2b5c152dfbcc31b258c4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "f8e44b1b583f93a8f4d00e5285d9ea8ccd9524cdd4c54788db2880a11f21287d"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/a9/2ddad6eb03195206aca765b4ff7bd7098c46fbc65957d5ac53f96ef8d6f4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "4d1ab027be86f7d5ccc9b777a22194fd3850012df413f216bf1608768b4daa2f"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/42/a0/ded38d60fc34f69afef6f3e379f896a80d34532bb6b4828e95f7003be610/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "55f01d82d7d96213f0963609876ae841c81e217985c668100c5fb95cc9a564b3"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/3e/49/121067d5621a77913dc0fd473bdf2ec4a515c564806b107d3b1257cd5b14/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",hashes = {sha256 = "031c7cdd5751cda19ddf90e42756ec2ee72a30791c2f65f5f800f9ee929862f0"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/fc/0845929db1840eec6aa6133b8c89941e251c3bc67180aee7d71a30bc1c80/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "ba745411caabc994963729663a7c2d09398795c36dc4b5672ca4fdc445ab6544"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d6/0a/dd0007d41a321edf64c4bda0aab70936281ee213406e6913105499f7d62a/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fb90267cc3748858236b9cedb580191be1d0d218f6cde64e954fa759d90fb08d"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/93/0d/eeed0a9824b14fa089a82247fca96de6b202af84e4093ba2a15afc0b4cb9/ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",hashes = {sha256 = "5188c3212c10fcd14a6de8ce787c0713a49fc5972054703f790cfd9f1d27a90b"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/45/c882a32e4b5c0ed6a5b4e0933af427fef48f3aad7259b87f38e33ee20536/ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",hashes = {sha256 = "518b13f9fe601a559a759f3d21cdb2590cb85611934a7c0f09c09dc1a869ec83"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/86/fa6be53f11d1c663a261d137d616bbb326cb937b361a55a00cacf9ba76aa/ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "825a7483da63b9448fdad9778269a5d02e5f64040aa8326fec071e830c2fc49c"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/f1/d26dbf3c53befd01d8b341cb29c555c1e910ef29478b4ebd50d1d67fbc64/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "54707e2200b9e1c34a62af09edd3ea3469a722951365311398458abe36ff45d6"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a8/80/119ce9e40690b7e0dfc6bec41369333593f8738fa4f58dbbffdb9b80339b/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "958b1fc6334cd745db7099a69da4f60503cfbbc05ce1412b1d06c5922cd8314b"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/0b/85/09625df6b3ccf0ae0ddc93c0ab4d89f785debc0ae1e7efa541696b788b6a/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d50c415df5ba918c483a2486a90dd5a3e6df634fca688f71d266e15a618d643f"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/e0/2e/c05050760b20fe10cb17b3fe7efd5d5653baefa862121f5b0825418f3d8b/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "bbdb57e57a5bb3510bfb43496bab44857546c56c7f04bb7bfd0b248388d41c2e"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d7/e0/6cfd5c61070f0e5556a724c753919b8758b86fe89f5b53eb9f53d0506b27/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "df8ef03eb60fc2e1c0570612363091898b97a7b3181422e1b34c3ee22d7e0a9e"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/85/01/14964bd94bbe809497d1affc0625e428803cc9fd21e145b1b2edcbbc3c92/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "89168de27694f7903a1317381525efdf7ea2c377b5b1eeeb927940870a7e8945"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/1d/c0/a39cc7de38b5acc81241dda9888ecabc1ee90fb3ebf9189ddfc65c08555d/ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",hashes = {sha256 = "8cdb4c720137bb7834cf2c09753d5f3468023eebb7f6ad2604ddf920328753dd"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1f/7f/d5c1e0279df8dd9ca92138bec8387a07112d97598f668ccb3190d0bc06aa/ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",hashes = {sha256 = "670d8a9c5b22af152863236b7a7fec471aafefc5e89b637b8f98d280cb92a0ce"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/73/88/8d40634f34fd206be8aab060537890ae939f67d3598718426be62493e4fe/ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "a67efad34e15232f03333d4a7cc96b1db8ecb676439b6a3db10d49ffbd3a8606"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/3b/25/9deabe6323318acb61e521e6fdcc92575af7f5d4f716def8c42d0cb0d6b2/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "ce8be9ce9c967a9952e92d9280d18de9ae331284645b50dc32f71ef207ef00e1"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/ce/48e9802811c6fe757aae2387e2feb24bf6964fa9a467c26da6c20daea916/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "e16f9611130aa3695aaff32d956e49b45cef902aa15cf9de18ebf919d6acc153"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/28/f6/dff4b9988da26b994f8bb019344ec44b81699f0abf0515040001d6cce8a3/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3a6afcf136a474703e9c7fa62fab76870775c98a4f59f599fdd24348dca3a229"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/81/bd/80fccf71b3387c2fcde566b3d45c827d8380401ee76907e1639ff297f996/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",hashes = {sha256 = "70328e9afcb83deb689547989e6b79fc8f094964b8b754b44a70ba7e68e523fe"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/d6/80134d4c11bd396d438964de26f9d7d9300e35bc2fbdca1584634f262d0a/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "fc2c45c0b5b7845278148f18a4039b6d8fde3f7266dd00986684453a57d3444a"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/99/a4/903a317cbb13071663ad370a4a16e7ba44e62d057352782d760dcd904a72/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fa3c15cefc29ed3f7ad6ac370bd46d8e431d1fa0ba03eb54912e8c5d826e458e"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/b4/7e/c1e1aa7ffb1716db2e9701b9516ec8c4f9a63e7d5cd54b9cced38260f584/ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",hashes = {sha256 = "e9117696191427cd2c5028878b89012e01cee51b2ae8f5dd440a79d6ba4a1011"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f8/1d/067de099bb82c7df5a853989bad5773edf89cc1016a23c6abbcbb28139d2/ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4ba827c038348ebde594788b66a4741ce9606b979b684e3bc1e7d1c11d6ac817"}}, +sdist = {name = "ruamel.yaml.clib-0.2.14.tar.gz", url = "https://files.pythonhosted.org/packages/d8/e9/39ec4d4b3f91188fad1842748f67d4e749c77c37e353c4e545052ee8e893/ruamel.yaml.clib-0.2.14.tar.gz", hashes = {sha256 = "803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e"}} +wheels = [ + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/21/e2/a59ff65c26aaf21a24eb38df777cb9af5d87ba8fc8107c163c2da9d1e85e/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "7df6f6e9d0e33c7b1d435defb185095386c469109de723d514142632a7b9d07f"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6b/fa/3234f913fe9a6525a7b97c6dad1f51e72b917e6872e051a5e2ffd8b16fbb/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "70eda7703b8126f5e52fcf276e6c0f40b0d314674f896fc58c47b0aef2b9ae83"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/ec/4edbf17ac2c87fa0845dd366ef8d5852b96eb58fcd65fc1ecf5fe27b4641/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "a0cb71ccc6ef9ce36eecb6272c81afdc2f565950cdcec33ae8e6cd8f7fc86f27"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/18/b0e1fafe59051de9e79cdd431863b03593ecfa8341c110affad7c8121efc/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e7cb9ad1d525d40f7d87b6df7c0ff916a66bc52cb61b66ac1b2a16d0c1b07640"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/d7/ae/e3811f05415594025e96000349d3400978adaed88d8f98d494352d9761ee/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/06/7d51f4688d6d72bb72fa74254e1593c4f5ebd0036be5b41fe39315b275e9/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/08/b4499234a420ef42960eeb05585df5cc7eb25ccb8c980490b079e6367050/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/ba/1975a27dedf1c4c33306ee67c948121be8710b19387aada29e2f139c43ee/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/20/15/8a19a13d27f3bd09fa18813add8380a29115a47b553845f08802959acbce/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/19/ee/8d6146a079ad21e534b5083c9ee4a4c8bec42f79cf87594b60978286b39a/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a9/f5/426b714abdc222392e68f3b8ad323930d05a214a27c7e7a0f06c69126401/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",hashes = {sha256 = "f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",hashes = {sha256 = "090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/42/ccfb34a25289afbbc42017e4d3d4288e61d35b2e00cfc6b92974a6a1f94b/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "6aeadc170090ff1889f0d2c3057557f9cd71f975f17535c26a5d37af98f19c27"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/82/73/e628a92e80197ff6a79ab81ec3fa00d4cc082d58ab78d3337b7ba7043301/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "5e56ac47260c0eed992789fa0b8efe43404a9adb608608631a948cee4fc2b052"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/c5/346c7094344a60419764b4b1334d9e0285031c961176ff88ffb652405b0c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "a911aa73588d9a8b08d662b9484bc0567949529824a55d3885b77e8dd62a127a"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/99/65080c863eb06d4498de3d6c86f3e90595e02e159fd8529f1565f56cfe2c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a05ba88adf3d7189a974b2de7a9d56731548d35dc0a822ec3dc669caa7019b29"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/3d/e3/0de85f3e3333f8e29e4b10244374a202a87665d1131798946ee22cf05c7c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "fb04c5650de6668b853623eceadcdb1a9f2fee381f5d7b6bc842ee7c239eeec4"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d9/25/0d2f09d8833c7fd77ab8efeff213093c16856479a9d293180a0d89f6bed9/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "df3ec9959241d07bc261f4983d25a1205ff37703faf42b474f15d54d88b4f8c9"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d3/8c/959f10c2e2153cbdab834c46e6954b6dd9e3b109c8f8c0a3cf1618310985/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "fbc08c02e9b147a11dfcaa1ac8a83168b699863493e183f7c0c8b12850b7d259"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/6b/e580a7c18b485e1a5f30a32cda96b20364b0ba649d9d2baaf72f8bd21f83/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c099cafc1834d3c5dac305865d04235f7c21c167c8dd31ebc3d6bbc357e2f023"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/ef/44/3455eebc761dc8e8fdced90f2b0a3fa61e32ba38b50de4130e2d57db0f21/ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",hashes = {sha256 = "b5b0f7e294700b615a3bcf6d28b26e6da94e8eba63b079f4ec92e9ba6c0d6b54"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/76/ab/5121f7f3b651db93de546f8c982c241397aad0a4765d793aca1dac5eadee/ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",hashes = {sha256 = "a37f40a859b503304dd740686359fcf541d6fb3ff7fc10f539af7f7150917c68"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b3/9f/3c51e9578b8c36fcc4bdd271a1a5bb65963a74a4b6ad1a989768a22f6c2a/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5bae1a073ca4244620425cd3d3aa9746bde590992b98ee8c7c8be8c597ca0d4e"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/16/cb02815bc2ae9c66760c0c061d23c7358f9ba51dae95ac85247662b7fbe2/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "0a54e5e40a7a691a426c2703b09b0d61a14294d25cfacc00631aa6f9c964df0d"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/31/c6/fc687cd1b93bff8e40861eea46d6dc1a6a778d9a085684e4045ff26a8e40/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "10d9595b6a19778f3269399eff6bab642608e5966183abc2adbe558a42d4efc9"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/45/5d/65a2bc08b709b08576b3f307bf63951ee68a8e047cbbda6f1c9864ecf9a7/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "dba72975485f2b87b786075e18a6e5d07dc2b4d8973beb2732b9b2816f1bad70"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/fb/d0/a70a03614d9a6788a3661ab1538879ed2aae4e84d861f101243116308a37/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "29757bdb7c142f9595cc1b62ec49a3d1c83fab9cef92db52b0ccebaad4eafb98"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/30/c93fa457611f79946d5cb6cc97493ca5425f3f21891d7b1f9b44eaa1b38e/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "557df28dbccf79b152fe2d1b935f6063d9cc431199ea2b0e84892f35c03bb0ee"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/40/85/e2c54ad637117cd13244a4649946eaa00f32edcb882d1f92df90e079ab00/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "26a8de280ab0d22b6e3ec745b4a5a07151a0f74aad92dd76ab9c8d8d7087720d"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/50/f899072c38877d8ef5382e0b3d47f8c4346226c1f52d6945d6f64fec6a2f/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e501c096aa3889133d674605ebd018471bc404a59cbc17da3c5924421c54d97c"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/99/7c/96d4b5075e30c65ea2064e40c2d657c7c235d7b6ef18751cf89a935b9041/ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",hashes = {sha256 = "915748cfc25b8cfd81b14d00f4bfdb2ab227a30d6d43459034533f4d1c207a2a"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7d/8c/73ee2babd04e8bfcf1fd5c20aa553d18bf0ebc24b592b4f831d12ae46cc0/ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",hashes = {sha256 = "4ccba93c1e5a40af45b2f08e4591969fa4697eae951c708f3f83dcbf9f6c6bb1"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/56/35a0a752415ae01992c68f5a6513bdef0e1b6fbdb60d7619342ce12346a0/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "f8b2acb0ffdd2ce8208accbec2dca4a06937d556fdcaefd6473ba1b5daa7e3c4"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/98/6a/9a68184ab93619f4607ff1675e4ef01e8accfcbff0d482f4ca44c10d8eab/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "aef953f3b8bd0b50bd52a2e52fb54a6a2171a1889d8dea4a5959d46c6624c451"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/3f/cfed5f088628128a9ec66f46794fd4d165642155c7b78c26d83b16c6bf7b/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "a0ac90efbc7a77b0d796c03c8cc4e62fd710b3f1e4c32947713ef2ef52e09543"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/d5/5ce2cc156c1da48160171968d91f066d305840fbf930ee955a509d025a44/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9bf6b699223afe6c7fe9f2ef76e0bfa6dd892c21e94ce8c957478987ade76cd8"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2b/71/d0b56bc902b38ebe4be8e270f730f929eec4edaf8a0fa7028f4ef64fa950/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d73a0187718f6eec5b2f729b0f98e4603f7bd9c48aa65d01227d1a5dcdfbe9e8"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/db/1f37449dd89c540218598316ccafc1a0aed60215e72efa315c5367cfd015/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "81f6d3b19bc703679a5705c6a16dabdc79823c71d791d73c65949be7f3012c02"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/5d/53/c498b30f35efcd9f47cb084d7ad9374f2b907470f73913dec6396b81397d/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "b28caeaf3e670c08cb7e8de221266df8494c169bd6ed8875493fab45be9607a4"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/79/492cfad9baed68914840c39e5f3c1cc251f51a897ddb3f532601215cbb12/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "94f3efb718f8f49b031f2071ec7a27dd20cbfe511b4dfd54ecee54c956da2b31"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/ca/f5/479ebfd5ba396e209ade90f7282d84b90c57b3e07be8dc6fcd02a6df7ffc/ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",hashes = {sha256 = "27c070cf3888e90d992be75dd47292ff9aa17dafd36492812a6a304a1aedc182"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/57/31/a044520fdb3bd409889f67f1efebda0658033c7ab3f390cee37531cc9a9e/ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4f4a150a737fccae13fb51234d41304ff2222e3b7d4c8e9428ed1a6ab48389b8"}}, ] marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and \"lint\" in dependency_groups" @@ -671,11 +675,11 @@ dependencies = [] [[packages]] name = "anyio" -version = "4.10.0" +version = "4.11.0" requires-python = ">=3.9" -sdist = {name = "anyio-4.10.0.tar.gz", url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hashes = {sha256 = "3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}} +sdist = {name = "anyio-4.11.0.tar.gz", url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hashes = {sha256 = "82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}} wheels = [ - {name = "anyio-4.10.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl",hashes = {sha256 = "60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}}, + {name = "anyio-4.11.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl",hashes = {sha256 = "0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}}, ] marker = "\"default\" in dependency_groups" @@ -756,7 +760,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "f41cee4895442b905a0fa8fe84189c460dff00eec403795e10a6ff2120675686"} +hashes = {sha256 = "a3b22dcb6e46e060513881b655a5824b61606a56fcce33d669d58321ed9c947f"} strategy = ["direct_minimal_versions", "inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.toml b/pylock.toml index 150c7d5..742c5f0 100644 --- a/pylock.toml +++ b/pylock.toml @@ -684,49 +684,54 @@ dependencies = [ [[packages]] name = "ruamel-yaml-clib" -version = "0.2.13" +version = "0.2.14" requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.13.tar.gz", url = "https://files.pythonhosted.org/packages/3c/fd/32c91c4d301ebe7931a3c44f7593650613afe14854e3cc9d2764321b7a46/ruamel.yaml.clib-0.2.13.tar.gz", hashes = {sha256 = "8d4f8d7853053a5a19171a0f515f1e14f503bd3e772c4da6bafe7d0893d4f299"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/30/b5/3bff051bfdc33f8d797a1a025a1dc74fb13703611917f611e62e12061893/ruamel.yaml.clib-0.2.13-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "817a3d8dbbefc337e9081d9bddd54ee6ef5d5351cccb5240d731d604c1d86d29"}}, - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/51/a3/8f199f9d6ff862b503eae06a4a9ec9f20fc232ee7590287d969ebf5a8859/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "b29e3a746dd774a49ec6412529dc6a7338efe0828230b7c5da2aef3ee6eb7cbc"}}, - {name = "ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/fb/47728a32be2e7ac00f854d30b0d39ed62e9eefdff19c024f4e5c49d3341c/ruamel.yaml.clib-0.2.13-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bae8383e02ef5a7c6b44a594746dcdb0994b8bdf4317d2fba3bbafe8262dfa9d"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/9a/21de96f5fc51e495f6ebe87f01a679ec3b9a36082431942d7dc7295175da/ruamel.yaml.clib-0.2.13-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "b3dae045e57780a6ec39a018220d82931d6cb3e6e8b326a9a804597ffa6f8520"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/26/4203139b2f1fc94b01e5fb5c2e9a5822725baad930ceb869e3525157f1b1/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "f6d476bc7bb9b25d54133f95d0766aaf1662689f6c26e9e08d28a45609a634f2"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/16/db/ec371bb692c404ad1cfad715b89300cca841a4ac31ed3467c66a5911ce01/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5622265f2b64f6933a29a5d8e33385a0c3ef47f509354602d0c28f5d7d126fe3"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/cb/71/230119917102ea682c6a1fa2e322ca18cdd4077342680908999e18fd84cc/ruamel.yaml.clib-0.2.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b2ba05d2dbe39435915aa20d53336d55fd0fa6c25eb1c580d60fc1f753e40a41"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/2d/22afc8402474285fc9bf35cb630f6194aecb2c777b304f872dada19ab06c/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_1_aarch64.whl",hashes = {sha256 = "a5a43fc6f95c58c1a65cbb7b68b31f9721362e10c5276d3f8db4ccde8e9acb04"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c9/c7/928d0692ac05bb0f05b337e151da28792f25782ae0e2cda1a5bf0dda9dde/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "5ce7178bd66cffe4eb4ce40c2ff525f42ccfa6e2e31eeea27293fe5bd0ae2d93"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b2/2972fae8d9dc10314e39c254638320e1b028511185cebaa96f3382122f40/ruamel.yaml.clib-0.2.13-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "490c5dfaf9f218f335f2f6f7ba52f7ce5460e94d67a42c8dd0096deae7684d23"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/89/e3/fc6c145f7d122a39793f9a8e508ba060a3bc5883065f3f11dbc9011023bd/ruamel.yaml.clib-0.2.13-cp313-cp313-win32.whl",hashes = {sha256 = "b5e32adbb14ffdb1130c699128070766e5cf781b3b05dd87049c16bb94395212"}}, - {name = "ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/95/e5/6cb4654b62b90116962d88cb74419caa3eb5fc50ccbc932d5553adf70812/ruamel.yaml.clib-0.2.13-cp313-cp313-win_amd64.whl",hashes = {sha256 = "826ce141d368f10a99a4fc6fab332ba4203f63da25828853d7957e76d13f7d41"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/ae/b6b3ed185206af04c779eec77a4a57587278b713b72034957d127307bbef/ruamel.yaml.clib-0.2.13-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "810500056a0e294131042eca6687a786e82aad817e8e0bc5ce059d2f95b67fef"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/6f/2b/b0307fc587cebabd8faaaeb1476c825fe4dbb5ad2b5c152dfbcc31b258c4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "f8e44b1b583f93a8f4d00e5285d9ea8ccd9524cdd4c54788db2880a11f21287d"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/a9/2ddad6eb03195206aca765b4ff7bd7098c46fbc65957d5ac53f96ef8d6f4/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "4d1ab027be86f7d5ccc9b777a22194fd3850012df413f216bf1608768b4daa2f"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/42/a0/ded38d60fc34f69afef6f3e379f896a80d34532bb6b4828e95f7003be610/ruamel.yaml.clib-0.2.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "55f01d82d7d96213f0963609876ae841c81e217985c668100c5fb95cc9a564b3"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/3e/49/121067d5621a77913dc0fd473bdf2ec4a515c564806b107d3b1257cd5b14/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_1_aarch64.whl",hashes = {sha256 = "031c7cdd5751cda19ddf90e42756ec2ee72a30791c2f65f5f800f9ee929862f0"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/fc/0845929db1840eec6aa6133b8c89941e251c3bc67180aee7d71a30bc1c80/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "ba745411caabc994963729663a7c2d09398795c36dc4b5672ca4fdc445ab6544"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d6/0a/dd0007d41a321edf64c4bda0aab70936281ee213406e6913105499f7d62a/ruamel.yaml.clib-0.2.13-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fb90267cc3748858236b9cedb580191be1d0d218f6cde64e954fa759d90fb08d"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/93/0d/eeed0a9824b14fa089a82247fca96de6b202af84e4093ba2a15afc0b4cb9/ruamel.yaml.clib-0.2.13-cp312-cp312-win32.whl",hashes = {sha256 = "5188c3212c10fcd14a6de8ce787c0713a49fc5972054703f790cfd9f1d27a90b"}}, - {name = "ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/45/c882a32e4b5c0ed6a5b4e0933af427fef48f3aad7259b87f38e33ee20536/ruamel.yaml.clib-0.2.13-cp312-cp312-win_amd64.whl",hashes = {sha256 = "518b13f9fe601a559a759f3d21cdb2590cb85611934a7c0f09c09dc1a869ec83"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/86/fa6be53f11d1c663a261d137d616bbb326cb937b361a55a00cacf9ba76aa/ruamel.yaml.clib-0.2.13-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "825a7483da63b9448fdad9778269a5d02e5f64040aa8326fec071e830c2fc49c"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/f1/d26dbf3c53befd01d8b341cb29c555c1e910ef29478b4ebd50d1d67fbc64/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "54707e2200b9e1c34a62af09edd3ea3469a722951365311398458abe36ff45d6"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a8/80/119ce9e40690b7e0dfc6bec41369333593f8738fa4f58dbbffdb9b80339b/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "958b1fc6334cd745db7099a69da4f60503cfbbc05ce1412b1d06c5922cd8314b"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/0b/85/09625df6b3ccf0ae0ddc93c0ab4d89f785debc0ae1e7efa541696b788b6a/ruamel.yaml.clib-0.2.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d50c415df5ba918c483a2486a90dd5a3e6df634fca688f71d266e15a618d643f"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/e0/2e/c05050760b20fe10cb17b3fe7efd5d5653baefa862121f5b0825418f3d8b/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "bbdb57e57a5bb3510bfb43496bab44857546c56c7f04bb7bfd0b248388d41c2e"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d7/e0/6cfd5c61070f0e5556a724c753919b8758b86fe89f5b53eb9f53d0506b27/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "df8ef03eb60fc2e1c0570612363091898b97a7b3181422e1b34c3ee22d7e0a9e"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/85/01/14964bd94bbe809497d1affc0625e428803cc9fd21e145b1b2edcbbc3c92/ruamel.yaml.clib-0.2.13-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "89168de27694f7903a1317381525efdf7ea2c377b5b1eeeb927940870a7e8945"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/1d/c0/a39cc7de38b5acc81241dda9888ecabc1ee90fb3ebf9189ddfc65c08555d/ruamel.yaml.clib-0.2.13-cp311-cp311-win32.whl",hashes = {sha256 = "8cdb4c720137bb7834cf2c09753d5f3468023eebb7f6ad2604ddf920328753dd"}}, - {name = "ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1f/7f/d5c1e0279df8dd9ca92138bec8387a07112d97598f668ccb3190d0bc06aa/ruamel.yaml.clib-0.2.13-cp311-cp311-win_amd64.whl",hashes = {sha256 = "670d8a9c5b22af152863236b7a7fec471aafefc5e89b637b8f98d280cb92a0ce"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/73/88/8d40634f34fd206be8aab060537890ae939f67d3598718426be62493e4fe/ruamel.yaml.clib-0.2.13-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "a67efad34e15232f03333d4a7cc96b1db8ecb676439b6a3db10d49ffbd3a8606"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/3b/25/9deabe6323318acb61e521e6fdcc92575af7f5d4f716def8c42d0cb0d6b2/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "ce8be9ce9c967a9952e92d9280d18de9ae331284645b50dc32f71ef207ef00e1"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/ce/48e9802811c6fe757aae2387e2feb24bf6964fa9a467c26da6c20daea916/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "e16f9611130aa3695aaff32d956e49b45cef902aa15cf9de18ebf919d6acc153"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/28/f6/dff4b9988da26b994f8bb019344ec44b81699f0abf0515040001d6cce8a3/ruamel.yaml.clib-0.2.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "3a6afcf136a474703e9c7fa62fab76870775c98a4f59f599fdd24348dca3a229"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/81/bd/80fccf71b3387c2fcde566b3d45c827d8380401ee76907e1639ff297f996/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_1_aarch64.whl",hashes = {sha256 = "70328e9afcb83deb689547989e6b79fc8f094964b8b754b44a70ba7e68e523fe"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/15/d6/80134d4c11bd396d438964de26f9d7d9300e35bc2fbdca1584634f262d0a/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "fc2c45c0b5b7845278148f18a4039b6d8fde3f7266dd00986684453a57d3444a"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/99/a4/903a317cbb13071663ad370a4a16e7ba44e62d057352782d760dcd904a72/ruamel.yaml.clib-0.2.13-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fa3c15cefc29ed3f7ad6ac370bd46d8e431d1fa0ba03eb54912e8c5d826e458e"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/b4/7e/c1e1aa7ffb1716db2e9701b9516ec8c4f9a63e7d5cd54b9cced38260f584/ruamel.yaml.clib-0.2.13-cp310-cp310-win32.whl",hashes = {sha256 = "e9117696191427cd2c5028878b89012e01cee51b2ae8f5dd440a79d6ba4a1011"}}, - {name = "ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f8/1d/067de099bb82c7df5a853989bad5773edf89cc1016a23c6abbcbb28139d2/ruamel.yaml.clib-0.2.13-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4ba827c038348ebde594788b66a4741ce9606b979b684e3bc1e7d1c11d6ac817"}}, +sdist = {name = "ruamel.yaml.clib-0.2.14.tar.gz", url = "https://files.pythonhosted.org/packages/d8/e9/39ec4d4b3f91188fad1842748f67d4e749c77c37e353c4e545052ee8e893/ruamel.yaml.clib-0.2.14.tar.gz", hashes = {sha256 = "803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e"}} +wheels = [ + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/21/e2/a59ff65c26aaf21a24eb38df777cb9af5d87ba8fc8107c163c2da9d1e85e/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "7df6f6e9d0e33c7b1d435defb185095386c469109de723d514142632a7b9d07f"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6b/fa/3234f913fe9a6525a7b97c6dad1f51e72b917e6872e051a5e2ffd8b16fbb/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "70eda7703b8126f5e52fcf276e6c0f40b0d314674f896fc58c47b0aef2b9ae83"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/ec/4edbf17ac2c87fa0845dd366ef8d5852b96eb58fcd65fc1ecf5fe27b4641/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "a0cb71ccc6ef9ce36eecb6272c81afdc2f565950cdcec33ae8e6cd8f7fc86f27"}}, + {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/18/b0e1fafe59051de9e79cdd431863b03593ecfa8341c110affad7c8121efc/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e7cb9ad1d525d40f7d87b6df7c0ff916a66bc52cb61b66ac1b2a16d0c1b07640"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/d7/ae/e3811f05415594025e96000349d3400978adaed88d8f98d494352d9761ee/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/06/7d51f4688d6d72bb72fa74254e1593c4f5ebd0036be5b41fe39315b275e9/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/08/b4499234a420ef42960eeb05585df5cc7eb25ccb8c980490b079e6367050/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/ba/1975a27dedf1c4c33306ee67c948121be8710b19387aada29e2f139c43ee/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/20/15/8a19a13d27f3bd09fa18813add8380a29115a47b553845f08802959acbce/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/19/ee/8d6146a079ad21e534b5083c9ee4a4c8bec42f79cf87594b60978286b39a/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a9/f5/426b714abdc222392e68f3b8ad323930d05a214a27c7e7a0f06c69126401/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",hashes = {sha256 = "f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2"}}, + {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",hashes = {sha256 = "090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/42/ccfb34a25289afbbc42017e4d3d4288e61d35b2e00cfc6b92974a6a1f94b/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "6aeadc170090ff1889f0d2c3057557f9cd71f975f17535c26a5d37af98f19c27"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/82/73/e628a92e80197ff6a79ab81ec3fa00d4cc082d58ab78d3337b7ba7043301/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "5e56ac47260c0eed992789fa0b8efe43404a9adb608608631a948cee4fc2b052"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/c5/346c7094344a60419764b4b1334d9e0285031c961176ff88ffb652405b0c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "a911aa73588d9a8b08d662b9484bc0567949529824a55d3885b77e8dd62a127a"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/99/65080c863eb06d4498de3d6c86f3e90595e02e159fd8529f1565f56cfe2c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a05ba88adf3d7189a974b2de7a9d56731548d35dc0a822ec3dc669caa7019b29"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/3d/e3/0de85f3e3333f8e29e4b10244374a202a87665d1131798946ee22cf05c7c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "fb04c5650de6668b853623eceadcdb1a9f2fee381f5d7b6bc842ee7c239eeec4"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d9/25/0d2f09d8833c7fd77ab8efeff213093c16856479a9d293180a0d89f6bed9/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "df3ec9959241d07bc261f4983d25a1205ff37703faf42b474f15d54d88b4f8c9"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d3/8c/959f10c2e2153cbdab834c46e6954b6dd9e3b109c8f8c0a3cf1618310985/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "fbc08c02e9b147a11dfcaa1ac8a83168b699863493e183f7c0c8b12850b7d259"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/6b/e580a7c18b485e1a5f30a32cda96b20364b0ba649d9d2baaf72f8bd21f83/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c099cafc1834d3c5dac305865d04235f7c21c167c8dd31ebc3d6bbc357e2f023"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/ef/44/3455eebc761dc8e8fdced90f2b0a3fa61e32ba38b50de4130e2d57db0f21/ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",hashes = {sha256 = "b5b0f7e294700b615a3bcf6d28b26e6da94e8eba63b079f4ec92e9ba6c0d6b54"}}, + {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/76/ab/5121f7f3b651db93de546f8c982c241397aad0a4765d793aca1dac5eadee/ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",hashes = {sha256 = "a37f40a859b503304dd740686359fcf541d6fb3ff7fc10f539af7f7150917c68"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b3/9f/3c51e9578b8c36fcc4bdd271a1a5bb65963a74a4b6ad1a989768a22f6c2a/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5bae1a073ca4244620425cd3d3aa9746bde590992b98ee8c7c8be8c597ca0d4e"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/16/cb02815bc2ae9c66760c0c061d23c7358f9ba51dae95ac85247662b7fbe2/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "0a54e5e40a7a691a426c2703b09b0d61a14294d25cfacc00631aa6f9c964df0d"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/31/c6/fc687cd1b93bff8e40861eea46d6dc1a6a778d9a085684e4045ff26a8e40/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "10d9595b6a19778f3269399eff6bab642608e5966183abc2adbe558a42d4efc9"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/45/5d/65a2bc08b709b08576b3f307bf63951ee68a8e047cbbda6f1c9864ecf9a7/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "dba72975485f2b87b786075e18a6e5d07dc2b4d8973beb2732b9b2816f1bad70"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/fb/d0/a70a03614d9a6788a3661ab1538879ed2aae4e84d861f101243116308a37/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "29757bdb7c142f9595cc1b62ec49a3d1c83fab9cef92db52b0ccebaad4eafb98"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/30/c93fa457611f79946d5cb6cc97493ca5425f3f21891d7b1f9b44eaa1b38e/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "557df28dbccf79b152fe2d1b935f6063d9cc431199ea2b0e84892f35c03bb0ee"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/40/85/e2c54ad637117cd13244a4649946eaa00f32edcb882d1f92df90e079ab00/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "26a8de280ab0d22b6e3ec745b4a5a07151a0f74aad92dd76ab9c8d8d7087720d"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/50/f899072c38877d8ef5382e0b3d47f8c4346226c1f52d6945d6f64fec6a2f/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e501c096aa3889133d674605ebd018471bc404a59cbc17da3c5924421c54d97c"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/99/7c/96d4b5075e30c65ea2064e40c2d657c7c235d7b6ef18751cf89a935b9041/ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",hashes = {sha256 = "915748cfc25b8cfd81b14d00f4bfdb2ab227a30d6d43459034533f4d1c207a2a"}}, + {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7d/8c/73ee2babd04e8bfcf1fd5c20aa553d18bf0ebc24b592b4f831d12ae46cc0/ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",hashes = {sha256 = "4ccba93c1e5a40af45b2f08e4591969fa4697eae951c708f3f83dcbf9f6c6bb1"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/56/35a0a752415ae01992c68f5a6513bdef0e1b6fbdb60d7619342ce12346a0/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "f8b2acb0ffdd2ce8208accbec2dca4a06937d556fdcaefd6473ba1b5daa7e3c4"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/98/6a/9a68184ab93619f4607ff1675e4ef01e8accfcbff0d482f4ca44c10d8eab/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "aef953f3b8bd0b50bd52a2e52fb54a6a2171a1889d8dea4a5959d46c6624c451"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/3f/cfed5f088628128a9ec66f46794fd4d165642155c7b78c26d83b16c6bf7b/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "a0ac90efbc7a77b0d796c03c8cc4e62fd710b3f1e4c32947713ef2ef52e09543"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/d5/5ce2cc156c1da48160171968d91f066d305840fbf930ee955a509d025a44/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9bf6b699223afe6c7fe9f2ef76e0bfa6dd892c21e94ce8c957478987ade76cd8"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2b/71/d0b56bc902b38ebe4be8e270f730f929eec4edaf8a0fa7028f4ef64fa950/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d73a0187718f6eec5b2f729b0f98e4603f7bd9c48aa65d01227d1a5dcdfbe9e8"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/db/1f37449dd89c540218598316ccafc1a0aed60215e72efa315c5367cfd015/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "81f6d3b19bc703679a5705c6a16dabdc79823c71d791d73c65949be7f3012c02"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/5d/53/c498b30f35efcd9f47cb084d7ad9374f2b907470f73913dec6396b81397d/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "b28caeaf3e670c08cb7e8de221266df8494c169bd6ed8875493fab45be9607a4"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/79/492cfad9baed68914840c39e5f3c1cc251f51a897ddb3f532601215cbb12/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "94f3efb718f8f49b031f2071ec7a27dd20cbfe511b4dfd54ecee54c956da2b31"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/ca/f5/479ebfd5ba396e209ade90f7282d84b90c57b3e07be8dc6fcd02a6df7ffc/ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",hashes = {sha256 = "27c070cf3888e90d992be75dd47292ff9aa17dafd36492812a6a304a1aedc182"}}, + {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/57/31/a044520fdb3bd409889f67f1efebda0658033c7ab3f390cee37531cc9a9e/ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4f4a150a737fccae13fb51234d41304ff2222e3b7d4c8e9428ed1a6ab48389b8"}}, ] marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and \"lint\" in dependency_groups" @@ -735,11 +740,11 @@ dependencies = [] [[packages]] name = "anyio" -version = "4.10.0" +version = "4.11.0" requires-python = ">=3.9" -sdist = {name = "anyio-4.10.0.tar.gz", url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hashes = {sha256 = "3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}} +sdist = {name = "anyio-4.11.0.tar.gz", url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hashes = {sha256 = "82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}} wheels = [ - {name = "anyio-4.10.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl",hashes = {sha256 = "60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}}, + {name = "anyio-4.11.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl",hashes = {sha256 = "0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}}, ] marker = "\"default\" in dependency_groups" @@ -848,7 +853,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "f41cee4895442b905a0fa8fe84189c460dff00eec403795e10a6ff2120675686"} +hashes = {sha256 = "a3b22dcb6e46e060513881b655a5824b61606a56fcce33d669d58321ed9c947f"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pyproject.toml b/pyproject.toml index 8472ac0..6a1eefe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,9 +11,9 @@ authors = [ { name = "Nassib Nassar", email = "nassib@indexdata.com" }, ] dependencies = [ - # 0.7.0 makes numpy an optional dependency, the minor version fixes a segfault + # Versions lower than 0.9 have issues binding the custom functions # 1.4 has a number of regressions so I'm letting it shake out until some fixes - "duckdb>=0.7.1,<1.4", + "duckdb>=0.9.2,<1.4", # 4.64 is the first release with type stubs "tqdm>=4.64.0", # 0.2 has query parameter handling, 0.2.3 is a required bug fix version From 7b08bd0715bb5bd7c7d06e26e5f274d34589683e Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Fri, 26 Sep 2025 19:54:16 +0000 Subject: [PATCH 08/25] Add additional history column and catch postgres error --- src/ldlite/__init__.py | 1 + src/ldlite/_database/__init__.py | 25 +++++++++++++++++++------ tests/test_load_history.py | 7 ++++--- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 938ce8e..271c791 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -406,6 +406,7 @@ def close(self) -> None: ... self._db.record_history( LoadHistory( prefix, + path, query if query and isinstance(query, str) else None, start, download, diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py index a3115a3..ffd72f6 100644 --- a/src/ldlite/_database/__init__.py +++ b/src/ldlite/_database/__init__.py @@ -6,11 +6,11 @@ from datetime import timezone from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast +import psycopg from psycopg import sql if TYPE_CHECKING: import duckdb - import psycopg class Prefix: @@ -66,6 +66,7 @@ def load_history_key(self) -> str: @dataclass(frozen=True) class LoadHistory: table_name: Prefix + path: str query: str | None start: datetime.datetime download: datetime.datetime @@ -98,10 +99,12 @@ class TypedDatabase(Database, Generic[DB]): def __init__(self, conn_factory: Callable[[], DB]): self._conn_factory = conn_factory with closing(self._conn_factory()) as conn, conn.cursor() as cur: - cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') - cur.execute(""" + try: + cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') + cur.execute(""" CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history" ( "table_name" TEXT UNIQUE + ,"path" TEXT ,"query" TEXT ,"start_utc" TIMESTAMP ,"download_complete_utc" TIMESTAMP @@ -109,7 +112,15 @@ def __init__(self, conn_factory: Callable[[], DB]): ,"index_complete_utc" TIMESTAMP ,"row_count" INTEGER );""") - conn.commit() + except psycopg.errors.UniqueViolation: + # postgres throws this when multiple threads try to create + # the same resource even if CREATE IF NOT EXISTS was used + # if we get it then something else create the ldlite_system + # resources and it is ok to not commit + # I'm not happy with this being in the base class but it's probably fine + ... + else: + conn.commit() @property @abstractmethod @@ -235,9 +246,10 @@ def record_history(self, history: LoadHistory) -> None: with closing(self._conn_factory()) as conn, conn.cursor() as cur: cur.execute( """ -INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7) +INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT ("table_name") DO UPDATE SET - "query" = EXCLUDED."query" + "path" = EXCLUDED."path" + ,"query" = EXCLUDED."query" ,"start_utc" = EXCLUDED."start_utc" ,"download_complete_utc" = EXCLUDED."download_complete_utc" ,"transformation_complete_utc" = EXCLUDED."transformation_complete_utc" @@ -246,6 +258,7 @@ def record_history(self, history: LoadHistory) -> None: """, ( history.table_name.load_history_key, + history.path, history.query, history.start.astimezone(timezone.utc), history.download.astimezone(timezone.utc), diff --git a/tests/test_load_history.py b/tests/test_load_history.py index 98a7e3e..78899aa 100644 --- a/tests/test_load_history.py +++ b/tests/test_load_history.py @@ -135,9 +135,10 @@ def _assert( (tn,), ) assert (d := cur.fetchone()) is not None - assert d[1] == q - assert d[6] == t - assert d[5] > d[4] > d[3] > d[2] + assert d[1] == "/patched" + assert d[2] == q + assert d[7] == t + assert d[6] > d[5] > d[4] > d[3] @mock.patch("httpx_folio.auth.httpx.post") From cb81953fd8a164f186a94d045e5fd4ca7ed4b44c Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Fri, 26 Sep 2025 16:25:14 -0400 Subject: [PATCH 09/25] Abstract json processing differences between duckdb and postgres (#51) The plan to speed up json transformation is to do it all in SQL using the native json functionality. A proof of concept and some napkin math has this running at least 10x faster. In order to not have to duplicate the transformation queries (which will be complicated) we're adding abstractions over the native functionality in duckdb and postgres. This will allow us to write one query that is agnostic to the underlying engine. Duckdb was in particular hard to get the versioning correct with as they like to have incompatibilities between versions. I think the version check and setting is a reasonable way to keep it consistent but we'll see if it becomes unmaintainable. Postgres compatibility has been tested from 13.22+. There's no actual functionality changes here but the PR was already getting huge before starting to do the actual refactor for the transformation. --- src/ldlite/_database/__init__.py | 13 +- src/ldlite/_database/duckdb.py | 77 +++++++++ src/ldlite/_database/postgres.py | 77 +++++++++ tests/test_json_operators.py | 282 +++++++++++++++++++++++++++++++ 4 files changed, 446 insertions(+), 3 deletions(-) create mode 100644 tests/test_json_operators.py diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py index ffd72f6..9decad5 100644 --- a/src/ldlite/_database/__init__.py +++ b/src/ldlite/_database/__init__.py @@ -98,10 +98,11 @@ def record_history(self, history: LoadHistory) -> None: ... class TypedDatabase(Database, Generic[DB]): def __init__(self, conn_factory: Callable[[], DB]): self._conn_factory = conn_factory - with closing(self._conn_factory()) as conn, conn.cursor() as cur: + with closing(self._conn_factory()) as conn: try: - cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') - cur.execute(""" + with conn.cursor() as cur: + cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') + cur.execute(""" CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history" ( "table_name" TEXT UNIQUE ,"path" TEXT @@ -112,6 +113,8 @@ def __init__(self, conn_factory: Callable[[], DB]): ,"index_complete_utc" TIMESTAMP ,"row_count" INTEGER );""") + + self._setup_jfuncs(conn) except psycopg.errors.UniqueViolation: # postgres throws this when multiple threads try to create # the same resource even if CREATE IF NOT EXISTS was used @@ -122,6 +125,10 @@ def __init__(self, conn_factory: Callable[[], DB]): else: conn.commit() + @staticmethod + @abstractmethod + def _setup_jfuncs(conn: DB) -> None: ... + @property @abstractmethod def _default_schema(self) -> str: ... diff --git a/src/ldlite/_database/duckdb.py b/src/ldlite/_database/duckdb.py index 0676875..c9b994a 100644 --- a/src/ldlite/_database/duckdb.py +++ b/src/ldlite/_database/duckdb.py @@ -8,6 +8,83 @@ class DuckDbDatabase(TypedDatabase[duckdb.DuckDBPyConnection]): + @staticmethod + def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: + with conn.cursor() as cur: + cur.execute("SELECT string_split(ltrim(version(),'v'), '.') AS has_lambda;") + if ver := cur.fetchone(): + (ma, mi, _) = ver[0] + if int(ma) > 1 and int(mi) >= 3: + cur.execute("SET lambda_syntax = 'ENABLE_SINGLE_ARROW';") + + with conn.cursor() as cur: + cur.execute( + r""" +CREATE OR REPLACE FUNCTION ldlite_system.jtype_of(j) AS + CASE coalesce(main.json_type(j), 'NULL') + WHEN 'VARCHAR' THEN 'string' + WHEN 'BIGINT' THEN 'number' + WHEN 'DOUBLE' THEN 'number' + WHEN 'UBIGINT' THEN 'number' + WHEN 'OBJECT' THEN 'object' + WHEN 'BOOLEAN' THEN 'boolean' + WHEN 'ARRAY' THEN 'array' + WHEN 'NULL' THEN 'null' + ELSE main.json_type(j) + END +; + +CREATE OR REPLACE FUNCTION ldlite_system.jextract(j, p) AS + CASE ldlite_system.jtype_of(main.json_extract(j, p)) + WHEN 'string' THEN + CASE + WHEN lower(main.json_extract_string(j, p)) = 'null' THEN 'null'::JSON + WHEN length(main.json_extract_string(j, p)) = 0 THEN 'null'::JSON + ELSE main.json_extract(j, p) + END + WHEN 'object' THEN + CASE + WHEN main.json_extract_string(j, p) = '{}' THEN 'null'::JSON + ELSE main.json_extract(j, p) + END + WHEN 'array' THEN + CASE + WHEN length(list_filter((main.json_extract(j, p))::JSON[], x -> x != 'null'::JSON)) = 0 THEN 'null'::JSON + ELSE list_filter((main.json_extract(j, p))::JSON[], x -> x != 'null'::JSON) + END + ELSE coalesce(main.json_extract(j, p), 'null'::JSON) + END +; + +CREATE OR REPLACE FUNCTION ldlite_system.jextract_string(j, p) AS + main.json_extract_string(ldlite_system.jextract(j, p), '$') +; + +CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j) AS + unnest(main.json_keys(j)) +; + +CREATE OR REPLACE FUNCTION ldlite_system.jis_uuid(j) AS + CASE ldlite_system.jtype_of(j) + WHEN 'string' THEN regexp_full_match(main.json_extract_string(j, '$'), '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$') + ELSE FALSE + END +; + +CREATE OR REPLACE FUNCTION ldlite_system.jis_datetime(j) AS + CASE ldlite_system.jtype_of(j) + WHEN 'string' THEN regexp_full_match(main.json_extract_string(j, '$'), '^\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?$') + ELSE FALSE + END +; + +CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j) AS + coalesce(main.json_type(j), 'NULL')='DOUBLE' +; + +""", # noqa: E501 + ) + @property def _default_schema(self) -> str: return "main" diff --git a/src/ldlite/_database/postgres.py b/src/ldlite/_database/postgres.py index 479018d..7a78477 100644 --- a/src/ldlite/_database/postgres.py +++ b/src/ldlite/_database/postgres.py @@ -13,6 +13,83 @@ def __init__(self, dsn: str): # same sql between duckdb and postgres super().__init__(lambda: psycopg.connect(dsn, cursor_factory=psycopg.RawCursor)) + @staticmethod + def _setup_jfuncs(conn: psycopg.Connection) -> None: + with conn.cursor() as cur: + cur.execute( + r""" +CREATE OR REPLACE FUNCTION ldlite_system.jtype_of(j JSONB) RETURNS TEXT AS $$ +BEGIN + RETURN jsonb_typeof(j); +END +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION ldlite_system.jextract(j JSONB, p TEXT) RETURNS JSONB AS $$ +BEGIN + RETURN CASE + WHEN ldlite_system.jtype_of(j->p) = 'string' THEN + CASE + WHEN lower(j->>p) = 'null' THEN 'null'::JSONB + WHEN length(j->>p) = 0 THEN 'null'::JSONB + ELSE j->p + END + WHEN ldlite_system.jtype_of(j->p) = 'array' THEN + CASE + WHEN jsonb_array_length(jsonb_path_query_array(j->p, '$[*] ? (@ != null)')) = 0 THEN 'null'::JSONB + ELSE jsonb_path_query_array(j->p, '$[*] ? (@ != null)') + END + WHEN ldlite_system.jtype_of(j->p) = 'object' THEN + CASE + WHEN j->>p = '{}' THEN 'null'::JSONB + ELSE j->p + END + ELSE j->p + END; +END +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION ldlite_system.jextract_string(j JSONB, p TEXT) RETURNS TEXT AS $$ +BEGIN + RETURN ldlite_system.jextract(j, p) ->> 0; +END +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j JSONB) RETURNS SETOF TEXT AS $$ +BEGIN + RETURN QUERY SELECT jsonb_object_keys(j); +END +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION ldlite_system.jis_uuid(j JSONB) RETURNS BOOLEAN AS $$ +BEGIN + RETURN CASE + WHEN ldlite_system.jtype_of(j) = 'string' THEN j->>0 ~ '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$' + ELSE FALSE + END; +END +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION ldlite_system.jis_datetime(j JSONB) RETURNS BOOLEAN AS $$ +BEGIN + RETURN CASE + WHEN ldlite_system.jtype_of(j) = 'string' THEN j->>0 ~ '^\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?$' + ELSE FALSE + END; +END +$$ LANGUAGE plpgsql; + + +CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j JSONB) RETURNS BOOLEAN AS $$ +BEGIN + RETURN CASE + WHEN ldlite_system.jtype_of(j) = 'number' THEN j->>0 LIKE '%.%' + ELSE FALSE + END; +END +$$ LANGUAGE plpgsql; +""", # noqa: E501 + ) + @property def _default_schema(self) -> str: return "public" diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py new file mode 100644 index 0000000..5eec23e --- /dev/null +++ b/tests/test_json_operators.py @@ -0,0 +1,282 @@ +from collections.abc import Callable, Iterator +from contextlib import closing +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, cast +from uuid import uuid4 + +import duckdb +import psycopg +import pytest +from pytest_cases import parametrize, parametrize_with_cases + +if TYPE_CHECKING: + from _typeshed import dbapi + + +def _db() -> str: + db = "db" + str(uuid4()).split("-")[0] + print(db) # noqa: T201 + return db + + +@dataclass +class JsonTC: + query: str + query_params: tuple[Any, ...] + assertion: str + assertion_params: tuple[Any, ...] + + +@parametrize( + p=[ + ("str", '"str_val"'), + ("str_empty", "null"), + ("num", "12"), + ("float", "16.3"), + ("bool", "true"), + ("obj", '{"k1":"v1","k2":"v2"}'), + ("obj_some", '{"k1":"v1","k2":null}'), + ("obj_empty", "null"), + ("arr_zero", "null"), + ("arr_str", '["s1","s2","s3"]'), + ("arr_str_some", '["s1","s2"]'), + ("arr_obj_some", '[{"k1":"v1"}]'), + ("na", "null"), + ("na_str1", "null"), + ("na_str2", "null"), + ], +) +def case_jextract(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """SELECT ldlite_system.jextract(jc, $1){assertion} FROM j;""", + p[:1], + """= $2::{jtype}""", + p[1:], + ) + + +@parametrize( + p=[ + ("str", "str_val"), + ("num", "12"), + ("float", "16.3"), + ("bool", "true"), + ("na",), + ("na_str1",), + ("na_str2",), + ], +) +def case_jextract_string(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """SELECT ldlite_system.jextract_string(jc, $1){assertion} FROM j;""", + p[:1], + """ = $2""" if len(p) == 2 else """ IS NULL""", + p[1:], + ) + + +def case_jobject_keys() -> JsonTC: + return JsonTC( + """ +{assertion} +(SELECT e.jkey, a.jkey +FROM (SELECT 'k1' jkey UNION SELECT 'k2' jkey) as e +FULL OUTER JOIN (SELECT ldlite_system.jobject_keys(jc->'obj') jkey FROM j) as a + USING (jkey) +WHERE e.jkey IS NULL or a.jkey IS NULL) as q;""", + (), + "SELECT COUNT(1) = 0 FROM ", + (), + ) + + +@parametrize( + p=[ + ("str", "string"), + ("num", "number"), + ("float", "number"), + ("bool", "boolean"), + ("obj", "object"), + ("arr_str", "array"), + ("arr_obj", "array"), + ("na", "null"), + ], +) +def case_jtypeof(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT ldlite_system.jtype_of(jc->$1){assertion} +FROM j;""", + p[:1], + """ = $2""", + p[1:], + ) + + +@parametrize( + p=[ + ("str", False), + ("str_empty", False), + ("num", False), + ("na", False), + ("na_str1", False), + ("na_str2", False), + ("uuid_nof", False), + ("uuid", True), + ], +) +def case_jis_uuid(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT {assertion}ldlite_system.jis_uuid(jc->$1) +FROM j;""", + p[:1], + "" if (p[1]) else """ NOT """, + (), + ) + + +@parametrize( + p=[ + ("str", False), + ("str_empty", False), + ("num", False), + ("na", False), + ("na_str1", False), + ("na_str2", False), + ("uuid_nof", False), + ("uuid", False), + ("dt", True), + ], +) +def case_jis_datetime(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT {assertion}ldlite_system.jis_datetime(jc->$1) +FROM j;""", + p[:1], + "" if (p[1]) else """ NOT """, + (), + ) + + +@parametrize( + p=[ + ("str", False), + ("str_empty", False), + ("num", False), + ("na", False), + ("na_str1", False), + ("na_str2", False), + ("uuid_nof", False), + ("uuid", False), + ("dt", False), + ("num", False), + ("float", True), + ], +) +def case_jis_float(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT {assertion}ldlite_system.jis_float(jc->$1) +FROM j;""", + p[:1], + "" if (p[1]) else """ NOT """, + (), + ) + + +def _assert(conn: "dbapi.DBAPIConnection", jtype: str, tc: JsonTC) -> None: + with closing(conn.cursor()) as cur: + query = tc.query.format(assertion="", jtype=jtype) + assertion = tc.query.format( + assertion=tc.assertion.format(jtype=jtype), + jtype=jtype, + ) + + cur.execute(assertion, (*tc.query_params, *tc.assertion_params)) + actual = cur.fetchone() + assert actual is not None + + if actual[0] is None or not actual[0]: + cur.execute(query, tc.query_params) + diff = "" + for r in cur.fetchall(): + diff += f"{r}\n" + pytest.fail(diff) + + assert actual[0] is not None + assert actual[0] + + +def _arrange(conn: "dbapi.DBAPIConnection") -> None: + with closing(conn.cursor()) as cur: + cur.execute( + "INSERT INTO j VALUES " + "('{" + """ "str": "str_val",""" + """ "str_empty": "",""" + """ "num": 12,""" + """ "float": 16.3,""" + """ "bool": true,""" + """ "uuid": "5b285d03-5490-1111-8888-52b2003b475c",""" + """ "uuid_nof": "5b285d03-5490-FFFF-0000-52b2003b475c",""" + """ "obj": {"k1": "v1", "k2": "v2"},""" + """ "obj_some": {"k1": "v1", "k2": null},""" + """ "obj_empty": {},""" + """ "arr_zero": [],""" + """ "arr_str": ["s1", "s2", "s3"],""" + """ "arr_str_some": ["s1", "s2", null],""" + """ "arr_obj": [{"k1": "v1"}, {"k2": "v2"}],""" + """ "arr_obj_some": [{"k1": "v1"}, null],""" + """ "dt": "2022-04-21T18:47:33.581+00:00",""" + """ "na": null,""" + """ "na_str1": "null", """ + """ "na_str2": "NULL" """ + " }')", + ) + + +@pytest.fixture(scope="session") +def duckdb_jop_dsn() -> Iterator[str]: + dsn = f":memory:{_db()}" + + with duckdb.connect(dsn) as conn: + conn.execute("CREATE TABLE j (jc JSON)") + _arrange(cast("dbapi.DBAPIConnection", conn)) + + yield dsn + + +@parametrize_with_cases("tc", cases=".") +def test_duckdb(duckdb_jop_dsn: str, tc: JsonTC) -> None: + from ldlite import LDLite + + ld = LDLite() + ld.connect_db(duckdb_jop_dsn) + + with duckdb.connect(duckdb_jop_dsn) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "JSON", tc) + + +@pytest.fixture(scope="session") +def pg_jop_dsn(pg_dsn: None | Callable[[str], str]) -> str: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + dsn = pg_dsn(_db()) + with psycopg.connect(dsn) as conn, conn.cursor() as cur: + cur.execute("CREATE TABLE j (jc JSONB)") + _arrange(cast("dbapi.DBAPIConnection", conn)) + return dsn + + +@parametrize_with_cases("tc", cases=".") +def test_postgres(pg_jop_dsn: str, tc: JsonTC) -> None: + from ldlite import LDLite + + ld = LDLite() + ld.connect_db_postgresql(pg_jop_dsn) + + with psycopg.connect(pg_jop_dsn, cursor_factory=psycopg.RawCursor) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "JSONB", tc) From 8372945bfed7401844fa2c86e649b086fa64f573 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Thu, 2 Oct 2025 16:01:19 +0000 Subject: [PATCH 10/25] Swallow another error due to parallel postgres queries --- src/ldlite/_database/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py index 9decad5..0cae6c7 100644 --- a/src/ldlite/_database/__init__.py +++ b/src/ldlite/_database/__init__.py @@ -116,12 +116,15 @@ def __init__(self, conn_factory: Callable[[], DB]): self._setup_jfuncs(conn) except psycopg.errors.UniqueViolation: - # postgres throws this when multiple threads try to create + # postgres throws a couple of errors when multiple threads try to create # the same resource even if CREATE IF NOT EXISTS was used - # if we get it then something else create the ldlite_system + # if we get it then something else created the ldlite_system # resources and it is ok to not commit # I'm not happy with this being in the base class but it's probably fine ... + except psycopg.errors.InternalError_ as e: + if str(e) != "tuple concurrently updated": + raise else: conn.commit() From abd4a78575098b2e4993cd2aaab3ccccde61d6c3 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Tue, 10 Feb 2026 12:57:37 -0500 Subject: [PATCH 11/25] Merge changes from the 3.2.1 release (#61) #60 created the 3.2.1 release while the 4.0 release was still in progress. This pulls in the relevant changes and makes them work with the 4.0 structure. #59 was not included because the transformation logic is going to be redone in 4.0. --- CHANGELOG.md | 9 + README.md | 6 +- examples/folio_demo.py | 37 ++- pylock.maximal.toml | 344 +++++++++----------- pylock.minimal.toml | 231 +++++-------- pylock.toml | 631 +++++++++++++++++------------------- pyproject.toml | 6 +- src/ldlite/_folio.py | 19 +- tests/mock_response_case.py | 9 +- tests/test_query.py | 35 ++ 10 files changed, 638 insertions(+), 689 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b958f7..871a049 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,15 @@ Please see [MIGRATING.md](./MIGRATING.md) for information on breaking changes. ### Removed +## [3.2.1] - November 2025 + +### Fixed + +- Endpoints which return system fields before the record list +- Example python script +- Columns with mixed and incompatible datatypes +- Endless looping for calendar/calendars endpoint + ## [3.2.0] - September 2025 ### Added diff --git a/README.md b/README.md index a1bb937..4a20a4d 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,12 @@ To install LDLite or upgrade to the latest version: ```bash $ python -m pip install --upgrade ldlite ``` - (On some systems it might be `python3` rather than `python`.) + +If you encounter the error `ImportError: no pq wrapper available.` you can either +* Run `python -m pip install psycopg[binary]` +* Ensure the libpq package is installed for your operating system + Check out the [migration guide](./MIGRATING.md) for more information about major version upgrades. *Optional* If you intend to use the `connect_db_postgres()` method install the binary provider: diff --git a/examples/folio_demo.py b/examples/folio_demo.py index 12949ca..9818d04 100644 --- a/examples/folio_demo.py +++ b/examples/folio_demo.py @@ -3,6 +3,8 @@ import sys +import httpx + import ldlite # Demo sites @@ -30,7 +32,7 @@ ) ld.connect_db(filename="ldlite.db") -# For PostgreSQL, use connect_db_postgresql() instead of connect_db(): +# For PostgreSQL, use connect_db_postgresql() instead: # ld.connect_db_postgresql(dsn='dbname=ldlite host=localhost user=ldlite') queries: list[tuple[str, ...] | tuple[str, str, object, int]] = [ @@ -38,7 +40,8 @@ ("folio_agreements.erm_resource", "/erm/resource"), ("folio_agreements.org", "/erm/org"), ("folio_agreements.refdata_value", "/erm/refdata"), - ("folio_agreements.usage_data_provider", "/usage-data-providers"), + # This endpoint doesn't work in EBSCO environments + # ("folio_agreements.usage_data_provider", "/usage-data-providers"), ("folio_audit.circulation_logs", "/audit-data/circulation/logs"), ("folio_circulation.audit_loan", "/loan-storage/loan-history"), ( @@ -165,7 +168,7 @@ "/acquisitions-units-storage/memberships", ), ("folio_orders.alert", "/orders-storage/alerts"), - ("folio_orders.order_invoice_relationship/orders-storage/order-invoice-relns"), + ("folio_orders.order_invoice_relationship", "/orders-storage/order-invoice-relns"), ("folio_orders.order_templates", "/orders-storage/order-templates"), ("folio_orders.pieces", "/orders-storage/pieces"), ("folio_orders.po_line", "/orders-storage/po-lines"), @@ -176,10 +179,10 @@ ("folio_organizations.contacts", "/organizations-storage/contacts"), ("folio_organizations.emails", "/organizations-storage/emails"), ("folio_organizations.interfaces", "/organizations-storage/interfaces"), - ("folio_organizations.organizations", "/organizations-storage/organizations"), + ("folio_organizations.organizations", "/organizations/organizations"), ("folio_organizations.phone_numbers", "/organizations-storage/phone-numbers"), ("folio_organizations.urls", "/organizations-storage/urls"), - ("folio_source_record.records", "/source-storage/records", {}, 2), + ("folio_source_record.records", "/source-storage/records", 2), ("folio_users.addresstype", "/addresstypes"), ("folio_users.departments", "/departments"), ("folio_users.groups", "/groups"), @@ -187,25 +190,31 @@ ("folio_users.users", "/users"), ] +errors: list[tuple[str, BaseException]] = [] tables: list[str] = [] for q in queries: try: - if len(q) == 4: + if len(q) == 3: tables += ld.query( table=q[0], path=q[1], - query=str(q[2]), - json_depth=int(q[3]), + json_depth=int(q[2]), ) else: - tables += ld.query(table=q[0], path=q[1], query=str(q[2])) - except (ValueError, RuntimeError) as e: - print( - 'folio_demo.py: error processing "' + str(q[1]) + '": ' + str(e), - file=sys.stderr, - ) + tables += ld.query(table=q[0], path=q[1]) + except (ValueError, RuntimeError, httpx.HTTPError) as e: + errors += [(q[1], e)] print() print("Tables:") for t in tables: print(t) print("(" + str(len(tables)) + " tables)") +if len(errors) > 0: + print() + print("Errors:") + for p, e in errors: + print( + 'folio_demo.py: error processing "' + p + '": ' + str(e), + file=sys.stderr, + ) +print("(" + str(len(errors)) + " errors)") diff --git a/pylock.maximal.toml b/pylock.maximal.toml index 49c1df7..bacb212 100644 --- a/pylock.maximal.toml +++ b/pylock.maximal.toml @@ -107,63 +107,71 @@ dependencies = [] [[packages]] name = "coverage" -version = "7.10.7" -requires-python = ">=3.9" -sdist = {name = "coverage-7.10.7.tar.gz", url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hashes = {sha256 = "f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239"}} -wheels = [ - {name = "coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520"}}, - {name = "coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd"}}, - {name = "coverage-7.10.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl",hashes = {sha256 = "b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2"}}, - {name = "coverage-7.10.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681"}}, - {name = "coverage-7.10.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880"}}, - {name = "coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63"}}, - {name = "coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399"}}, - {name = "coverage-7.10.7-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl",hashes = {sha256 = "67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235"}}, - {name = "coverage-7.10.7-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d"}}, - {name = "coverage-7.10.7-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a"}}, - {name = "coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d"}}, - {name = "coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f"}}, - {name = "coverage-7.10.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl",hashes = {sha256 = "dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698"}}, - {name = "coverage-7.10.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843"}}, - {name = "coverage-7.10.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546"}}, - {name = "coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c"}}, - {name = "coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2"}}, - {name = "coverage-7.10.7-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl",hashes = {sha256 = "2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a"}}, - {name = "coverage-7.10.7-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb"}}, - {name = "coverage-7.10.7-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb"}}, - {name = "coverage-7.10.7-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl",hashes = {sha256 = "f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260"}}, +version = "7.13.4" +requires-python = ">=3.10" +sdist = {name = "coverage-7.13.4.tar.gz", url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hashes = {sha256 = "e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}} +wheels = [ + {name = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}}, + {name = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}}, + {name = "coverage-7.13.4-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl",hashes = {sha256 = "8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}}, + {name = "coverage-7.13.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}}, + {name = "coverage-7.13.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}}, + {name = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}}, + {name = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}}, + {name = "coverage-7.13.4-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl",hashes = {sha256 = "c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}}, + {name = "coverage-7.13.4-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}}, + {name = "coverage-7.13.4-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}}, + {name = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}}, + {name = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}}, + {name = "coverage-7.13.4-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl",hashes = {sha256 = "f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}}, + {name = "coverage-7.13.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}}, + {name = "coverage-7.13.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}}, + {name = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}}, + {name = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}}, + {name = "coverage-7.13.4-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl",hashes = {sha256 = "2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}}, + {name = "coverage-7.13.4-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}}, + {name = "coverage-7.13.4-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}}, + {name = "coverage-7.13.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl",hashes = {sha256 = "1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}}, ] marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" @@ -172,11 +180,11 @@ dependencies = [] [[packages]] name = "httpx-folio" -version = "0.2.3" +version = "0.3.0" requires-python = ">=3.9" -sdist = {name = "httpx_folio-0.2.3.tar.gz", url = "https://files.pythonhosted.org/packages/72/07/727a73827674a6a91db6a58ac492703d6d0efe9a5f14d856aff9b434fe65/httpx_folio-0.2.3.tar.gz", hashes = {sha256 = "8c4afd55231e1a645c824a7ffa63ebc1b0261223e5d6b65101ab639a6a0a54dd"}} +sdist = {name = "httpx_folio-0.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/87/23/dd3f9ade71ace5a4b0343388792aa1bf8892f95ddf7217d82c0182f14c59/httpx_folio-0.3.0.tar.gz", hashes = {sha256 = "436778fb1bffb3327393bd5b809e7f38a2fd9fdfc8fea71a0a47fe2e0dbae2f2"}} wheels = [ - {name = "httpx_folio-0.2.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/34/3c/b5333a57399d8c787efb2c90d9accb6ddf22523fcec3404814b0eb10bb8a/httpx_folio-0.2.3-py3-none-any.whl",hashes = {sha256 = "e319cc8cf3e0443982655a6012017e36af112e58081b050b40048052b039b6e9"}}, + {name = "httpx_folio-0.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5a/91/2ab3ee8588e5eab7808be5c3b1ea8fb3515f07686cddf49cbcde40885b3d/httpx_folio-0.3.0-py3-none-any.whl",hashes = {sha256 = "5396438eb07257db7c080382f65711b01b93eab3b2adc420a5855be3007c37ae"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -188,36 +196,40 @@ dependencies = [ [[packages]] name = "orjson" -version = "3.11.3" -requires-python = ">=3.9" -sdist = {name = "orjson-3.11.3.tar.gz", url = "https://files.pythonhosted.org/packages/be/4d/8df5f83256a809c22c4d6792ce8d43bb503be0fb7a8e4da9025754b09658/orjson-3.11.3.tar.gz", hashes = {sha256 = "1c0603b1d2ffcd43a411d64797a19556ef76958aef1c182f22dc30860152a98a"}} -wheels = [ - {name = "orjson-3.11.3-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/ef/77/d3b1fef1fc6aaeed4cbf3be2b480114035f4df8fa1a99d2dac1d40d6e924/orjson-3.11.3-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "cf4b81227ec86935568c7edd78352a92e97af8da7bd70bdfdaa0d2e0011a1ab4"}}, - {name = "orjson-3.11.3-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e4/6d/468d21d49bb12f900052edcfbf52c292022d0a323d7828dc6376e6319703/orjson-3.11.3-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "bc8bc85b81b6ac9fc4dae393a8c159b817f4c2c9dee5d12b773bddb3b95fc07e"}}, - {name = "orjson-3.11.3-cp314-cp314-manylinux_2_34_aarch64.whl",url = "https://files.pythonhosted.org/packages/67/46/1e2588700d354aacdf9e12cc2d98131fb8ac6f31ca65997bef3863edb8ff/orjson-3.11.3-cp314-cp314-manylinux_2_34_aarch64.whl",hashes = {sha256 = "88dcfc514cfd1b0de038443c7b3e6a9797ffb1b3674ef1fd14f701a13397f82d"}}, - {name = "orjson-3.11.3-cp314-cp314-manylinux_2_34_x86_64.whl",url = "https://files.pythonhosted.org/packages/3b/94/11137c9b6adb3779f1b34fd98be51608a14b430dbc02c6d41134fbba484c/orjson-3.11.3-cp314-cp314-manylinux_2_34_x86_64.whl",hashes = {sha256 = "d61cd543d69715d5fc0a690c7c6f8dcc307bc23abef9738957981885f5f38229"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/10/61/dccedcf9e9bcaac09fdabe9eaee0311ca92115699500efbd31950d878833/orjson-3.11.3-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2b7b153ed90ababadbef5c3eb39549f9476890d339cf47af563aea7e07db2451"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/0e/fd/0e935539aa7b08b3ca0f817d73034f7eb506792aae5ecc3b7c6e679cdf5f/orjson-3.11.3-cp314-cp314-musllinux_1_2_armv7l.whl",hashes = {sha256 = "7909ae2460f5f494fecbcd10613beafe40381fd0316e35d6acb5f3a05bfda167"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/4a/2b/50ae1a5505cd1043379132fdb2adb8a05f37b3e1ebffe94a5073321966fd/orjson-3.11.3-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "2030c01cbf77bc67bee7eef1e7e31ecf28649353987775e3583062c752da0077"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/cd/1d/a473c158e380ef6f32753b5f39a69028b25ec5be331c2049a2201bde2e19/orjson-3.11.3-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a0169ebd1cbd94b26c7a7ad282cf5c2744fce054133f959e02eb5265deae1872"}}, - {name = "orjson-3.11.3-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/da/09/17d9d2b60592890ff7382e591aa1d9afb202a266b180c3d4049b1ec70e4a/orjson-3.11.3-cp314-cp314-win32.whl",hashes = {sha256 = "0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d"}}, - {name = "orjson-3.11.3-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/15/58/358f6846410a6b4958b74734727e582ed971e13d335d6c7ce3e47730493e/orjson-3.11.3-cp314-cp314-win_amd64.whl",hashes = {sha256 = "317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804"}}, - {name = "orjson-3.11.3-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/28/01/d6b274a0635be0468d4dbd9cafe80c47105937a0d42434e805e67cd2ed8b/orjson-3.11.3-cp314-cp314-win_arm64.whl",hashes = {sha256 = "e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc"}}, - {name = "orjson-3.11.3-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/fc/79/8932b27293ad35919571f77cb3693b5906cf14f206ef17546052a241fdf6/orjson-3.11.3-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "af40c6612fd2a4b00de648aa26d18186cd1322330bd3a3cc52f87c699e995810"}}, - {name = "orjson-3.11.3-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/1c/82/cb93cd8cf132cd7643b30b6c5a56a26c4e780c7a145db6f83de977b540ce/orjson-3.11.3-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "9f1587f26c235894c09e8b5b7636a38091a9e6e7fe4531937534749c04face43"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/b8/2d9eb181a9b6bb71463a78882bcac1027fd29cf62c38a40cc02fc11d3495/orjson-3.11.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "61dcdad16da5bb486d7227a37a2e789c429397793a6955227cedbd7252eb5a27"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/b4/14/a0e971e72d03b509190232356d54c0f34507a05050bd026b8db2bf2c192c/orjson-3.11.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "11c6d71478e2cbea0a709e8a06365fa63da81da6498a53e4c4f065881d21ae8f"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/8e/af/dc74536722b03d65e17042cc30ae586161093e5b1f29bccda24765a6ae47/orjson-3.11.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "ff94112e0098470b665cb0ed06efb187154b63649403b8d5e9aedeb482b4548c"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/62/e6/7a3b63b6677bce089fe939353cda24a7679825c43a24e49f757805fc0d8a/orjson-3.11.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "ae8b756575aaa2a855a75192f356bbda11a89169830e1439cfb1a3e1a6dde7be"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/fc/cd/ce2ab93e2e7eaf518f0fd15e3068b8c43216c8a44ed82ac2b79ce5cef72d/orjson-3.11.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "c9416cc19a349c167ef76135b2fe40d03cea93680428efee8771f3e9fb66079d"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d0/b4/f98355eff0bd1a38454209bbc73372ce351ba29933cb3e2eba16c04b9448/orjson-3.11.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "b822caf5b9752bc6f246eb08124c3d12bf2175b66ab74bac2ef3bbf9221ce1b2"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/92/8f5182d7bc2a1bed46ed960b61a39af8389f0ad476120cd99e67182bfb6d/orjson-3.11.3-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "414f71e3bdd5573893bf5ecdf35c32b213ed20aa15536fe2f588f946c318824f"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/1a/60/c41ca753ce9ffe3d0f67b9b4c093bdd6e5fdb1bc53064f992f66bb99954d/orjson-3.11.3-cp313-cp313-musllinux_1_2_armv7l.whl",hashes = {sha256 = "828e3149ad8815dc14468f36ab2a4b819237c155ee1370341b91ea4c8672d2ee"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/dd/13/e4a4f16d71ce1868860db59092e78782c67082a8f1dc06a3788aef2b41bc/orjson-3.11.3-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "ac9e05f25627ffc714c21f8dfe3a579445a5c392a9c8ae7ba1d0e9fb5333f56e"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/8d/8b/bafb7f0afef9344754a3a0597a12442f1b85a048b82108ef2c956f53babd/orjson-3.11.3-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e44fbe4000bd321d9f3b648ae46e0196d21577cf66ae684a96ff90b1f7c93633"}}, - {name = "orjson-3.11.3-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/60/d4/bae8e4f26afb2c23bea69d2f6d566132584d1c3a5fe89ee8c17b718cab67/orjson-3.11.3-cp313-cp313-win32.whl",hashes = {sha256 = "2039b7847ba3eec1f5886e75e6763a16e18c68a63efc4b029ddf994821e2e66b"}}, - {name = "orjson-3.11.3-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/88/76/224985d9f127e121c8cad882cea55f0ebe39f97925de040b75ccd4b33999/orjson-3.11.3-cp313-cp313-win_amd64.whl",hashes = {sha256 = "29be5ac4164aa8bdcba5fa0700a3c9c316b411d8ed9d39ef8a882541bd452fae"}}, - {name = "orjson-3.11.3-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e2/cf/0dce7a0be94bd36d1346be5067ed65ded6adb795fdbe3abd234c8d576d01/orjson-3.11.3-cp313-cp313-win_arm64.whl",hashes = {sha256 = "18bd1435cb1f2857ceb59cfb7de6f92593ef7b831ccd1b9bfb28ca530e539dce"}}, +version = "3.11.7" +requires-python = ">=3.10" +sdist = {name = "orjson-3.11.7.tar.gz", url = "https://files.pythonhosted.org/packages/53/45/b268004f745ede84e5798b48ee12b05129d19235d0e15267aa57dcdb400b/orjson-3.11.7.tar.gz", hashes = {sha256 = "9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49"}} +wheels = [ + {name = "orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/e9/1e/745565dca749813db9a093c5ebc4bac1a9475c64d54b95654336ac3ed961/orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0"}}, + {name = "orjson-3.11.7-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/46/19/e40f6225da4d3aa0c8dc6e5219c5e87c2063a560fe0d72a88deb59776794/orjson-3.11.7-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/9d/7e/c4de2babef2c0817fd1f048fd176aa48c37bec8aef53d2fa932983032cce/orjson-3.11.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/eb/74/233d360632bafd2197f217eee7fb9c9d0229eac0c18128aee5b35b0014fe/orjson-3.11.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/79/51/af79504981dd31efe20a9e360eb49c15f06df2b40e7f25a0a52d9ae888e8/orjson-3.11.7-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/67/e2/da898eb68b72304f8de05ca6715870d09d603ee98d30a27e8a9629abc64b/orjson-3.11.7-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/c5/89/15364d92acb3d903b029e28d834edb8780c2b97404cbf7929aa6b9abdb24/orjson-3.11.7-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c2/8b/ecdad52d0b38d4b8f514be603e69ccd5eacf4e7241f972e37e79792212ec/orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b9/0e/45e1dcf10e17d0924b7c9162f87ec7b4ca79e28a0548acf6a71788d3e108/orjson-3.11.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/63/d7/4d2e8b03561257af0450f2845b91fbd111d7e526ccdf737267108075e0ba/orjson-3.11.7-cp314-cp314-musllinux_1_2_armv7l.whl",hashes = {sha256 = "23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/78/cf/d45343518282108b29c12a65892445fc51f9319dc3c552ceb51bb5905ed2/orjson-3.11.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a9/3a/d6001f51a7275aacd342e77b735c71fa04125a3f93c36fee4526bc8c654e/orjson-3.11.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2"}}, + {name = "orjson-3.11.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/1d/d3/f19b47ce16820cc2c480f7f1723e17f6d411b3a295c60c8ad3aa9ff1c96a/orjson-3.11.7-cp314-cp314-win32.whl",hashes = {sha256 = "89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576"}}, + {name = "orjson-3.11.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/12/df/172771902943af54bf661a8d102bdf2e7f932127968080632bda6054b62c/orjson-3.11.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1"}}, + {name = "orjson-3.11.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/6f/1c/f2a8d8a1b17514660a614ce5f7aac74b934e69f5abc2700cc7ced882a009/orjson-3.11.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d"}}, + {name = "orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/89/25/6e0e52cac5aab51d7b6dcd257e855e1dec1c2060f6b28566c509b4665f62/orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733"}}, + {name = "orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/29/a77f48d2fc8a05bbc529e5ff481fb43d914f9e383ea2469d4f3d51df3d00/orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/25/0a16e0729a0e6a1504f9d1a13cdd365f030068aab64cec6958396b9969d7/orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/66/da/a2e505469d60666a05ab373f1a6322eb671cb2ba3a0ccfc7d4bc97196787/orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/23/bf/ed73f88396ea35c71b38961734ea4a4746f7ca0768bf28fd551d37e48dd0/orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/73/3c/b05d80716f0225fc9008fbf8ab22841dcc268a626aa550561743714ce3bf/orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/61/e8/0be9b0addd9bf86abfc938e97441dcd0375d494594b1c8ad10fe57479617/orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c9/ec/c68e3b9021a31d9ec15a94931db1410136af862955854ed5dd7e7e4f5bff/orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d2/45/f3466739aaafa570cc8e77c6dbb853c48bf56e3b43738020e2661e08b0ac/orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/e1/84/9f7f02288da1ffb31405c1be07657afd1eecbcb4b64ee2817b6fe0f785fa/orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",hashes = {sha256 = "ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/18/07/9dd2f0c0104f1a0295ffbe912bc8d63307a539b900dd9e2c48ef7810d971/orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/66/857a8e4a3292e1f7b1b202883bcdeb43a91566cf59a93f97c53b44bd6801/orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223"}}, + {name = "orjson-3.11.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/0a/5b/6ebcf3defc1aab3a338ca777214966851e92efb1f30dc7fc8285216e6d1b/orjson-3.11.7-cp313-cp313-win32.whl",hashes = {sha256 = "7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3"}}, + {name = "orjson-3.11.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/00/04/c6f72daca5092e3117840a1b1e88dfc809cc1470cf0734890d0366b684a1/orjson-3.11.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757"}}, + {name = "orjson-3.11.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/03/ba/077a0f6f1085d6b806937246860fafbd5b17f3919c70ee3f3d8d9c713f38/orjson-3.11.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -226,28 +238,27 @@ dependencies = [] [[packages]] name = "psycopg" -version = "3.2.10" -requires-python = ">=3.8" -sdist = {name = "psycopg-3.2.10.tar.gz", url = "https://files.pythonhosted.org/packages/a9/f1/0258a123c045afaf3c3b60c22ccff077bceeb24b8dc2c593270899353bd0/psycopg-3.2.10.tar.gz", hashes = {sha256 = "0bce99269d16ed18401683a8569b2c5abd94f72f8364856d56c0389bcd50972a"}} +version = "3.3.2" +requires-python = ">=3.10" +sdist = {name = "psycopg-3.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/e0/1a/7d9ef4fdc13ef7f15b934c393edc97a35c281bb7d3c3329fbfcbe915a7c2/psycopg-3.3.2.tar.gz", hashes = {sha256 = "707a67975ee214d200511177a6a80e56e654754c9afca06a7194ea6bbfde9ca7"}} wheels = [ - {name = "psycopg-3.2.10-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/4a/90/422ffbbeeb9418c795dae2a768db860401446af0c6768bc061ce22325f58/psycopg-3.2.10-py3-none-any.whl",hashes = {sha256 = "ab5caf09a9ec42e314a21f5216dbcceac528e0e05142e42eea83a3b28b320ac3"}}, + {name = "psycopg-3.3.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8c/51/2779ccdf9305981a06b21a6b27e8547c948d85c41c76ff434192784a4c93/psycopg-3.3.2-py3-none-any.whl",hashes = {sha256 = "3e94bc5f4690247d734599af56e51bae8e0db8e4311ea413f801fef82b14a99b"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ - "backports-zoneinfo>=0.2.0; python_version < \"3.9\"", "typing-extensions>=4.6; python_version < \"3.13\"", "tzdata; sys_platform == \"win32\"", ] [[packages]] name = "pytest" -version = "8.4.2" -requires-python = ">=3.9" -sdist = {name = "pytest-8.4.2.tar.gz", url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hashes = {sha256 = "86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}} +version = "9.0.2" +requires-python = ">=3.10" +sdist = {name = "pytest-9.0.2.tar.gz", url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hashes = {sha256 = "75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"}} wheels = [ - {name = "pytest-8.4.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl",hashes = {sha256 = "872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}}, + {name = "pytest-9.0.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl",hashes = {sha256 = "711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}}, ] marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" @@ -255,8 +266,8 @@ marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" dependencies = [ "colorama>=0.4; sys_platform == \"win32\"", "exceptiongroup>=1; python_version < \"3.11\"", - "iniconfig>=1", - "packaging>=20", + "iniconfig>=1.0.1", + "packaging>=22", "pluggy<2,>=1.5", "pygments>=2.7.2", "tomli>=1; python_version < \"3.11\"", @@ -281,26 +292,27 @@ dependencies = [ [[packages]] name = "tqdm" -version = "4.67.1" +version = "4.67.3" requires-python = ">=3.7" -sdist = {name = "tqdm-4.67.1.tar.gz", url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hashes = {sha256 = "f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}} +sdist = {name = "tqdm-4.67.3.tar.gz", url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hashes = {sha256 = "7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb"}} wheels = [ - {name = "tqdm-4.67.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl",hashes = {sha256 = "26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}}, + {name = "tqdm-4.67.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl",hashes = {sha256 = "ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ "colorama; platform_system == \"Windows\"", + "importlib-metadata; python_version < \"3.8\"", ] [[packages]] name = "types-tqdm" -version = "4.67.0.20250809" +version = "4.67.3.20260205" requires-python = ">=3.9" -sdist = {name = "types_tqdm-4.67.0.20250809.tar.gz", url = "https://files.pythonhosted.org/packages/fb/d0/cf498fc630d9fdaf2428b93e60b0e67b08008fec22b78716b8323cf644dc/types_tqdm-4.67.0.20250809.tar.gz", hashes = {sha256 = "02bf7ab91256080b9c4c63f9f11b519c27baaf52718e5fdab9e9606da168d500"}} +sdist = {name = "types_tqdm-4.67.3.20260205.tar.gz", url = "https://files.pythonhosted.org/packages/53/46/790b9872523a48163bdda87d47849b4466017640e5259d06eed539340afd/types_tqdm-4.67.3.20260205.tar.gz", hashes = {sha256 = "f3023682d4aa3bbbf908c8c6bb35f35692d319460d9bbd3e646e8852f3dd9f85"}} wheels = [ - {name = "types_tqdm-4.67.0.20250809-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3f/13/3ff0781445d7c12730befce0fddbbc7a76e56eb0e7029446f2853238360a/types_tqdm-4.67.0.20250809-py3-none-any.whl",hashes = {sha256 = "1a73053b31fcabf3c1f3e2a9d5ecdba0f301bde47a418cd0e0bdf774827c5c57"}}, + {name = "types_tqdm-4.67.3.20260205-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl",hashes = {sha256 = "85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173"}}, ] marker = "python_version >= \"3.13\" and \"types\" in dependency_groups" @@ -384,11 +396,11 @@ dependencies = [] [[packages]] name = "httpx-retries" -version = "0.4.2" +version = "0.4.5" requires-python = ">=3.9" -sdist = {name = "httpx_retries-0.4.2.tar.gz", url = "https://files.pythonhosted.org/packages/9e/32/37cd73ca29912cc572cec2a79b09cb719786d22e37bf02140bc750d34b36/httpx_retries-0.4.2.tar.gz", hashes = {sha256 = "8c32b781cf18dc9d67fc380792bf465cde107831ec1c1c504a7df6c80f06536c"}} +sdist = {name = "httpx_retries-0.4.5.tar.gz", url = "https://files.pythonhosted.org/packages/22/40/b9b5e4c16fb86d2999840bb795b28670a61856c7f48f030530b412bf4133/httpx_retries-0.4.5.tar.gz", hashes = {sha256 = "acee306d7384eefad71ac12fefe8b13d7b41c19595c538e68d9bd7e40e59539d"}} wheels = [ - {name = "httpx_retries-0.4.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a4/73/0700c81ad08787e2648de8ae69c046bdfee865216187bdd43cb2ba35b36c/httpx_retries-0.4.2-py3-none-any.whl",hashes = {sha256 = "0393e2ee1ab7a90aa748733cc8fe8ff722f21f282fc8f8780369089918cec994"}}, + {name = "httpx_retries-0.4.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/0a/2626b5a2678f8072ba3174d3e40f81429fdc41d1cb993280dbc7ba3c4e3f/httpx_retries-0.4.5-py3-none-any.whl",hashes = {sha256 = "ae22d6ef197a2da49242246a01d721474cbd6516b1fef155f6da694ee410bb37"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -399,11 +411,11 @@ dependencies = [ [[packages]] name = "iniconfig" -version = "2.1.0" -requires-python = ">=3.8" -sdist = {name = "iniconfig-2.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hashes = {sha256 = "3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}} +version = "2.3.0" +requires-python = ">=3.10" +sdist = {name = "iniconfig-2.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hashes = {sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}} wheels = [ - {name = "iniconfig-2.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl",hashes = {sha256 = "9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}}, + {name = "iniconfig-2.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl",hashes = {sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}}, ] marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" @@ -439,11 +451,11 @@ dependencies = [] [[packages]] name = "packaging" -version = "25.0" +version = "26.0" requires-python = ">=3.8" -sdist = {name = "packaging-25.0.tar.gz", url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hashes = {sha256 = "d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}} +sdist = {name = "packaging-26.0.tar.gz", url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hashes = {sha256 = "00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}} wheels = [ - {name = "packaging-25.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl",hashes = {sha256 = "29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}}, + {name = "packaging-26.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl",hashes = {sha256 = "b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}}, ] marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" @@ -452,11 +464,11 @@ dependencies = [] [[packages]] name = "pathspec" -version = "0.12.1" -requires-python = ">=3.8" -sdist = {name = "pathspec-0.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hashes = {sha256 = "a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}} +version = "1.0.4" +requires-python = ">=3.9" +sdist = {name = "pathspec-1.0.4.tar.gz", url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hashes = {sha256 = "0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645"}} wheels = [ - {name = "pathspec-0.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl",hashes = {sha256 = "a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}}, + {name = "pathspec-1.0.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl",hashes = {sha256 = "fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}}, ] marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" @@ -478,42 +490,14 @@ dependencies = [] [[packages]] name = "ruamel-yaml" -version = "0.18.15" -requires-python = ">=3.8" -sdist = {name = "ruamel.yaml-0.18.15.tar.gz", url = "https://files.pythonhosted.org/packages/3e/db/f3950f5e5031b618aae9f423a39bf81a55c148aecd15a34527898e752cf4/ruamel.yaml-0.18.15.tar.gz", hashes = {sha256 = "dbfca74b018c4c3fba0b9cc9ee33e53c371194a9000e694995e620490fd40700"}} +version = "0.19.1" +requires-python = ">=3.9" +sdist = {name = "ruamel_yaml-0.19.1.tar.gz", url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hashes = {sha256 = "53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993"}} wheels = [ - {name = "ruamel.yaml-0.18.15-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d1/e5/f2a0621f1781b76a38194acae72f01e37b1941470407345b6e8653ad7640/ruamel.yaml-0.18.15-py3-none-any.whl",hashes = {sha256 = "148f6488d698b7a5eded5ea793a025308b25eca97208181b6a026037f391f701"}}, + {name = "ruamel_yaml-0.19.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl",hashes = {sha256 = "27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93"}}, ] marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" -[packages.tool.pdm] -dependencies = [ - "ruamel-yaml-clib>=0.2.7; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", -] - -[[packages]] -name = "ruamel-yaml-clib" -version = "0.2.14" -requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.14.tar.gz", url = "https://files.pythonhosted.org/packages/d8/e9/39ec4d4b3f91188fad1842748f67d4e749c77c37e353c4e545052ee8e893/ruamel.yaml.clib-0.2.14.tar.gz", hashes = {sha256 = "803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/21/e2/a59ff65c26aaf21a24eb38df777cb9af5d87ba8fc8107c163c2da9d1e85e/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "7df6f6e9d0e33c7b1d435defb185095386c469109de723d514142632a7b9d07f"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6b/fa/3234f913fe9a6525a7b97c6dad1f51e72b917e6872e051a5e2ffd8b16fbb/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "70eda7703b8126f5e52fcf276e6c0f40b0d314674f896fc58c47b0aef2b9ae83"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/ec/4edbf17ac2c87fa0845dd366ef8d5852b96eb58fcd65fc1ecf5fe27b4641/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "a0cb71ccc6ef9ce36eecb6272c81afdc2f565950cdcec33ae8e6cd8f7fc86f27"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/18/b0e1fafe59051de9e79cdd431863b03593ecfa8341c110affad7c8121efc/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e7cb9ad1d525d40f7d87b6df7c0ff916a66bc52cb61b66ac1b2a16d0c1b07640"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/d7/ae/e3811f05415594025e96000349d3400978adaed88d8f98d494352d9761ee/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/06/7d51f4688d6d72bb72fa74254e1593c4f5ebd0036be5b41fe39315b275e9/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/08/b4499234a420ef42960eeb05585df5cc7eb25ccb8c980490b079e6367050/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/ba/1975a27dedf1c4c33306ee67c948121be8710b19387aada29e2f139c43ee/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/20/15/8a19a13d27f3bd09fa18813add8380a29115a47b553845f08802959acbce/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/19/ee/8d6146a079ad21e534b5083c9ee4a4c8bec42f79cf87594b60978286b39a/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a9/f5/426b714abdc222392e68f3b8ad323930d05a214a27c7e7a0f06c69126401/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",hashes = {sha256 = "f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",hashes = {sha256 = "090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78"}}, -] -marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and python_version >= \"3.13\" and \"lint\" in dependency_groups" - [packages.tool.pdm] dependencies = [] @@ -532,11 +516,11 @@ dependencies = [] [[packages]] name = "anyio" -version = "4.11.0" +version = "4.12.1" requires-python = ">=3.9" -sdist = {name = "anyio-4.11.0.tar.gz", url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hashes = {sha256 = "82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}} +sdist = {name = "anyio-4.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hashes = {sha256 = "41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703"}} wheels = [ - {name = "anyio-4.11.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl",hashes = {sha256 = "0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}}, + {name = "anyio-4.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl",hashes = {sha256 = "d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -544,30 +528,16 @@ marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" dependencies = [ "exceptiongroup>=1.0.2; python_version < \"3.11\"", "idna>=2.8", - "sniffio>=1.1", "typing-extensions>=4.5; python_version < \"3.13\"", ] [[packages]] name = "idna" -version = "3.10" -requires-python = ">=3.6" -sdist = {name = "idna-3.10.tar.gz", url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hashes = {sha256 = "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}} -wheels = [ - {name = "idna-3.10-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl",hashes = {sha256 = "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}}, -] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sniffio" -version = "1.3.1" -requires-python = ">=3.7" -sdist = {name = "sniffio-1.3.1.tar.gz", url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hashes = {sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}} +version = "3.11" +requires-python = ">=3.8" +sdist = {name = "idna-3.11.tar.gz", url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hashes = {sha256 = "795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}} wheels = [ - {name = "sniffio-1.3.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl",hashes = {sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}}, + {name = "idna-3.11-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl",hashes = {sha256 = "771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -576,11 +546,11 @@ dependencies = [] [[packages]] name = "certifi" -version = "2025.8.3" +version = "2026.1.4" requires-python = ">=3.7" -sdist = {name = "certifi-2025.8.3.tar.gz", url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hashes = {sha256 = "e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}} +sdist = {name = "certifi-2026.1.4.tar.gz", url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hashes = {sha256 = "ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}} wheels = [ - {name = "certifi-2025.8.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl",hashes = {sha256 = "f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}}, + {name = "certifi-2026.1.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl",hashes = {sha256 = "9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}}, ] marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -605,11 +575,11 @@ dependencies = [ [[packages]] name = "types-requests" -version = "2.32.4.20250913" +version = "2.32.4.20260107" requires-python = ">=3.9" -sdist = {name = "types_requests-2.32.4.20250913.tar.gz", url = "https://files.pythonhosted.org/packages/36/27/489922f4505975b11de2b5ad07b4fe1dca0bca9be81a703f26c5f3acfce5/types_requests-2.32.4.20250913.tar.gz", hashes = {sha256 = "abd6d4f9ce3a9383f269775a9835a4c24e5cd6b9f647d64f88aa4613c33def5d"}} +sdist = {name = "types_requests-2.32.4.20260107.tar.gz", url = "https://files.pythonhosted.org/packages/0f/f3/a0663907082280664d745929205a89d41dffb29e89a50f753af7d57d0a96/types_requests-2.32.4.20260107.tar.gz", hashes = {sha256 = "018a11ac158f801bfa84857ddec1650750e393df8a004a8a9ae2a9bec6fcb24f"}} wheels = [ - {name = "types_requests-2.32.4.20250913-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2a/20/9a227ea57c1285986c4cf78400d0a91615d25b24e257fd9e2969606bdfae/types_requests-2.32.4.20250913-py3-none-any.whl",hashes = {sha256 = "78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1"}}, + {name = "types_requests-2.32.4.20260107-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1c/12/709ea261f2bf91ef0a26a9eed20f2623227a8ed85610c1e54c5805692ecb/types_requests-2.32.4.20260107-py3-none-any.whl",hashes = {sha256 = "b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d"}}, ] marker = "python_version >= \"3.13\" and \"types\" in dependency_groups" @@ -620,11 +590,11 @@ dependencies = [ [[packages]] name = "urllib3" -version = "2.5.0" +version = "2.6.3" requires-python = ">=3.9" -sdist = {name = "urllib3-2.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hashes = {sha256 = "3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}} +sdist = {name = "urllib3-2.6.3.tar.gz", url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hashes = {sha256 = "1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}} wheels = [ - {name = "urllib3-2.5.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl",hashes = {sha256 = "e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}}, + {name = "urllib3-2.6.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl",hashes = {sha256 = "bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}}, ] marker = "python_version >= \"3.13\" and \"types\" in dependency_groups" @@ -633,11 +603,11 @@ dependencies = [] [[packages]] name = "tzdata" -version = "2025.2" +version = "2025.3" requires-python = ">=2" -sdist = {name = "tzdata-2025.2.tar.gz", url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hashes = {sha256 = "b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}} +sdist = {name = "tzdata-2025.3.tar.gz", url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hashes = {sha256 = "de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7"}} wheels = [ - {name = "tzdata-2025.2-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl",hashes = {sha256 = "1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}}, + {name = "tzdata-2025.3-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl",hashes = {sha256 = "06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}}, ] marker = "sys_platform == \"win32\" and python_version >= \"3.13\" and \"default\" in dependency_groups" @@ -645,7 +615,7 @@ marker = "sys_platform == \"win32\" and python_version >= \"3.13\" and \"default dependencies = [] [tool.pdm] -hashes = {sha256 = "a3b22dcb6e46e060513881b655a5824b61606a56fcce33d669d58321ed9c947f"} +hashes = {sha256 = "0c0e9208d38f65d8253d8fa6094d6d32dd41f91a12e3ab69ff765e694312f812"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.minimal.toml b/pylock.minimal.toml index 4cc3ad0..6dd6a47 100644 --- a/pylock.minimal.toml +++ b/pylock.minimal.toml @@ -237,11 +237,11 @@ dependencies = [] [[packages]] name = "httpx-folio" -version = "0.2.3" +version = "0.3.0" requires-python = ">=3.9" -sdist = {name = "httpx_folio-0.2.3.tar.gz", url = "https://files.pythonhosted.org/packages/72/07/727a73827674a6a91db6a58ac492703d6d0efe9a5f14d856aff9b434fe65/httpx_folio-0.2.3.tar.gz", hashes = {sha256 = "8c4afd55231e1a645c824a7ffa63ebc1b0261223e5d6b65101ab639a6a0a54dd"}} +sdist = {name = "httpx_folio-0.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/87/23/dd3f9ade71ace5a4b0343388792aa1bf8892f95ddf7217d82c0182f14c59/httpx_folio-0.3.0.tar.gz", hashes = {sha256 = "436778fb1bffb3327393bd5b809e7f38a2fd9fdfc8fea71a0a47fe2e0dbae2f2"}} wheels = [ - {name = "httpx_folio-0.2.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/34/3c/b5333a57399d8c787efb2c90d9accb6ddf22523fcec3404814b0eb10bb8a/httpx_folio-0.2.3-py3-none-any.whl",hashes = {sha256 = "e319cc8cf3e0443982655a6012017e36af112e58081b050b40048052b039b6e9"}}, + {name = "httpx_folio-0.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5a/91/2ab3ee8588e5eab7808be5c3b1ea8fb3515f07686cddf49cbcde40885b3d/httpx_folio-0.3.0-py3-none-any.whl",hashes = {sha256 = "5396438eb07257db7c080382f65711b01b93eab3b2adc420a5855be3007c37ae"}}, ] marker = "\"default\" in dependency_groups" @@ -366,41 +366,56 @@ dependencies = [] [[packages]] name = "tomli" -version = "2.2.1" +version = "2.4.0" requires-python = ">=3.8" -sdist = {name = "tomli-2.2.1.tar.gz", url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hashes = {sha256 = "cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}} -wheels = [ - {name = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}}, - {name = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}}, - {name = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}}, - {name = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}}, - {name = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}}, - {name = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}}, - {name = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}}, - {name = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}}, - {name = "tomli-2.2.1-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl",hashes = {sha256 = "d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}}, - {name = "tomli-2.2.1-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl",hashes = {sha256 = "a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}}, - {name = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}}, - {name = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}}, - {name = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}}, - {name = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}}, - {name = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}}, - {name = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}}, - {name = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}}, - {name = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}}, - {name = "tomli-2.2.1-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl",hashes = {sha256 = "889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}}, - {name = "tomli-2.2.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}}, - {name = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}}, - {name = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}}, - {name = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}}, - {name = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}}, - {name = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}}, - {name = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}}, - {name = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}}, - {name = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}}, - {name = "tomli-2.2.1-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl",hashes = {sha256 = "465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}}, - {name = "tomli-2.2.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}}, - {name = "tomli-2.2.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl",hashes = {sha256 = "cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}}, +sdist = {name = "tomli-2.4.0.tar.gz", url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hashes = {sha256 = "aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}} +wheels = [ + {name = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}}, + {name = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}}, + {name = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}}, + {name = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}}, + {name = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}}, + {name = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}}, + {name = "tomli-2.4.0-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl",hashes = {sha256 = "31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}}, + {name = "tomli-2.4.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}}, + {name = "tomli-2.4.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}}, + {name = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}}, + {name = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}}, + {name = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}}, + {name = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}}, + {name = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}}, + {name = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}}, + {name = "tomli-2.4.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl",hashes = {sha256 = "d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}}, + {name = "tomli-2.4.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}}, + {name = "tomli-2.4.0-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}}, + {name = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}}, + {name = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}}, + {name = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}}, + {name = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}}, + {name = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}}, + {name = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}}, + {name = "tomli-2.4.0-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl",hashes = {sha256 = "7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}}, + {name = "tomli-2.4.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}}, + {name = "tomli-2.4.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}}, + {name = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}}, + {name = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}}, + {name = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}}, + {name = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}}, + {name = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}}, + {name = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}}, + {name = "tomli-2.4.0-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl",hashes = {sha256 = "0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}}, + {name = "tomli-2.4.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}}, + {name = "tomli-2.4.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}}, + {name = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}}, + {name = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}}, + {name = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}}, + {name = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}}, + {name = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}}, + {name = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}}, + {name = "tomli-2.4.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl",hashes = {sha256 = "b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}}, + {name = "tomli-2.4.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}}, + {name = "tomli-2.4.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}}, + {name = "tomli-2.4.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl",hashes = {sha256 = "1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}}, ] marker = "\"lint\" in dependency_groups and python_version < \"3.11\" or \"test\" in dependency_groups and python_version < \"3.11\"" @@ -448,11 +463,11 @@ dependencies = [] [[packages]] name = "exceptiongroup" -version = "1.3.0" +version = "1.3.1" requires-python = ">=3.7" -sdist = {name = "exceptiongroup-1.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hashes = {sha256 = "b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}} +sdist = {name = "exceptiongroup-1.3.1.tar.gz", url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hashes = {sha256 = "8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}} wheels = [ - {name = "exceptiongroup-1.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl",hashes = {sha256 = "4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}}, + {name = "exceptiongroup-1.3.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl",hashes = {sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}}, ] marker = "\"default\" in dependency_groups and python_version < \"3.11\" or \"test\" in dependency_groups and python_version < \"3.11\"" @@ -510,11 +525,11 @@ dependencies = [] [[packages]] name = "httpx-retries" -version = "0.4.2" +version = "0.4.5" requires-python = ">=3.9" -sdist = {name = "httpx_retries-0.4.2.tar.gz", url = "https://files.pythonhosted.org/packages/9e/32/37cd73ca29912cc572cec2a79b09cb719786d22e37bf02140bc750d34b36/httpx_retries-0.4.2.tar.gz", hashes = {sha256 = "8c32b781cf18dc9d67fc380792bf465cde107831ec1c1c504a7df6c80f06536c"}} +sdist = {name = "httpx_retries-0.4.5.tar.gz", url = "https://files.pythonhosted.org/packages/22/40/b9b5e4c16fb86d2999840bb795b28670a61856c7f48f030530b412bf4133/httpx_retries-0.4.5.tar.gz", hashes = {sha256 = "acee306d7384eefad71ac12fefe8b13d7b41c19595c538e68d9bd7e40e59539d"}} wheels = [ - {name = "httpx_retries-0.4.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a4/73/0700c81ad08787e2648de8ae69c046bdfee865216187bdd43cb2ba35b36c/httpx_retries-0.4.2-py3-none-any.whl",hashes = {sha256 = "0393e2ee1ab7a90aa748733cc8fe8ff722f21f282fc8f8780369089918cec994"}}, + {name = "httpx_retries-0.4.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/0a/2626b5a2678f8072ba3174d3e40f81429fdc41d1cb993280dbc7ba3c4e3f/httpx_retries-0.4.5-py3-none-any.whl",hashes = {sha256 = "ae22d6ef197a2da49242246a01d721474cbd6516b1fef155f6da694ee410bb37"}}, ] marker = "\"default\" in dependency_groups" @@ -525,11 +540,11 @@ dependencies = [ [[packages]] name = "iniconfig" -version = "2.1.0" -requires-python = ">=3.8" -sdist = {name = "iniconfig-2.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hashes = {sha256 = "3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}} +version = "2.3.0" +requires-python = ">=3.10" +sdist = {name = "iniconfig-2.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hashes = {sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}} wheels = [ - {name = "iniconfig-2.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl",hashes = {sha256 = "9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}}, + {name = "iniconfig-2.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl",hashes = {sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}}, ] marker = "\"test\" in dependency_groups" @@ -565,11 +580,11 @@ dependencies = [] [[packages]] name = "packaging" -version = "25.0" +version = "26.0" requires-python = ">=3.8" -sdist = {name = "packaging-25.0.tar.gz", url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hashes = {sha256 = "d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}} +sdist = {name = "packaging-26.0.tar.gz", url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hashes = {sha256 = "00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}} wheels = [ - {name = "packaging-25.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl",hashes = {sha256 = "29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}}, + {name = "packaging-26.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl",hashes = {sha256 = "b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}}, ] marker = "\"test\" in dependency_groups" @@ -578,11 +593,11 @@ dependencies = [] [[packages]] name = "pathspec" -version = "0.12.1" -requires-python = ">=3.8" -sdist = {name = "pathspec-0.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hashes = {sha256 = "a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}} +version = "1.0.4" +requires-python = ">=3.9" +sdist = {name = "pathspec-1.0.4.tar.gz", url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hashes = {sha256 = "0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645"}} wheels = [ - {name = "pathspec-0.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl",hashes = {sha256 = "a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}}, + {name = "pathspec-1.0.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl",hashes = {sha256 = "fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}}, ] marker = "\"lint\" in dependency_groups" @@ -604,82 +619,24 @@ dependencies = [] [[packages]] name = "ruamel-yaml" -version = "0.18.15" -requires-python = ">=3.8" -sdist = {name = "ruamel.yaml-0.18.15.tar.gz", url = "https://files.pythonhosted.org/packages/3e/db/f3950f5e5031b618aae9f423a39bf81a55c148aecd15a34527898e752cf4/ruamel.yaml-0.18.15.tar.gz", hashes = {sha256 = "dbfca74b018c4c3fba0b9cc9ee33e53c371194a9000e694995e620490fd40700"}} +version = "0.19.1" +requires-python = ">=3.9" +sdist = {name = "ruamel_yaml-0.19.1.tar.gz", url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hashes = {sha256 = "53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993"}} wheels = [ - {name = "ruamel.yaml-0.18.15-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d1/e5/f2a0621f1781b76a38194acae72f01e37b1941470407345b6e8653ad7640/ruamel.yaml-0.18.15-py3-none-any.whl",hashes = {sha256 = "148f6488d698b7a5eded5ea793a025308b25eca97208181b6a026037f391f701"}}, + {name = "ruamel_yaml-0.19.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl",hashes = {sha256 = "27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93"}}, ] marker = "\"lint\" in dependency_groups" -[packages.tool.pdm] -dependencies = [ - "ruamel-yaml-clib>=0.2.7; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", -] - -[[packages]] -name = "ruamel-yaml-clib" -version = "0.2.14" -requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.14.tar.gz", url = "https://files.pythonhosted.org/packages/d8/e9/39ec4d4b3f91188fad1842748f67d4e749c77c37e353c4e545052ee8e893/ruamel.yaml.clib-0.2.14.tar.gz", hashes = {sha256 = "803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/21/e2/a59ff65c26aaf21a24eb38df777cb9af5d87ba8fc8107c163c2da9d1e85e/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "7df6f6e9d0e33c7b1d435defb185095386c469109de723d514142632a7b9d07f"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6b/fa/3234f913fe9a6525a7b97c6dad1f51e72b917e6872e051a5e2ffd8b16fbb/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "70eda7703b8126f5e52fcf276e6c0f40b0d314674f896fc58c47b0aef2b9ae83"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/ec/4edbf17ac2c87fa0845dd366ef8d5852b96eb58fcd65fc1ecf5fe27b4641/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "a0cb71ccc6ef9ce36eecb6272c81afdc2f565950cdcec33ae8e6cd8f7fc86f27"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/18/b0e1fafe59051de9e79cdd431863b03593ecfa8341c110affad7c8121efc/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e7cb9ad1d525d40f7d87b6df7c0ff916a66bc52cb61b66ac1b2a16d0c1b07640"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/d7/ae/e3811f05415594025e96000349d3400978adaed88d8f98d494352d9761ee/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/06/7d51f4688d6d72bb72fa74254e1593c4f5ebd0036be5b41fe39315b275e9/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/08/b4499234a420ef42960eeb05585df5cc7eb25ccb8c980490b079e6367050/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/ba/1975a27dedf1c4c33306ee67c948121be8710b19387aada29e2f139c43ee/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/20/15/8a19a13d27f3bd09fa18813add8380a29115a47b553845f08802959acbce/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/19/ee/8d6146a079ad21e534b5083c9ee4a4c8bec42f79cf87594b60978286b39a/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a9/f5/426b714abdc222392e68f3b8ad323930d05a214a27c7e7a0f06c69126401/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",hashes = {sha256 = "f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",hashes = {sha256 = "090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/42/ccfb34a25289afbbc42017e4d3d4288e61d35b2e00cfc6b92974a6a1f94b/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "6aeadc170090ff1889f0d2c3057557f9cd71f975f17535c26a5d37af98f19c27"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/82/73/e628a92e80197ff6a79ab81ec3fa00d4cc082d58ab78d3337b7ba7043301/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "5e56ac47260c0eed992789fa0b8efe43404a9adb608608631a948cee4fc2b052"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/c5/346c7094344a60419764b4b1334d9e0285031c961176ff88ffb652405b0c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "a911aa73588d9a8b08d662b9484bc0567949529824a55d3885b77e8dd62a127a"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/99/65080c863eb06d4498de3d6c86f3e90595e02e159fd8529f1565f56cfe2c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a05ba88adf3d7189a974b2de7a9d56731548d35dc0a822ec3dc669caa7019b29"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/3d/e3/0de85f3e3333f8e29e4b10244374a202a87665d1131798946ee22cf05c7c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "fb04c5650de6668b853623eceadcdb1a9f2fee381f5d7b6bc842ee7c239eeec4"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d9/25/0d2f09d8833c7fd77ab8efeff213093c16856479a9d293180a0d89f6bed9/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "df3ec9959241d07bc261f4983d25a1205ff37703faf42b474f15d54d88b4f8c9"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d3/8c/959f10c2e2153cbdab834c46e6954b6dd9e3b109c8f8c0a3cf1618310985/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "fbc08c02e9b147a11dfcaa1ac8a83168b699863493e183f7c0c8b12850b7d259"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/6b/e580a7c18b485e1a5f30a32cda96b20364b0ba649d9d2baaf72f8bd21f83/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c099cafc1834d3c5dac305865d04235f7c21c167c8dd31ebc3d6bbc357e2f023"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/ef/44/3455eebc761dc8e8fdced90f2b0a3fa61e32ba38b50de4130e2d57db0f21/ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",hashes = {sha256 = "b5b0f7e294700b615a3bcf6d28b26e6da94e8eba63b079f4ec92e9ba6c0d6b54"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/76/ab/5121f7f3b651db93de546f8c982c241397aad0a4765d793aca1dac5eadee/ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",hashes = {sha256 = "a37f40a859b503304dd740686359fcf541d6fb3ff7fc10f539af7f7150917c68"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b3/9f/3c51e9578b8c36fcc4bdd271a1a5bb65963a74a4b6ad1a989768a22f6c2a/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5bae1a073ca4244620425cd3d3aa9746bde590992b98ee8c7c8be8c597ca0d4e"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/16/cb02815bc2ae9c66760c0c061d23c7358f9ba51dae95ac85247662b7fbe2/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "0a54e5e40a7a691a426c2703b09b0d61a14294d25cfacc00631aa6f9c964df0d"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/31/c6/fc687cd1b93bff8e40861eea46d6dc1a6a778d9a085684e4045ff26a8e40/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "10d9595b6a19778f3269399eff6bab642608e5966183abc2adbe558a42d4efc9"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/45/5d/65a2bc08b709b08576b3f307bf63951ee68a8e047cbbda6f1c9864ecf9a7/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "dba72975485f2b87b786075e18a6e5d07dc2b4d8973beb2732b9b2816f1bad70"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/fb/d0/a70a03614d9a6788a3661ab1538879ed2aae4e84d861f101243116308a37/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "29757bdb7c142f9595cc1b62ec49a3d1c83fab9cef92db52b0ccebaad4eafb98"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/30/c93fa457611f79946d5cb6cc97493ca5425f3f21891d7b1f9b44eaa1b38e/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "557df28dbccf79b152fe2d1b935f6063d9cc431199ea2b0e84892f35c03bb0ee"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/40/85/e2c54ad637117cd13244a4649946eaa00f32edcb882d1f92df90e079ab00/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "26a8de280ab0d22b6e3ec745b4a5a07151a0f74aad92dd76ab9c8d8d7087720d"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/50/f899072c38877d8ef5382e0b3d47f8c4346226c1f52d6945d6f64fec6a2f/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e501c096aa3889133d674605ebd018471bc404a59cbc17da3c5924421c54d97c"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/99/7c/96d4b5075e30c65ea2064e40c2d657c7c235d7b6ef18751cf89a935b9041/ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",hashes = {sha256 = "915748cfc25b8cfd81b14d00f4bfdb2ab227a30d6d43459034533f4d1c207a2a"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7d/8c/73ee2babd04e8bfcf1fd5c20aa553d18bf0ebc24b592b4f831d12ae46cc0/ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",hashes = {sha256 = "4ccba93c1e5a40af45b2f08e4591969fa4697eae951c708f3f83dcbf9f6c6bb1"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/56/35a0a752415ae01992c68f5a6513bdef0e1b6fbdb60d7619342ce12346a0/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "f8b2acb0ffdd2ce8208accbec2dca4a06937d556fdcaefd6473ba1b5daa7e3c4"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/98/6a/9a68184ab93619f4607ff1675e4ef01e8accfcbff0d482f4ca44c10d8eab/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "aef953f3b8bd0b50bd52a2e52fb54a6a2171a1889d8dea4a5959d46c6624c451"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/3f/cfed5f088628128a9ec66f46794fd4d165642155c7b78c26d83b16c6bf7b/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "a0ac90efbc7a77b0d796c03c8cc4e62fd710b3f1e4c32947713ef2ef52e09543"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/d5/5ce2cc156c1da48160171968d91f066d305840fbf930ee955a509d025a44/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9bf6b699223afe6c7fe9f2ef76e0bfa6dd892c21e94ce8c957478987ade76cd8"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2b/71/d0b56bc902b38ebe4be8e270f730f929eec4edaf8a0fa7028f4ef64fa950/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d73a0187718f6eec5b2f729b0f98e4603f7bd9c48aa65d01227d1a5dcdfbe9e8"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/db/1f37449dd89c540218598316ccafc1a0aed60215e72efa315c5367cfd015/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "81f6d3b19bc703679a5705c6a16dabdc79823c71d791d73c65949be7f3012c02"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/5d/53/c498b30f35efcd9f47cb084d7ad9374f2b907470f73913dec6396b81397d/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "b28caeaf3e670c08cb7e8de221266df8494c169bd6ed8875493fab45be9607a4"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/79/492cfad9baed68914840c39e5f3c1cc251f51a897ddb3f532601215cbb12/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "94f3efb718f8f49b031f2071ec7a27dd20cbfe511b4dfd54ecee54c956da2b31"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/ca/f5/479ebfd5ba396e209ade90f7282d84b90c57b3e07be8dc6fcd02a6df7ffc/ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",hashes = {sha256 = "27c070cf3888e90d992be75dd47292ff9aa17dafd36492812a6a304a1aedc182"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/57/31/a044520fdb3bd409889f67f1efebda0658033c7ab3f390cee37531cc9a9e/ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4f4a150a737fccae13fb51234d41304ff2222e3b7d4c8e9428ed1a6ab48389b8"}}, -] -marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and \"lint\" in dependency_groups" - [packages.tool.pdm] dependencies = [] [[packages]] name = "anyio" -version = "4.11.0" +version = "4.12.1" requires-python = ">=3.9" -sdist = {name = "anyio-4.11.0.tar.gz", url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hashes = {sha256 = "82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}} +sdist = {name = "anyio-4.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hashes = {sha256 = "41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703"}} wheels = [ - {name = "anyio-4.11.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl",hashes = {sha256 = "0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}}, + {name = "anyio-4.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl",hashes = {sha256 = "d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c"}}, ] marker = "\"default\" in dependency_groups" @@ -687,30 +644,16 @@ marker = "\"default\" in dependency_groups" dependencies = [ "exceptiongroup>=1.0.2; python_version < \"3.11\"", "idna>=2.8", - "sniffio>=1.1", "typing-extensions>=4.5; python_version < \"3.13\"", ] [[packages]] name = "idna" -version = "3.10" -requires-python = ">=3.6" -sdist = {name = "idna-3.10.tar.gz", url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hashes = {sha256 = "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}} -wheels = [ - {name = "idna-3.10-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl",hashes = {sha256 = "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sniffio" -version = "1.3.1" -requires-python = ">=3.7" -sdist = {name = "sniffio-1.3.1.tar.gz", url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hashes = {sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}} +version = "3.11" +requires-python = ">=3.8" +sdist = {name = "idna-3.11.tar.gz", url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hashes = {sha256 = "795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}} wheels = [ - {name = "sniffio-1.3.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl",hashes = {sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}}, + {name = "idna-3.11-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl",hashes = {sha256 = "771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}}, ] marker = "\"default\" in dependency_groups" @@ -719,11 +662,11 @@ dependencies = [] [[packages]] name = "certifi" -version = "2025.8.3" +version = "2026.1.4" requires-python = ">=3.7" -sdist = {name = "certifi-2025.8.3.tar.gz", url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hashes = {sha256 = "e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}} +sdist = {name = "certifi-2026.1.4.tar.gz", url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hashes = {sha256 = "ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}} wheels = [ - {name = "certifi-2025.8.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl",hashes = {sha256 = "f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}}, + {name = "certifi-2026.1.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl",hashes = {sha256 = "9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}}, ] marker = "\"default\" in dependency_groups" @@ -748,11 +691,11 @@ dependencies = [ [[packages]] name = "tzdata" -version = "2025.2" +version = "2025.3" requires-python = ">=2" -sdist = {name = "tzdata-2025.2.tar.gz", url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hashes = {sha256 = "b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}} +sdist = {name = "tzdata-2025.3.tar.gz", url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hashes = {sha256 = "de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7"}} wheels = [ - {name = "tzdata-2025.2-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl",hashes = {sha256 = "1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}}, + {name = "tzdata-2025.3-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl",hashes = {sha256 = "06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}}, ] marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" @@ -760,7 +703,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "a3b22dcb6e46e060513881b655a5824b61606a56fcce33d669d58321ed9c947f"} +hashes = {sha256 = "0c0e9208d38f65d8253d8fa6094d6d32dd41f91a12e3ab69ff765e694312f812"} strategy = ["direct_minimal_versions", "inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.toml b/pylock.toml index 742c5f0..56be3e9 100644 --- a/pylock.toml +++ b/pylock.toml @@ -146,101 +146,115 @@ dependencies = [] [[packages]] name = "coverage" -version = "7.10.7" -requires-python = ">=3.9" -sdist = {name = "coverage-7.10.7.tar.gz", url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hashes = {sha256 = "f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239"}} -wheels = [ - {name = "coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520"}}, - {name = "coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360"}}, - {name = "coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e"}}, - {name = "coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd"}}, - {name = "coverage-7.10.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl",hashes = {sha256 = "b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2"}}, - {name = "coverage-7.10.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681"}}, - {name = "coverage-7.10.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880"}}, - {name = "coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63"}}, - {name = "coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699"}}, - {name = "coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0"}}, - {name = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399"}}, - {name = "coverage-7.10.7-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl",hashes = {sha256 = "67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235"}}, - {name = "coverage-7.10.7-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d"}}, - {name = "coverage-7.10.7-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a"}}, - {name = "coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d"}}, - {name = "coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49"}}, - {name = "coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c"}}, - {name = "coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f"}}, - {name = "coverage-7.10.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl",hashes = {sha256 = "dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698"}}, - {name = "coverage-7.10.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843"}}, - {name = "coverage-7.10.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546"}}, - {name = "coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c"}}, - {name = "coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0"}}, - {name = "coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999"}}, - {name = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2"}}, - {name = "coverage-7.10.7-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl",hashes = {sha256 = "2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a"}}, - {name = "coverage-7.10.7-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb"}}, - {name = "coverage-7.10.7-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb"}}, - {name = "coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/13/e4/eb12450f71b542a53972d19117ea5a5cea1cab3ac9e31b0b5d498df1bd5a/coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "7bb3b9ddb87ef7725056572368040c32775036472d5a033679d1fa6c8dc08417"}}, - {name = "coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/37/66/593f9be12fc19fb36711f19a5371af79a718537204d16ea1d36f16bd78d2/coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "18afb24843cbc175687225cab1138c95d262337f5473512010e46831aa0c2973"}}, - {name = "coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/66/80/4c49f7ae09cafdacc73fbc30949ffe77359635c168f4e9ff33c9ebb07838/coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "399a0b6347bcd3822be369392932884b8216d0944049ae22925631a9b3d4ba4c"}}, - {name = "coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a6/90/a64aaacab3b37a17aaedd83e8000142561a29eb262cede42d94a67f7556b/coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "314f2c326ded3f4b09be11bc282eb2fc861184bc95748ae67b360ac962770be7"}}, - {name = "coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/2e/2dda59afd6103b342e096f246ebc5f87a3363b5412609946c120f4e7750d/coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c41e71c9cfb854789dee6fc51e46743a6d138b1803fab6cb860af43265b42ea6"}}, - {name = "coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/53/dc/8d8119c9051d50f3119bb4a75f29f1e4a6ab9415cd1fa8bf22fcc3fb3b5f/coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "bc01f57ca26269c2c706e838f6422e2a8788e41b3e3c65e2f41148212e57cd59"}}, - {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/b3/edaff9c5d79ee4d4b6d3fe046f2b1d799850425695b789d491a64225d493/coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a6442c59a8ac8b85812ce33bc4d05bde3fb22321fa8294e2a5b487c3505f611b"}}, - {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/11/25/9a0728564bb05863f7e513e5a594fe5ffef091b325437f5430e8cfb0d530/coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "78a384e49f46b80fb4c901d52d92abe098e78768ed829c673fbb53c498bef73a"}}, - {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/fd/ca2650443bfbef5b0e74373aac4df67b08180d2f184b482c41499668e258/coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "5e1e9802121405ede4b0133aa4340ad8186a1d2526de5b7c3eca519db7bb89fb"}}, - {name = "coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/24/79/f692f125fb4299b6f963b0745124998ebb8e73ecdfce4ceceb06a8c6bec5/coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "d41213ea25a86f69efd1575073d34ea11aabe075604ddf3d148ecfec9e1e96a1"}}, - {name = "coverage-7.10.7-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/5e/75/61b9bbd6c7d24d896bfeec57acba78e0f8deac68e6baf2d4804f7aae1f88/coverage-7.10.7-cp312-cp312-win32.whl",hashes = {sha256 = "77eb4c747061a6af8d0f7bdb31f1e108d172762ef579166ec84542f711d90256"}}, - {name = "coverage-7.10.7-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ca/f3/3bf7905288b45b075918d372498f1cf845b5b579b723c8fd17168018d5f5/coverage-7.10.7-cp312-cp312-win_amd64.whl",hashes = {sha256 = "f51328ffe987aecf6d09f3cd9d979face89a617eacdaea43e7b3080777f647ba"}}, - {name = "coverage-7.10.7-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/5c/44/3e32dbe933979d05cf2dac5e697c8599cfe038aaf51223ab901e208d5a62/coverage-7.10.7-cp312-cp312-win_arm64.whl",hashes = {sha256 = "bda5e34f8a75721c96085903c6f2197dc398c20ffd98df33f866a9c8fd95f4bf"}}, - {name = "coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/5d/c1a17867b0456f2e9ce2d8d4708a4c3a089947d0bec9c66cdf60c9e7739f/coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "a609f9c93113be646f44c2a0256d6ea375ad047005d7f57a5c15f614dc1b2f59"}}, - {name = "coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/54/f0/514dcf4b4e3698b9a9077f084429681bf3aad2b4a72578f89d7f643eb506/coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "65646bb0359386e07639c367a22cf9b5bf6304e8630b565d0626e2bdf329227a"}}, - {name = "coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/20/f6/9626b81d17e2a4b25c63ac1b425ff307ecdeef03d67c9a147673ae40dc36/coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "5f33166f0dfcce728191f520bd2692914ec70fac2713f6bf3ce59c3deacb4699"}}, - {name = "coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/b0/ef/bd8e719c2f7417ba03239052e099b76ea1130ac0cbb183ee1fcaa58aaff3/coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "35f5e3f9e455bb17831876048355dca0f758b6df22f49258cb5a91da23ef437d"}}, - {name = "coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a5/b6/bf054de41ec948b151ae2b79a55c107f5760979538f5fb80c195f2517718/coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4da86b6d62a496e908ac2898243920c7992499c1712ff7c2b6d837cc69d9467e"}}, - {name = "coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/0f/e5/3860756aa6f9318227443c6ce4ed7bf9e70bb7f1447a0353f45ac5c7974b/coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "6b8b09c1fad947c84bbbc95eca841350fad9cbfa5a2d7ca88ac9f8d836c92e23"}}, - {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/26/0f/bd08bd042854f7fd07b45808927ebcce99a7ed0f2f412d11629883517ac2/coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4376538f36b533b46f8971d3a3e63464f2c7905c9800db97361c43a2b14792ab"}}, - {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/8e/a7/4777b14de4abcc2e80c6b1d430f5d51eb18ed1d75fca56cbce5f2db9b36e/coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "121da30abb574f6ce6ae09840dae322bef734480ceafe410117627aa54f76d82"}}, - {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/34/72/17d082b00b53cd45679bad682fac058b87f011fd8b9fe31d77f5f8d3a4e4/coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "88127d40df529336a9836870436fc2751c339fbaed3a836d42c93f3e4bd1d0a2"}}, - {name = "coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/7a/92367572eb5bdd6a84bfa278cc7e97db192f9f45b28c94a9ca1a921c3577/coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ba58bbcd1b72f136080c0bccc2400d66cc6115f3f906c499013d065ac33a4b61"}}, - {name = "coverage-7.10.7-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/2f/88/a23cc185f6a805dfc4fdf14a94016835eeb85e22ac3a0e66d5e89acd6462/coverage-7.10.7-cp311-cp311-win32.whl",hashes = {sha256 = "972b9e3a4094b053a4e46832b4bc829fc8a8d347160eb39d03f1690316a99c14"}}, - {name = "coverage-7.10.7-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fe/ef/0b510a399dfca17cec7bc2f05ad8bd78cf55f15c8bc9a73ab20c5c913c2e/coverage-7.10.7-cp311-cp311-win_amd64.whl",hashes = {sha256 = "a7b55a944a7f43892e28ad4bc0561dfd5f0d73e605d1aa5c3c976b52aea121d2"}}, - {name = "coverage-7.10.7-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/7f/023657f301a276e4ba1850f82749bc136f5a7e8768060c2e5d9744a22951/coverage-7.10.7-cp311-cp311-win_arm64.whl",hashes = {sha256 = "736f227fb490f03c6488f9b6d45855f8e0fd749c007f9303ad30efab0e73c05a"}}, - {name = "coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/e5/6c/3a3f7a46888e69d18abe3ccc6fe4cb16cccb1e6a2f99698931dafca489e6/coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "fc04cc7a3db33664e0c2d10eb8990ff6b3536f6842c9590ae8da4c614b9ed05a"}}, - {name = "coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/03/94/952d30f180b1a916c11a56f5c22d3535e943aa22430e9e3322447e520e1c/coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "e201e015644e207139f7e2351980feb7040e6f4b2c2978892f3e3789d1c125e5"}}, - {name = "coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/50/2b/9e0cf8ded1e114bcd8b2fd42792b57f1c4e9e4ea1824cde2af93a67305be/coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "240af60539987ced2c399809bd34f7c78e8abe0736af91c3d7d0e795df633d17"}}, - {name = "coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/19/20/d0384ac06a6f908783d9b6aa6135e41b093971499ec488e47279f5b846e6/coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8421e088bc051361b01c4b3a50fd39a4b9133079a2229978d9d30511fd05231b"}}, - {name = "coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/60/83/5c283cff3d41285f8eab897651585db908a909c572bdc014bcfaf8a8b6ae/coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6be8ed3039ae7f7ac5ce058c308484787c86e8437e72b30bf5e88b8ea10f3c87"}}, - {name = "coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/60/22/02eb98fdc5ff79f423e990d877693e5310ae1eab6cb20ae0b0b9ac45b23b/coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e28299d9f2e889e6d51b1f043f58d5f997c373cc12e6403b90df95b8b047c13e"}}, - {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b4/bc/25c83bcf3ad141b32cd7dc45485ef3c01a776ca3aa8ef0a93e77e8b5bc43/coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c4e16bd7761c5e454f4efd36f345286d6f7c5fa111623c355691e2755cae3b9e"}}, - {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3c/b7/95574702888b58c0928a6e982038c596f9c34d52c5e5107f1eef729399b5/coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "b1c81d0e5e160651879755c9c675b974276f135558cf4ba79fee7b8413a515df"}}, - {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/47/b6/40095c185f235e085df0e0b158f6bd68cc6e1d80ba6c7721dc81d97ec318/coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "606cc265adc9aaedcc84f1f064f0e8736bc45814f15a357e30fca7ecc01504e0"}}, - {name = "coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c8/50/4aea0556da7a4b93ec9168420d170b55e2eb50ae21b25062513d020c6861/coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "10b24412692df990dbc34f8fb1b6b13d236ace9dfdd68df5b28c2e39cafbba13"}}, - {name = "coverage-7.10.7-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/6a/28/ea1a84a60828177ae3b100cb6723838523369a44ec5742313ed7db3da160/coverage-7.10.7-cp310-cp310-win32.whl",hashes = {sha256 = "b51dcd060f18c19290d9b8a9dd1e0181538df2ce0717f562fff6cf74d9fc0b5b"}}, - {name = "coverage-7.10.7-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fc/1a/a81d46bbeb3c3fd97b9602ebaa411e076219a150489bcc2c025f151bd52d/coverage-7.10.7-cp310-cp310-win_amd64.whl",hashes = {sha256 = "3a622ac801b17198020f09af3eaf45666b344a0d69fc2a6ffe2ea83aeef1d807"}}, - {name = "coverage-7.10.7-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl",hashes = {sha256 = "f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260"}}, +version = "7.13.4" +requires-python = ">=3.10" +sdist = {name = "coverage-7.13.4.tar.gz", url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hashes = {sha256 = "e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}} +wheels = [ + {name = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}}, + {name = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}}, + {name = "coverage-7.13.4-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl",hashes = {sha256 = "8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}}, + {name = "coverage-7.13.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}}, + {name = "coverage-7.13.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}}, + {name = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}}, + {name = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}}, + {name = "coverage-7.13.4-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl",hashes = {sha256 = "c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}}, + {name = "coverage-7.13.4-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}}, + {name = "coverage-7.13.4-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}}, + {name = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}}, + {name = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}}, + {name = "coverage-7.13.4-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl",hashes = {sha256 = "f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}}, + {name = "coverage-7.13.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}}, + {name = "coverage-7.13.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}}, + {name = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}}, + {name = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}}, + {name = "coverage-7.13.4-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl",hashes = {sha256 = "2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}}, + {name = "coverage-7.13.4-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}}, + {name = "coverage-7.13.4-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}}, + {name = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"}}, + {name = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/a0/2ea570925524ef4e00bb6c82649f5682a77fac5ab910a65c9284de422600/coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/ac/45dc2e19a1939098d783c846e130b8f862fbb50d09e0af663988f2f21973/coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/2d/4d/26d236ff35abc3b5e63540d3386e4c3b192168c1d96da5cb2f43c640970f/coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/ec/55/14a966c757d1348b2e19caf699415a2a4c4f7feaa4bbc6326a51f5c7dd1b/coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/33/50116647905837c66d28b2af1321b845d5f5d19be9655cb84d4a0ea806b4/coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c2/b4/8efb11a46e3665d92635a56e4f2d4529de6d33f2cb38afd47d779d15fc99/coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/51/24/8cd73dd399b812cc76bb0ac260e671c4163093441847ffe058ac9fda1e32/coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/03/94/0a4b12f1d0e029ce1ccc1c800944a9984cbe7d678e470bb6d3c6bc38a0da/coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/44/6002fbf88f6698ca034360ce474c406be6d5a985b3fdb3401128031eef6b/coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"}}, + {name = "coverage-7.13.4-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/de/c6/a0279f7c00e786be75a749a5674e6fa267bcbd8209cd10c9a450c655dfa7/coverage-7.13.4-cp312-cp312-win32.whl",hashes = {sha256 = "01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"}}, + {name = "coverage-7.13.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/77/4e/c0a25a425fcf5557d9abd18419c95b63922e897bc86c1f327f155ef234a9/coverage-7.13.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"}}, + {name = "coverage-7.13.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/47/ac/92da44ad9a6f4e3a7debd178949d6f3769bedca33830ce9b1dcdab589a37/coverage-7.13.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"}}, + {name = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"}}, + {name = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"}}, + {name = "coverage-7.13.4-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl",hashes = {sha256 = "784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"}}, + {name = "coverage-7.13.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"}}, + {name = "coverage-7.13.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"}}, + {name = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/d4/7827d9ffa34d5d4d752eec907022aa417120936282fc488306f5da08c292/coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"}}, + {name = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/b0/d69df26607c64043292644dbb9dc54b0856fabaa2cbb1eeee3331cc9e280/coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/82/a4/c1523f7c9e47b2271dbf8c2a097e7a1f89ef0d66f5840bb59b7e8814157b/coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/02/aa7ec01d1a5023c4b680ab7257f9bfde9defe8fdddfe40be096ac19e8177/coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/35/98/85aba0aed5126d896162087ef3f0e789a225697245256fc6181b95f47207/coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/96/72/1db59bd67494bc162e3e4cd5fbc7edba2c7026b22f7c8ef1496d58c2b94c/coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/9d/97/72899c59c7066961de6e3daa142d459d47d104956db43e057e034f015c8a/coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/39/1f/f1885573b5970235e908da4389176936c8933e86cb316b9620aab1585fa2/coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a8/cf/e80390c5b7480b722fa3e994f8202807799b85bc562aa4f1dde209fbb7be/coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/bf/f89a8350d85572f95412debb0fb9bb4795b1d5b5232bd652923c759e787b/coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/6e/612a02aece8178c818df273e8d1642190c4875402ca2ba74514394b27aba/coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/cb/98/b5afc39af67c2fa6786b03c3a7091fc300947387ce8914b096db8a73d67a/coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"}}, + {name = "coverage-7.13.4-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/51/30/2bba8ef0682d5bd210c38fe497e12a06c9f8d663f7025e9f5c2c31ce847d/coverage-7.13.4-cp310-cp310-win32.whl",hashes = {sha256 = "a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"}}, + {name = "coverage-7.13.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/78/13/331f94934cf6c092b8ea59ff868eb587bc8fe0893f02c55bc6c0183a192e/coverage-7.13.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"}}, + {name = "coverage-7.13.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl",hashes = {sha256 = "1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}}, ] marker = "\"test\" in dependency_groups" @@ -249,11 +263,11 @@ dependencies = [] [[packages]] name = "httpx-folio" -version = "0.2.3" +version = "0.3.0" requires-python = ">=3.9" -sdist = {name = "httpx_folio-0.2.3.tar.gz", url = "https://files.pythonhosted.org/packages/72/07/727a73827674a6a91db6a58ac492703d6d0efe9a5f14d856aff9b434fe65/httpx_folio-0.2.3.tar.gz", hashes = {sha256 = "8c4afd55231e1a645c824a7ffa63ebc1b0261223e5d6b65101ab639a6a0a54dd"}} +sdist = {name = "httpx_folio-0.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/87/23/dd3f9ade71ace5a4b0343388792aa1bf8892f95ddf7217d82c0182f14c59/httpx_folio-0.3.0.tar.gz", hashes = {sha256 = "436778fb1bffb3327393bd5b809e7f38a2fd9fdfc8fea71a0a47fe2e0dbae2f2"}} wheels = [ - {name = "httpx_folio-0.2.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/34/3c/b5333a57399d8c787efb2c90d9accb6ddf22523fcec3404814b0eb10bb8a/httpx_folio-0.2.3-py3-none-any.whl",hashes = {sha256 = "e319cc8cf3e0443982655a6012017e36af112e58081b050b40048052b039b6e9"}}, + {name = "httpx_folio-0.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5a/91/2ab3ee8588e5eab7808be5c3b1ea8fb3515f07686cddf49cbcde40885b3d/httpx_folio-0.3.0-py3-none-any.whl",hashes = {sha256 = "5396438eb07257db7c080382f65711b01b93eab3b2adc420a5855be3007c37ae"}}, ] marker = "\"default\" in dependency_groups" @@ -265,79 +279,83 @@ dependencies = [ [[packages]] name = "orjson" -version = "3.11.3" -requires-python = ">=3.9" -sdist = {name = "orjson-3.11.3.tar.gz", url = "https://files.pythonhosted.org/packages/be/4d/8df5f83256a809c22c4d6792ce8d43bb503be0fb7a8e4da9025754b09658/orjson-3.11.3.tar.gz", hashes = {sha256 = "1c0603b1d2ffcd43a411d64797a19556ef76958aef1c182f22dc30860152a98a"}} -wheels = [ - {name = "orjson-3.11.3-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/ef/77/d3b1fef1fc6aaeed4cbf3be2b480114035f4df8fa1a99d2dac1d40d6e924/orjson-3.11.3-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "cf4b81227ec86935568c7edd78352a92e97af8da7bd70bdfdaa0d2e0011a1ab4"}}, - {name = "orjson-3.11.3-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e4/6d/468d21d49bb12f900052edcfbf52c292022d0a323d7828dc6376e6319703/orjson-3.11.3-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "bc8bc85b81b6ac9fc4dae393a8c159b817f4c2c9dee5d12b773bddb3b95fc07e"}}, - {name = "orjson-3.11.3-cp314-cp314-manylinux_2_34_aarch64.whl",url = "https://files.pythonhosted.org/packages/67/46/1e2588700d354aacdf9e12cc2d98131fb8ac6f31ca65997bef3863edb8ff/orjson-3.11.3-cp314-cp314-manylinux_2_34_aarch64.whl",hashes = {sha256 = "88dcfc514cfd1b0de038443c7b3e6a9797ffb1b3674ef1fd14f701a13397f82d"}}, - {name = "orjson-3.11.3-cp314-cp314-manylinux_2_34_x86_64.whl",url = "https://files.pythonhosted.org/packages/3b/94/11137c9b6adb3779f1b34fd98be51608a14b430dbc02c6d41134fbba484c/orjson-3.11.3-cp314-cp314-manylinux_2_34_x86_64.whl",hashes = {sha256 = "d61cd543d69715d5fc0a690c7c6f8dcc307bc23abef9738957981885f5f38229"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/10/61/dccedcf9e9bcaac09fdabe9eaee0311ca92115699500efbd31950d878833/orjson-3.11.3-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2b7b153ed90ababadbef5c3eb39549f9476890d339cf47af563aea7e07db2451"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/0e/fd/0e935539aa7b08b3ca0f817d73034f7eb506792aae5ecc3b7c6e679cdf5f/orjson-3.11.3-cp314-cp314-musllinux_1_2_armv7l.whl",hashes = {sha256 = "7909ae2460f5f494fecbcd10613beafe40381fd0316e35d6acb5f3a05bfda167"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/4a/2b/50ae1a5505cd1043379132fdb2adb8a05f37b3e1ebffe94a5073321966fd/orjson-3.11.3-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "2030c01cbf77bc67bee7eef1e7e31ecf28649353987775e3583062c752da0077"}}, - {name = "orjson-3.11.3-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/cd/1d/a473c158e380ef6f32753b5f39a69028b25ec5be331c2049a2201bde2e19/orjson-3.11.3-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a0169ebd1cbd94b26c7a7ad282cf5c2744fce054133f959e02eb5265deae1872"}}, - {name = "orjson-3.11.3-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/da/09/17d9d2b60592890ff7382e591aa1d9afb202a266b180c3d4049b1ec70e4a/orjson-3.11.3-cp314-cp314-win32.whl",hashes = {sha256 = "0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d"}}, - {name = "orjson-3.11.3-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/15/58/358f6846410a6b4958b74734727e582ed971e13d335d6c7ce3e47730493e/orjson-3.11.3-cp314-cp314-win_amd64.whl",hashes = {sha256 = "317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804"}}, - {name = "orjson-3.11.3-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/28/01/d6b274a0635be0468d4dbd9cafe80c47105937a0d42434e805e67cd2ed8b/orjson-3.11.3-cp314-cp314-win_arm64.whl",hashes = {sha256 = "e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc"}}, - {name = "orjson-3.11.3-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/fc/79/8932b27293ad35919571f77cb3693b5906cf14f206ef17546052a241fdf6/orjson-3.11.3-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "af40c6612fd2a4b00de648aa26d18186cd1322330bd3a3cc52f87c699e995810"}}, - {name = "orjson-3.11.3-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/1c/82/cb93cd8cf132cd7643b30b6c5a56a26c4e780c7a145db6f83de977b540ce/orjson-3.11.3-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "9f1587f26c235894c09e8b5b7636a38091a9e6e7fe4531937534749c04face43"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/b8/2d9eb181a9b6bb71463a78882bcac1027fd29cf62c38a40cc02fc11d3495/orjson-3.11.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "61dcdad16da5bb486d7227a37a2e789c429397793a6955227cedbd7252eb5a27"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/b4/14/a0e971e72d03b509190232356d54c0f34507a05050bd026b8db2bf2c192c/orjson-3.11.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "11c6d71478e2cbea0a709e8a06365fa63da81da6498a53e4c4f065881d21ae8f"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/8e/af/dc74536722b03d65e17042cc30ae586161093e5b1f29bccda24765a6ae47/orjson-3.11.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "ff94112e0098470b665cb0ed06efb187154b63649403b8d5e9aedeb482b4548c"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/62/e6/7a3b63b6677bce089fe939353cda24a7679825c43a24e49f757805fc0d8a/orjson-3.11.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "ae8b756575aaa2a855a75192f356bbda11a89169830e1439cfb1a3e1a6dde7be"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/fc/cd/ce2ab93e2e7eaf518f0fd15e3068b8c43216c8a44ed82ac2b79ce5cef72d/orjson-3.11.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "c9416cc19a349c167ef76135b2fe40d03cea93680428efee8771f3e9fb66079d"}}, - {name = "orjson-3.11.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d0/b4/f98355eff0bd1a38454209bbc73372ce351ba29933cb3e2eba16c04b9448/orjson-3.11.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "b822caf5b9752bc6f246eb08124c3d12bf2175b66ab74bac2ef3bbf9221ce1b2"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/92/8f5182d7bc2a1bed46ed960b61a39af8389f0ad476120cd99e67182bfb6d/orjson-3.11.3-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "414f71e3bdd5573893bf5ecdf35c32b213ed20aa15536fe2f588f946c318824f"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/1a/60/c41ca753ce9ffe3d0f67b9b4c093bdd6e5fdb1bc53064f992f66bb99954d/orjson-3.11.3-cp313-cp313-musllinux_1_2_armv7l.whl",hashes = {sha256 = "828e3149ad8815dc14468f36ab2a4b819237c155ee1370341b91ea4c8672d2ee"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/dd/13/e4a4f16d71ce1868860db59092e78782c67082a8f1dc06a3788aef2b41bc/orjson-3.11.3-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "ac9e05f25627ffc714c21f8dfe3a579445a5c392a9c8ae7ba1d0e9fb5333f56e"}}, - {name = "orjson-3.11.3-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/8d/8b/bafb7f0afef9344754a3a0597a12442f1b85a048b82108ef2c956f53babd/orjson-3.11.3-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e44fbe4000bd321d9f3b648ae46e0196d21577cf66ae684a96ff90b1f7c93633"}}, - {name = "orjson-3.11.3-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/60/d4/bae8e4f26afb2c23bea69d2f6d566132584d1c3a5fe89ee8c17b718cab67/orjson-3.11.3-cp313-cp313-win32.whl",hashes = {sha256 = "2039b7847ba3eec1f5886e75e6763a16e18c68a63efc4b029ddf994821e2e66b"}}, - {name = "orjson-3.11.3-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/88/76/224985d9f127e121c8cad882cea55f0ebe39f97925de040b75ccd4b33999/orjson-3.11.3-cp313-cp313-win_amd64.whl",hashes = {sha256 = "29be5ac4164aa8bdcba5fa0700a3c9c316b411d8ed9d39ef8a882541bd452fae"}}, - {name = "orjson-3.11.3-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e2/cf/0dce7a0be94bd36d1346be5067ed65ded6adb795fdbe3abd234c8d576d01/orjson-3.11.3-cp313-cp313-win_arm64.whl",hashes = {sha256 = "18bd1435cb1f2857ceb59cfb7de6f92593ef7b831ccd1b9bfb28ca530e539dce"}}, - {name = "orjson-3.11.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/3d/b0/a7edab2a00cdcb2688e1c943401cb3236323e7bfd2839815c6131a3742f4/orjson-3.11.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "8c752089db84333e36d754c4baf19c0e1437012242048439c7e80eb0e6426e3b"}}, - {name = "orjson-3.11.3-cp312-cp312-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e1/c6/ff4865a9cc398a07a83342713b5932e4dc3cb4bf4bc04e8f83dedfc0d736/orjson-3.11.3-cp312-cp312-macosx_15_0_arm64.whl",hashes = {sha256 = "9b8761b6cf04a856eb544acdd82fc594b978f12ac3602d6374a7edb9d86fd2c2"}}, - {name = "orjson-3.11.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/6e/e6/e00bea2d9472f44fe8794f523e548ce0ad51eb9693cf538a753a27b8bda4/orjson-3.11.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "8b13974dc8ac6ba22feaa867fc19135a3e01a134b4f7c9c28162fed4d615008a"}}, - {name = "orjson-3.11.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/54/31/9fbb78b8e1eb3ac605467cb846e1c08d0588506028b37f4ee21f978a51d4/orjson-3.11.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "f83abab5bacb76d9c821fd5c07728ff224ed0e52d7a71b7b3de822f3df04e15c"}}, - {name = "orjson-3.11.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/36/88/b0604c22af1eed9f98d709a96302006915cfd724a7ebd27d6dd11c22d80b/orjson-3.11.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "e6fbaf48a744b94091a56c62897b27c31ee2da93d826aa5b207131a1e13d4064"}}, - {name = "orjson-3.11.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/0e/9d/1c1238ae9fffbfed51ba1e507731b3faaf6b846126a47e9649222b0fd06f/orjson-3.11.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "bc779b4f4bba2847d0d2940081a7b6f7b5877e05408ffbb74fa1faf4a136c424"}}, - {name = "orjson-3.11.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/a3/b5/c06f1b090a1c875f337e21dd71943bc9d84087f7cdf8c6e9086902c34e42/orjson-3.11.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "bd4b909ce4c50faa2192da6bb684d9848d4510b736b0611b6ab4020ea6fd2d23"}}, - {name = "orjson-3.11.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a0/26/5f028c7d81ad2ebbf84414ba6d6c9cac03f22f5cd0d01eb40fb2d6a06b07/orjson-3.11.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "524b765ad888dc5518bbce12c77c2e83dee1ed6b0992c1790cc5fb49bb4b6667"}}, - {name = "orjson-3.11.3-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/fe/d4/b8df70d9cfb56e385bf39b4e915298f9ae6c61454c8154a0f5fd7efcd42e/orjson-3.11.3-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "84fd82870b97ae3cdcea9d8746e592b6d40e1e4d4527835fc520c588d2ded04f"}}, - {name = "orjson-3.11.3-cp312-cp312-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/da/5e/afe6a052ebc1a4741c792dd96e9f65bf3939d2094e8b356503b68d48f9f5/orjson-3.11.3-cp312-cp312-musllinux_1_2_armv7l.whl",hashes = {sha256 = "fbecb9709111be913ae6879b07bafd4b0785b44c1eb5cac8ac76da048b3885a1"}}, - {name = "orjson-3.11.3-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/f8/90/7bbabafeb2ce65915e9247f14a56b29c9334003536009ef5b122783fe67e/orjson-3.11.3-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "9dba358d55aee552bd868de348f4736ca5a4086d9a62e2bfbbeeb5629fe8b0cc"}}, - {name = "orjson-3.11.3-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/27/b3/2d703946447da8b093350570644a663df69448c9d9330e5f1d9cce997f20/orjson-3.11.3-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eabcf2e84f1d7105f84580e03012270c7e97ecb1fb1618bda395061b2a84a049"}}, - {name = "orjson-3.11.3-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/38/70/b14dcfae7aff0e379b0119c8a812f8396678919c431efccc8e8a0263e4d9/orjson-3.11.3-cp312-cp312-win32.whl",hashes = {sha256 = "3782d2c60b8116772aea8d9b7905221437fdf53e7277282e8d8b07c220f96cca"}}, - {name = "orjson-3.11.3-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/35/b8/9e3127d65de7fff243f7f3e53f59a531bf6bb295ebe5db024c2503cc0726/orjson-3.11.3-cp312-cp312-win_amd64.whl",hashes = {sha256 = "79b44319268af2eaa3e315b92298de9a0067ade6e6003ddaef72f8e0bedb94f1"}}, - {name = "orjson-3.11.3-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/92/a946e737d4d8a7fd84a606aba96220043dcc7d6988b9e7551f7f6d5ba5ad/orjson-3.11.3-cp312-cp312-win_arm64.whl",hashes = {sha256 = "0e92a4e83341ef79d835ca21b8bd13e27c859e4e9e4d7b63defc6e58462a3710"}}, - {name = "orjson-3.11.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/cd/8b/360674cd817faef32e49276187922a946468579fcaf37afdfb6c07046e92/orjson-3.11.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "9d2ae0cc6aeb669633e0124531f342a17d8e97ea999e42f12a5ad4adaa304c5f"}}, - {name = "orjson-3.11.3-cp311-cp311-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/05/3d/5fa9ea4b34c1a13be7d9046ba98d06e6feb1d8853718992954ab59d16625/orjson-3.11.3-cp311-cp311-macosx_15_0_arm64.whl",hashes = {sha256 = "ba21dbb2493e9c653eaffdc38819b004b7b1b246fb77bfc93dc016fe664eac91"}}, - {name = "orjson-3.11.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/e5/5f/e18367823925e00b1feec867ff5f040055892fc474bf5f7875649ecfa586/orjson-3.11.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "00f1a271e56d511d1569937c0447d7dce5a99a33ea0dec76673706360a051904"}}, - {name = "orjson-3.11.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/0f/bd/3c66b91c4564759cf9f473251ac1650e446c7ba92a7c0f9f56ed54f9f0e6/orjson-3.11.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "b67e71e47caa6680d1b6f075a396d04fa6ca8ca09aafb428731da9b3ea32a5a6"}}, - {name = "orjson-3.11.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/82/b5/dc8dcd609db4766e2967a85f63296c59d4722b39503e5b0bf7fd340d387f/orjson-3.11.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d7d012ebddffcce8c85734a6d9e5f08180cd3857c5f5a3ac70185b43775d043d"}}, - {name = "orjson-3.11.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/48/c2/d58ec5fd1270b2aa44c862171891adc2e1241bd7dab26c8f46eb97c6c6f1/orjson-3.11.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "dd759f75d6b8d1b62012b7f5ef9461d03c804f94d539a5515b454ba3a6588038"}}, - {name = "orjson-3.11.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/73/87/0ef7e22eb8dd1ef940bfe3b9e441db519e692d62ed1aae365406a16d23d0/orjson-3.11.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "6890ace0809627b0dff19cfad92d69d0fa3f089d3e359a2a532507bb6ba34efb"}}, - {name = "orjson-3.11.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/6a/e5bf7b70883f374710ad74faf99bacfc4b5b5a7797c1d5e130350e0e28a3/orjson-3.11.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "f9d4a5e041ae435b815e568537755773d05dac031fee6a57b4ba70897a44d9d2"}}, - {name = "orjson-3.11.3-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/bd/0c/4577fd860b6386ffaa56440e792af01c7882b56d2766f55384b5b0e9d39b/orjson-3.11.3-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2d68bf97a771836687107abfca089743885fb664b90138d8761cce61d5625d55"}}, - {name = "orjson-3.11.3-cp311-cp311-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/66/4b/83e92b2d67e86d1c33f2ea9411742a714a26de63641b082bdbf3d8e481af/orjson-3.11.3-cp311-cp311-musllinux_1_2_armv7l.whl",hashes = {sha256 = "bfc27516ec46f4520b18ef645864cee168d2a027dbf32c5537cb1f3e3c22dac1"}}, - {name = "orjson-3.11.3-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/6d/e5/9eea6a14e9b5ceb4a271a1fd2e1dec5f2f686755c0fab6673dc6ff3433f4/orjson-3.11.3-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "f66b001332a017d7945e177e282a40b6997056394e3ed7ddb41fb1813b83e824"}}, - {name = "orjson-3.11.3-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/45/78/8d4f5ad0c80ba9bf8ac4d0fc71f93a7d0dc0844989e645e2074af376c307/orjson-3.11.3-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "212e67806525d2561efbfe9e799633b17eb668b8964abed6b5319b2f1cfbae1f"}}, - {name = "orjson-3.11.3-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/0b/5f/16386970370178d7a9b438517ea3d704efcf163d286422bae3b37b88dbb5/orjson-3.11.3-cp311-cp311-win32.whl",hashes = {sha256 = "6e8e0c3b85575a32f2ffa59de455f85ce002b8bdc0662d6b9c2ed6d80ab5d204"}}, - {name = "orjson-3.11.3-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/09/60/db16c6f7a41dd8ac9fb651f66701ff2aeb499ad9ebc15853a26c7c152448/orjson-3.11.3-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6be2f1b5d3dc99a5ce5ce162fc741c22ba9f3443d3dd586e6a1211b7bc87bc7b"}}, - {name = "orjson-3.11.3-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/3e/2a/bb811ad336667041dea9b8565c7c9faf2f59b47eb5ab680315eea612ef2e/orjson-3.11.3-cp311-cp311-win_arm64.whl",hashes = {sha256 = "fafb1a99d740523d964b15c8db4eabbfc86ff29f84898262bf6e3e4c9e97e43e"}}, - {name = "orjson-3.11.3-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/9b/64/4a3cef001c6cd9c64256348d4c13a7b09b857e3e1cbb5185917df67d8ced/orjson-3.11.3-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "29cb1f1b008d936803e2da3d7cba726fc47232c45df531b29edf0b232dd737e7"}}, - {name = "orjson-3.11.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/10/ce/0c8c87f54f79d051485903dc46226c4d3220b691a151769156054df4562b/orjson-3.11.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "97dceed87ed9139884a55db8722428e27bd8452817fbf1869c58b49fecab1120"}}, - {name = "orjson-3.11.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/ef/d0/249497e861f2d438f45b3ab7b7b361484237414945169aa285608f9f7019/orjson-3.11.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "58533f9e8266cb0ac298e259ed7b4d42ed3fa0b78ce76860626164de49e0d467"}}, - {name = "orjson-3.11.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/e5/64/00485702f640a0fd56144042a1ea196469f4a3ae93681871564bf74fa996/orjson-3.11.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "0c212cfdd90512fe722fa9bd620de4d46cda691415be86b2e02243242ae81873"}}, - {name = "orjson-3.11.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/64/81/110d68dba3909171bf3f05619ad0cf187b430e64045ae4e0aa7ccfe25b15/orjson-3.11.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "5ff835b5d3e67d9207343effb03760c00335f8b5285bfceefd4dc967b0e48f6a"}}, - {name = "orjson-3.11.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/79/92/dba25c22b0ddfafa1e6516a780a00abac28d49f49e7202eb433a53c3e94e/orjson-3.11.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "f5aa4682912a450c2db89cbd92d356fef47e115dffba07992555542f344d301b"}}, - {name = "orjson-3.11.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/1d/ca2230fd55edbd87b58a43a19032d63a4b180389a97520cc62c535b726f9/orjson-3.11.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "d7d18dd34ea2e860553a579df02041845dee0af8985dff7f8661306f95504ddf"}}, - {name = "orjson-3.11.3-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/6e/b9/96bbc8ed3e47e52b487d504bd6861798977445fbc410da6e87e302dc632d/orjson-3.11.3-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d8b11701bc43be92ea42bd454910437b355dfb63696c06fe953ffb40b5f763b4"}}, - {name = "orjson-3.11.3-cp310-cp310-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/c4/3c/418fbd93d94b0df71cddf96b7fe5894d64a5d890b453ac365120daec30f7/orjson-3.11.3-cp310-cp310-musllinux_1_2_armv7l.whl",hashes = {sha256 = "90368277087d4af32d38bd55f9da2ff466d25325bf6167c8f382d8ee40cb2bbc"}}, - {name = "orjson-3.11.3-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/5b/a9/2bfd58817d736c2f63608dec0c34857339d423eeed30099b126562822191/orjson-3.11.3-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "fd7ff459fb393358d3a155d25b275c60b07a2c83dcd7ea962b1923f5a1134569"}}, - {name = "orjson-3.11.3-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/33/ba/29023771f334096f564e48d82ed855a0ed3320389d6748a9c949e25be734/orjson-3.11.3-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f8d902867b699bcd09c176a280b1acdab57f924489033e53d0afe79817da37e6"}}, - {name = "orjson-3.11.3-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/39/62/b5a1eca83f54cb3aa11a9645b8a22f08d97dbd13f27f83aae7c6666a0a05/orjson-3.11.3-cp310-cp310-win32.whl",hashes = {sha256 = "bb93562146120bb51e6b154962d3dadc678ed0fce96513fa6bc06599bb6f6edc"}}, - {name = "orjson-3.11.3-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e3/c0/7ebfaa327d9a9ed982adc0d9420dbce9a3fec45b60ab32c6308f731333fa/orjson-3.11.3-cp310-cp310-win_amd64.whl",hashes = {sha256 = "976c6f1975032cc327161c65d4194c549f2589d88b105a5e3499429a54479770"}}, +version = "3.11.7" +requires-python = ">=3.10" +sdist = {name = "orjson-3.11.7.tar.gz", url = "https://files.pythonhosted.org/packages/53/45/b268004f745ede84e5798b48ee12b05129d19235d0e15267aa57dcdb400b/orjson-3.11.7.tar.gz", hashes = {sha256 = "9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49"}} +wheels = [ + {name = "orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/e9/1e/745565dca749813db9a093c5ebc4bac1a9475c64d54b95654336ac3ed961/orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0"}}, + {name = "orjson-3.11.7-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/46/19/e40f6225da4d3aa0c8dc6e5219c5e87c2063a560fe0d72a88deb59776794/orjson-3.11.7-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/9d/7e/c4de2babef2c0817fd1f048fd176aa48c37bec8aef53d2fa932983032cce/orjson-3.11.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/eb/74/233d360632bafd2197f217eee7fb9c9d0229eac0c18128aee5b35b0014fe/orjson-3.11.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/79/51/af79504981dd31efe20a9e360eb49c15f06df2b40e7f25a0a52d9ae888e8/orjson-3.11.7-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/67/e2/da898eb68b72304f8de05ca6715870d09d603ee98d30a27e8a9629abc64b/orjson-3.11.7-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/c5/89/15364d92acb3d903b029e28d834edb8780c2b97404cbf7929aa6b9abdb24/orjson-3.11.7-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c2/8b/ecdad52d0b38d4b8f514be603e69ccd5eacf4e7241f972e37e79792212ec/orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b9/0e/45e1dcf10e17d0924b7c9162f87ec7b4ca79e28a0548acf6a71788d3e108/orjson-3.11.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/63/d7/4d2e8b03561257af0450f2845b91fbd111d7e526ccdf737267108075e0ba/orjson-3.11.7-cp314-cp314-musllinux_1_2_armv7l.whl",hashes = {sha256 = "23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/78/cf/d45343518282108b29c12a65892445fc51f9319dc3c552ceb51bb5905ed2/orjson-3.11.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a9/3a/d6001f51a7275aacd342e77b735c71fa04125a3f93c36fee4526bc8c654e/orjson-3.11.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2"}}, + {name = "orjson-3.11.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/1d/d3/f19b47ce16820cc2c480f7f1723e17f6d411b3a295c60c8ad3aa9ff1c96a/orjson-3.11.7-cp314-cp314-win32.whl",hashes = {sha256 = "89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576"}}, + {name = "orjson-3.11.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/12/df/172771902943af54bf661a8d102bdf2e7f932127968080632bda6054b62c/orjson-3.11.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1"}}, + {name = "orjson-3.11.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/6f/1c/f2a8d8a1b17514660a614ce5f7aac74b934e69f5abc2700cc7ced882a009/orjson-3.11.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d"}}, + {name = "orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/89/25/6e0e52cac5aab51d7b6dcd257e855e1dec1c2060f6b28566c509b4665f62/orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733"}}, + {name = "orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/29/a77f48d2fc8a05bbc529e5ff481fb43d914f9e383ea2469d4f3d51df3d00/orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/25/0a16e0729a0e6a1504f9d1a13cdd365f030068aab64cec6958396b9969d7/orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/66/da/a2e505469d60666a05ab373f1a6322eb671cb2ba3a0ccfc7d4bc97196787/orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/23/bf/ed73f88396ea35c71b38961734ea4a4746f7ca0768bf28fd551d37e48dd0/orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/73/3c/b05d80716f0225fc9008fbf8ab22841dcc268a626aa550561743714ce3bf/orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/61/e8/0be9b0addd9bf86abfc938e97441dcd0375d494594b1c8ad10fe57479617/orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c9/ec/c68e3b9021a31d9ec15a94931db1410136af862955854ed5dd7e7e4f5bff/orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d2/45/f3466739aaafa570cc8e77c6dbb853c48bf56e3b43738020e2661e08b0ac/orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/e1/84/9f7f02288da1ffb31405c1be07657afd1eecbcb4b64ee2817b6fe0f785fa/orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",hashes = {sha256 = "ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/18/07/9dd2f0c0104f1a0295ffbe912bc8d63307a539b900dd9e2c48ef7810d971/orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/66/857a8e4a3292e1f7b1b202883bcdeb43a91566cf59a93f97c53b44bd6801/orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223"}}, + {name = "orjson-3.11.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/0a/5b/6ebcf3defc1aab3a338ca777214966851e92efb1f30dc7fc8285216e6d1b/orjson-3.11.7-cp313-cp313-win32.whl",hashes = {sha256 = "7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3"}}, + {name = "orjson-3.11.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/00/04/c6f72daca5092e3117840a1b1e88dfc809cc1470cf0734890d0366b684a1/orjson-3.11.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757"}}, + {name = "orjson-3.11.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/03/ba/077a0f6f1085d6b806937246860fafbd5b17f3919c70ee3f3d8d9c713f38/orjson-3.11.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539"}}, + {name = "orjson-3.11.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/80/bf/76f4f1665f6983385938f0e2a5d7efa12a58171b8456c252f3bae8a4cf75/orjson-3.11.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f"}}, + {name = "orjson-3.11.7-cp312-cp312-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/79/53/6c72c002cb13b5a978a068add59b25a8bdf2800ac1c9c8ecdb26d6d97064/orjson-3.11.7-cp312-cp312-macosx_15_0_arm64.whl",hashes = {sha256 = "89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/83/10e48852865e5dd151bdfe652c06f7da484578ed02c5fca938e3632cb0b8/orjson-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/6e/52/a66e22a2b9abaa374b4a081d410edab6d1e30024707b87eab7c734afe28d/orjson-3.11.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/de/38/605d371417021359f4910c496f764c48ceb8997605f8c25bf1dfe58c0ebe/orjson-3.11.7-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/98/af32e842b0ffd2335c89714d48ca4e3917b42f5d6ee5537832e069a4b3ac/orjson-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/96/0b/fc793858dfa54be6feee940c1463370ece34b3c39c1ca0aa3845f5ba9892/orjson-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/dc/91/98a52415059db3f374757d0b7f0f16e3b5cd5976c90d1c2b56acaea039e6/orjson-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/dc/b6/cb540117bda61791f46381f8c26c8f93e802892830a6055748d3bb1925ab/orjson-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/63/1a/50a3201c334a7f17c231eee5f841342190723794e3b06293f26e7cf87d31/orjson-3.11.7-cp312-cp312-musllinux_1_2_armv7l.whl",hashes = {sha256 = "b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/87/cd/8de1c67d0be44fdc22701e5989c0d015a2adf391498ad42c4dc589cd3013/orjson-3.11.7-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/fe/d605d700c35dd55f51710d159fc54516a280923cd1b7e47508982fbb387d/orjson-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2"}}, + {name = "orjson-3.11.7-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/e4/e4/15ecc67edb3ddb3e2f46ae04475f2d294e8b60c1825fbe28a428b93b3fbd/orjson-3.11.7-cp312-cp312-win32.whl",hashes = {sha256 = "f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f"}}, + {name = "orjson-3.11.7-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/34/70/2e0855361f76198a3965273048c8e50a9695d88cd75811a5b46444895845/orjson-3.11.7-cp312-cp312-win_amd64.whl",hashes = {sha256 = "bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74"}}, + {name = "orjson-3.11.7-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/68/40/c2051bd19fc467610fed469dc29e43ac65891571138f476834ca192bc290/orjson-3.11.7-cp312-cp312-win_arm64.whl",hashes = {sha256 = "26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5"}}, + {name = "orjson-3.11.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/37/02/da6cb01fc6087048d7f61522c327edf4250f1683a58a839fdcc435746dd5/orjson-3.11.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c"}}, + {name = "orjson-3.11.7-cp311-cp311-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c1/c2/5885e7a5881dba9a9af51bc564e8967225a642b3e03d089289a35054e749/orjson-3.11.7-cp311-cp311-macosx_15_0_arm64.whl",hashes = {sha256 = "79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/1d/4e7688de0a92d1caf600dfd5fb70b4c5bfff51dfa61ac555072ef2d0d32a/orjson-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/2f/b2/ec04b74ae03a125db7bd69cffd014b227b7f341e3261bf75b5eb88a1aa92/orjson-3.11.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/4c/69/f95bdf960605f08f827f6e3291fe243d8aa9c5c9ff017a8d7232209184c3/orjson-3.11.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a4/1b/de59c57bae1d148ef298852abd31909ac3089cff370dfd4cd84cc99cbc42/orjson-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/ee/9e/9decc59f4499f695f65c650f6cfa6cd4c37a3fbe8fa235a0a3614cb54386/orjson-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/28/e6/59f932bcabd1eac44e334fe8e3281a92eacfcb450586e1f4bde0423728d8/orjson-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f1/36/b0f05c0eaa7ca30bc965e37e6a2956b0d67adb87a9872942d3568da846ae/orjson-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/b8/03/58ec7d302b8d86944c60c7b4b82975d5161fcce4c9bc8c6cb1d6741b6115/orjson-3.11.7-cp311-cp311-musllinux_1_2_armv7l.whl",hashes = {sha256 = "7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/06/3a/868d65ef9a8b99be723bd510de491349618abd9f62c826cf206d962db295/orjson-3.11.7-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5b/c7/1e18e1c83afe3349f4f6dc9e14910f0ae5f82eac756d1412ea4018938535/orjson-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561"}}, + {name = "orjson-3.11.7-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/d4/0b/ccb7ee1a65b37e8eeb8b267dc953561d72370e85185e459616d4345bab34/orjson-3.11.7-cp311-cp311-win32.whl",hashes = {sha256 = "c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d"}}, + {name = "orjson-3.11.7-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/af/9e/55c776dffda3f381e0f07d010a4f5f3902bf48eaba1bb7684d301acd4924/orjson-3.11.7-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471"}}, + {name = "orjson-3.11.7-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/aa/8e/424a620fa7d263b880162505fb107ef5e0afaa765b5b06a88312ac291560/orjson-3.11.7-cp311-cp311-win_arm64.whl",hashes = {sha256 = "1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d"}}, + {name = "orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/52/a2/fa129e749d500f9b183e8a3446a193818a25f60261e9ce143ad61e975208/orjson-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/08/93/1e82011cd1e0bd051ef9d35bed1aa7fb4ea1f0a055dc2c841b46b43a9ebd/orjson-3.11.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/fe/d8/a26b431ef962c7d55736674dddade876822f3e33223c1f47a36879350d04/orjson-3.11.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a7/19/f47819b84a580f490da260c3ee9ade214cf4cf78ac9ce8c1c758f80fdfc9/orjson-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/5b/cd/37ece39a0777ba077fdcdbe4cccae3be8ed00290c14bf8afdc548befc260/orjson-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/8f/ed/f2b5d66aa9b6b5c02ff5f120efc7b38c7c4962b21e6be0f00fd99a5c348e/orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c4/6e/baa83e68d1aa09fa8c3e5b2c087d01d0a0bd45256de719ed7bc22c07052d/orjson-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/0c/47/7f8ef4963b772cd56999b535e553f7eb5cd27e9dd6c049baee6f18bfa05d/orjson-3.11.7-cp310-cp310-musllinux_1_2_armv7l.whl",hashes = {sha256 = "3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/38/eb/2df104dd2244b3618f25325a656f85cc3277f74bbd91224752410a78f3c7/orjson-3.11.7-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/2a/ee41de0aa3a6686598661eae2b4ebdff1340c65bfb17fcff8b87138aab21/orjson-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f"}}, + {name = "orjson-3.11.7-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/4c/fa/92fc5d3d402b87a8b28277a9ed35386218a6a5287c7fe5ee9b9f02c53fb2/orjson-3.11.7-cp310-cp310-win32.whl",hashes = {sha256 = "ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de"}}, + {name = "orjson-3.11.7-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/07/29/a576bf36d73d60df06904d3844a9df08e25d59eba64363aaf8ec2f9bff41/orjson-3.11.7-cp310-cp310-win_amd64.whl",hashes = {sha256 = "d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993"}}, ] marker = "\"default\" in dependency_groups" @@ -346,28 +364,27 @@ dependencies = [] [[packages]] name = "psycopg" -version = "3.2.10" -requires-python = ">=3.8" -sdist = {name = "psycopg-3.2.10.tar.gz", url = "https://files.pythonhosted.org/packages/a9/f1/0258a123c045afaf3c3b60c22ccff077bceeb24b8dc2c593270899353bd0/psycopg-3.2.10.tar.gz", hashes = {sha256 = "0bce99269d16ed18401683a8569b2c5abd94f72f8364856d56c0389bcd50972a"}} +version = "3.3.2" +requires-python = ">=3.10" +sdist = {name = "psycopg-3.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/e0/1a/7d9ef4fdc13ef7f15b934c393edc97a35c281bb7d3c3329fbfcbe915a7c2/psycopg-3.3.2.tar.gz", hashes = {sha256 = "707a67975ee214d200511177a6a80e56e654754c9afca06a7194ea6bbfde9ca7"}} wheels = [ - {name = "psycopg-3.2.10-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/4a/90/422ffbbeeb9418c795dae2a768db860401446af0c6768bc061ce22325f58/psycopg-3.2.10-py3-none-any.whl",hashes = {sha256 = "ab5caf09a9ec42e314a21f5216dbcceac528e0e05142e42eea83a3b28b320ac3"}}, + {name = "psycopg-3.3.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8c/51/2779ccdf9305981a06b21a6b27e8547c948d85c41c76ff434192784a4c93/psycopg-3.3.2-py3-none-any.whl",hashes = {sha256 = "3e94bc5f4690247d734599af56e51bae8e0db8e4311ea413f801fef82b14a99b"}}, ] marker = "\"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ - "backports-zoneinfo>=0.2.0; python_version < \"3.9\"", "typing-extensions>=4.6; python_version < \"3.13\"", "tzdata; sys_platform == \"win32\"", ] [[packages]] name = "pytest" -version = "8.4.2" -requires-python = ">=3.9" -sdist = {name = "pytest-8.4.2.tar.gz", url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hashes = {sha256 = "86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}} +version = "9.0.2" +requires-python = ">=3.10" +sdist = {name = "pytest-9.0.2.tar.gz", url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hashes = {sha256 = "75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"}} wheels = [ - {name = "pytest-8.4.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl",hashes = {sha256 = "872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}}, + {name = "pytest-9.0.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl",hashes = {sha256 = "711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}}, ] marker = "\"test\" in dependency_groups" @@ -375,8 +392,8 @@ marker = "\"test\" in dependency_groups" dependencies = [ "colorama>=0.4; sys_platform == \"win32\"", "exceptiongroup>=1; python_version < \"3.11\"", - "iniconfig>=1", - "packaging>=20", + "iniconfig>=1.0.1", + "packaging>=22", "pluggy<2,>=1.5", "pygments>=2.7.2", "tomli>=1; python_version < \"3.11\"", @@ -401,26 +418,27 @@ dependencies = [ [[packages]] name = "tqdm" -version = "4.67.1" +version = "4.67.3" requires-python = ">=3.7" -sdist = {name = "tqdm-4.67.1.tar.gz", url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hashes = {sha256 = "f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}} +sdist = {name = "tqdm-4.67.3.tar.gz", url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hashes = {sha256 = "7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb"}} wheels = [ - {name = "tqdm-4.67.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl",hashes = {sha256 = "26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}}, + {name = "tqdm-4.67.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl",hashes = {sha256 = "ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf"}}, ] marker = "\"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ "colorama; platform_system == \"Windows\"", + "importlib-metadata; python_version < \"3.8\"", ] [[packages]] name = "types-tqdm" -version = "4.67.0.20250809" +version = "4.67.3.20260205" requires-python = ">=3.9" -sdist = {name = "types_tqdm-4.67.0.20250809.tar.gz", url = "https://files.pythonhosted.org/packages/fb/d0/cf498fc630d9fdaf2428b93e60b0e67b08008fec22b78716b8323cf644dc/types_tqdm-4.67.0.20250809.tar.gz", hashes = {sha256 = "02bf7ab91256080b9c4c63f9f11b519c27baaf52718e5fdab9e9606da168d500"}} +sdist = {name = "types_tqdm-4.67.3.20260205.tar.gz", url = "https://files.pythonhosted.org/packages/53/46/790b9872523a48163bdda87d47849b4466017640e5259d06eed539340afd/types_tqdm-4.67.3.20260205.tar.gz", hashes = {sha256 = "f3023682d4aa3bbbf908c8c6bb35f35692d319460d9bbd3e646e8852f3dd9f85"}} wheels = [ - {name = "types_tqdm-4.67.0.20250809-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3f/13/3ff0781445d7c12730befce0fddbbc7a76e56eb0e7029446f2853238360a/types_tqdm-4.67.0.20250809-py3-none-any.whl",hashes = {sha256 = "1a73053b31fcabf3c1f3e2a9d5ecdba0f301bde47a418cd0e0bdf774827c5c57"}}, + {name = "types_tqdm-4.67.3.20260205-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl",hashes = {sha256 = "85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173"}}, ] marker = "\"types\" in dependency_groups" @@ -431,41 +449,56 @@ dependencies = [ [[packages]] name = "tomli" -version = "2.2.1" +version = "2.4.0" requires-python = ">=3.8" -sdist = {name = "tomli-2.2.1.tar.gz", url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hashes = {sha256 = "cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}} -wheels = [ - {name = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}}, - {name = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}}, - {name = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}}, - {name = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}}, - {name = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}}, - {name = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}}, - {name = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}}, - {name = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}}, - {name = "tomli-2.2.1-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl",hashes = {sha256 = "d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}}, - {name = "tomli-2.2.1-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl",hashes = {sha256 = "a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}}, - {name = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}}, - {name = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}}, - {name = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}}, - {name = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}}, - {name = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}}, - {name = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}}, - {name = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}}, - {name = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}}, - {name = "tomli-2.2.1-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl",hashes = {sha256 = "889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}}, - {name = "tomli-2.2.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}}, - {name = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}}, - {name = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}}, - {name = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}}, - {name = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}}, - {name = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}}, - {name = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}}, - {name = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}}, - {name = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}}, - {name = "tomli-2.2.1-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl",hashes = {sha256 = "465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}}, - {name = "tomli-2.2.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}}, - {name = "tomli-2.2.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl",hashes = {sha256 = "cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}}, +sdist = {name = "tomli-2.4.0.tar.gz", url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hashes = {sha256 = "aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}} +wheels = [ + {name = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}}, + {name = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}}, + {name = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}}, + {name = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}}, + {name = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}}, + {name = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}}, + {name = "tomli-2.4.0-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl",hashes = {sha256 = "31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}}, + {name = "tomli-2.4.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}}, + {name = "tomli-2.4.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}}, + {name = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}}, + {name = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}}, + {name = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}}, + {name = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}}, + {name = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}}, + {name = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}}, + {name = "tomli-2.4.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl",hashes = {sha256 = "d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}}, + {name = "tomli-2.4.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}}, + {name = "tomli-2.4.0-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}}, + {name = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}}, + {name = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}}, + {name = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}}, + {name = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}}, + {name = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}}, + {name = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}}, + {name = "tomli-2.4.0-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl",hashes = {sha256 = "7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}}, + {name = "tomli-2.4.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}}, + {name = "tomli-2.4.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}}, + {name = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}}, + {name = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}}, + {name = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}}, + {name = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}}, + {name = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}}, + {name = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}}, + {name = "tomli-2.4.0-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl",hashes = {sha256 = "0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}}, + {name = "tomli-2.4.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}}, + {name = "tomli-2.4.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}}, + {name = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}}, + {name = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}}, + {name = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}}, + {name = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}}, + {name = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}}, + {name = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}}, + {name = "tomli-2.4.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl",hashes = {sha256 = "b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}}, + {name = "tomli-2.4.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}}, + {name = "tomli-2.4.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}}, + {name = "tomli-2.4.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl",hashes = {sha256 = "1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}}, ] marker = "\"lint\" in dependency_groups and python_version < \"3.11\" or \"test\" in dependency_groups and python_version < \"3.11\"" @@ -513,11 +546,11 @@ dependencies = [] [[packages]] name = "exceptiongroup" -version = "1.3.0" +version = "1.3.1" requires-python = ">=3.7" -sdist = {name = "exceptiongroup-1.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hashes = {sha256 = "b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}} +sdist = {name = "exceptiongroup-1.3.1.tar.gz", url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hashes = {sha256 = "8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}} wheels = [ - {name = "exceptiongroup-1.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl",hashes = {sha256 = "4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}}, + {name = "exceptiongroup-1.3.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl",hashes = {sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}}, ] marker = "\"default\" in dependency_groups and python_version < \"3.11\" or \"test\" in dependency_groups and python_version < \"3.11\"" @@ -575,11 +608,11 @@ dependencies = [] [[packages]] name = "httpx-retries" -version = "0.4.2" +version = "0.4.5" requires-python = ">=3.9" -sdist = {name = "httpx_retries-0.4.2.tar.gz", url = "https://files.pythonhosted.org/packages/9e/32/37cd73ca29912cc572cec2a79b09cb719786d22e37bf02140bc750d34b36/httpx_retries-0.4.2.tar.gz", hashes = {sha256 = "8c32b781cf18dc9d67fc380792bf465cde107831ec1c1c504a7df6c80f06536c"}} +sdist = {name = "httpx_retries-0.4.5.tar.gz", url = "https://files.pythonhosted.org/packages/22/40/b9b5e4c16fb86d2999840bb795b28670a61856c7f48f030530b412bf4133/httpx_retries-0.4.5.tar.gz", hashes = {sha256 = "acee306d7384eefad71ac12fefe8b13d7b41c19595c538e68d9bd7e40e59539d"}} wheels = [ - {name = "httpx_retries-0.4.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a4/73/0700c81ad08787e2648de8ae69c046bdfee865216187bdd43cb2ba35b36c/httpx_retries-0.4.2-py3-none-any.whl",hashes = {sha256 = "0393e2ee1ab7a90aa748733cc8fe8ff722f21f282fc8f8780369089918cec994"}}, + {name = "httpx_retries-0.4.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/0a/2626b5a2678f8072ba3174d3e40f81429fdc41d1cb993280dbc7ba3c4e3f/httpx_retries-0.4.5-py3-none-any.whl",hashes = {sha256 = "ae22d6ef197a2da49242246a01d721474cbd6516b1fef155f6da694ee410bb37"}}, ] marker = "\"default\" in dependency_groups" @@ -590,11 +623,11 @@ dependencies = [ [[packages]] name = "iniconfig" -version = "2.1.0" -requires-python = ">=3.8" -sdist = {name = "iniconfig-2.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hashes = {sha256 = "3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}} +version = "2.3.0" +requires-python = ">=3.10" +sdist = {name = "iniconfig-2.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hashes = {sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}} wheels = [ - {name = "iniconfig-2.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl",hashes = {sha256 = "9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}}, + {name = "iniconfig-2.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl",hashes = {sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}}, ] marker = "\"test\" in dependency_groups" @@ -630,11 +663,11 @@ dependencies = [] [[packages]] name = "packaging" -version = "25.0" +version = "26.0" requires-python = ">=3.8" -sdist = {name = "packaging-25.0.tar.gz", url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hashes = {sha256 = "d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}} +sdist = {name = "packaging-26.0.tar.gz", url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hashes = {sha256 = "00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}} wheels = [ - {name = "packaging-25.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl",hashes = {sha256 = "29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}}, + {name = "packaging-26.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl",hashes = {sha256 = "b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}}, ] marker = "\"test\" in dependency_groups" @@ -643,11 +676,11 @@ dependencies = [] [[packages]] name = "pathspec" -version = "0.12.1" -requires-python = ">=3.8" -sdist = {name = "pathspec-0.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hashes = {sha256 = "a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}} +version = "1.0.4" +requires-python = ">=3.9" +sdist = {name = "pathspec-1.0.4.tar.gz", url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hashes = {sha256 = "0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645"}} wheels = [ - {name = "pathspec-0.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl",hashes = {sha256 = "a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}}, + {name = "pathspec-1.0.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl",hashes = {sha256 = "fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}}, ] marker = "\"lint\" in dependency_groups" @@ -669,82 +702,24 @@ dependencies = [] [[packages]] name = "ruamel-yaml" -version = "0.18.15" -requires-python = ">=3.8" -sdist = {name = "ruamel.yaml-0.18.15.tar.gz", url = "https://files.pythonhosted.org/packages/3e/db/f3950f5e5031b618aae9f423a39bf81a55c148aecd15a34527898e752cf4/ruamel.yaml-0.18.15.tar.gz", hashes = {sha256 = "dbfca74b018c4c3fba0b9cc9ee33e53c371194a9000e694995e620490fd40700"}} +version = "0.19.1" +requires-python = ">=3.9" +sdist = {name = "ruamel_yaml-0.19.1.tar.gz", url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hashes = {sha256 = "53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993"}} wheels = [ - {name = "ruamel.yaml-0.18.15-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d1/e5/f2a0621f1781b76a38194acae72f01e37b1941470407345b6e8653ad7640/ruamel.yaml-0.18.15-py3-none-any.whl",hashes = {sha256 = "148f6488d698b7a5eded5ea793a025308b25eca97208181b6a026037f391f701"}}, + {name = "ruamel_yaml-0.19.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl",hashes = {sha256 = "27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93"}}, ] marker = "\"lint\" in dependency_groups" -[packages.tool.pdm] -dependencies = [ - "ruamel-yaml-clib>=0.2.7; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", -] - -[[packages]] -name = "ruamel-yaml-clib" -version = "0.2.14" -requires-python = ">=3.9" -sdist = {name = "ruamel.yaml.clib-0.2.14.tar.gz", url = "https://files.pythonhosted.org/packages/d8/e9/39ec4d4b3f91188fad1842748f67d4e749c77c37e353c4e545052ee8e893/ruamel.yaml.clib-0.2.14.tar.gz", hashes = {sha256 = "803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e"}} -wheels = [ - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/21/e2/a59ff65c26aaf21a24eb38df777cb9af5d87ba8fc8107c163c2da9d1e85e/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "7df6f6e9d0e33c7b1d435defb185095386c469109de723d514142632a7b9d07f"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6b/fa/3234f913fe9a6525a7b97c6dad1f51e72b917e6872e051a5e2ffd8b16fbb/ruamel.yaml.clib-0.2.14-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "70eda7703b8126f5e52fcf276e6c0f40b0d314674f896fc58c47b0aef2b9ae83"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ef/ec/4edbf17ac2c87fa0845dd366ef8d5852b96eb58fcd65fc1ecf5fe27b4641/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "a0cb71ccc6ef9ce36eecb6272c81afdc2f565950cdcec33ae8e6cd8f7fc86f27"}}, - {name = "ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/18/b0e1fafe59051de9e79cdd431863b03593ecfa8341c110affad7c8121efc/ruamel.yaml.clib-0.2.14-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e7cb9ad1d525d40f7d87b6df7c0ff916a66bc52cb61b66ac1b2a16d0c1b07640"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/d7/ae/e3811f05415594025e96000349d3400978adaed88d8f98d494352d9761ee/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/72/06/7d51f4688d6d72bb72fa74254e1593c4f5ebd0036be5b41fe39315b275e9/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/08/b4499234a420ef42960eeb05585df5cc7eb25ccb8c980490b079e6367050/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl",hashes = {sha256 = "1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/ba/1975a27dedf1c4c33306ee67c948121be8710b19387aada29e2f139c43ee/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/20/15/8a19a13d27f3bd09fa18813add8380a29115a47b553845f08802959acbce/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/19/ee/8d6146a079ad21e534b5083c9ee4a4c8bec42f79cf87594b60978286b39a/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a9/f5/426b714abdc222392e68f3b8ad323930d05a214a27c7e7a0f06c69126401/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl",hashes = {sha256 = "f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2"}}, - {name = "ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl",hashes = {sha256 = "090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/42/ccfb34a25289afbbc42017e4d3d4288e61d35b2e00cfc6b92974a6a1f94b/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "6aeadc170090ff1889f0d2c3057557f9cd71f975f17535c26a5d37af98f19c27"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",url = "https://files.pythonhosted.org/packages/82/73/e628a92e80197ff6a79ab81ec3fa00d4cc082d58ab78d3337b7ba7043301/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl",hashes = {sha256 = "5e56ac47260c0eed992789fa0b8efe43404a9adb608608631a948cee4fc2b052"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/c5/346c7094344a60419764b4b1334d9e0285031c961176ff88ffb652405b0c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl",hashes = {sha256 = "a911aa73588d9a8b08d662b9484bc0567949529824a55d3885b77e8dd62a127a"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/99/65080c863eb06d4498de3d6c86f3e90595e02e159fd8529f1565f56cfe2c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a05ba88adf3d7189a974b2de7a9d56731548d35dc0a822ec3dc669caa7019b29"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/3d/e3/0de85f3e3333f8e29e4b10244374a202a87665d1131798946ee22cf05c7c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "fb04c5650de6668b853623eceadcdb1a9f2fee381f5d7b6bc842ee7c239eeec4"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d9/25/0d2f09d8833c7fd77ab8efeff213093c16856479a9d293180a0d89f6bed9/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "df3ec9959241d07bc261f4983d25a1205ff37703faf42b474f15d54d88b4f8c9"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d3/8c/959f10c2e2153cbdab834c46e6954b6dd9e3b109c8f8c0a3cf1618310985/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "fbc08c02e9b147a11dfcaa1ac8a83168b699863493e183f7c0c8b12850b7d259"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/6b/e580a7c18b485e1a5f30a32cda96b20364b0ba649d9d2baaf72f8bd21f83/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c099cafc1834d3c5dac305865d04235f7c21c167c8dd31ebc3d6bbc357e2f023"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/ef/44/3455eebc761dc8e8fdced90f2b0a3fa61e32ba38b50de4130e2d57db0f21/ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl",hashes = {sha256 = "b5b0f7e294700b615a3bcf6d28b26e6da94e8eba63b079f4ec92e9ba6c0d6b54"}}, - {name = "ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/76/ab/5121f7f3b651db93de546f8c982c241397aad0a4765d793aca1dac5eadee/ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl",hashes = {sha256 = "a37f40a859b503304dd740686359fcf541d6fb3ff7fc10f539af7f7150917c68"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b3/9f/3c51e9578b8c36fcc4bdd271a1a5bb65963a74a4b6ad1a989768a22f6c2a/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5bae1a073ca4244620425cd3d3aa9746bde590992b98ee8c7c8be8c597ca0d4e"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/16/cb02815bc2ae9c66760c0c061d23c7358f9ba51dae95ac85247662b7fbe2/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl",hashes = {sha256 = "0a54e5e40a7a691a426c2703b09b0d61a14294d25cfacc00631aa6f9c964df0d"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/31/c6/fc687cd1b93bff8e40861eea46d6dc1a6a778d9a085684e4045ff26a8e40/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl",hashes = {sha256 = "10d9595b6a19778f3269399eff6bab642608e5966183abc2adbe558a42d4efc9"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/45/5d/65a2bc08b709b08576b3f307bf63951ee68a8e047cbbda6f1c9864ecf9a7/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "dba72975485f2b87b786075e18a6e5d07dc2b4d8973beb2732b9b2816f1bad70"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/fb/d0/a70a03614d9a6788a3661ab1538879ed2aae4e84d861f101243116308a37/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "29757bdb7c142f9595cc1b62ec49a3d1c83fab9cef92db52b0ccebaad4eafb98"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/30/c93fa457611f79946d5cb6cc97493ca5425f3f21891d7b1f9b44eaa1b38e/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "557df28dbccf79b152fe2d1b935f6063d9cc431199ea2b0e84892f35c03bb0ee"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/40/85/e2c54ad637117cd13244a4649946eaa00f32edcb882d1f92df90e079ab00/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "26a8de280ab0d22b6e3ec745b4a5a07151a0f74aad92dd76ab9c8d8d7087720d"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/50/f899072c38877d8ef5382e0b3d47f8c4346226c1f52d6945d6f64fec6a2f/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e501c096aa3889133d674605ebd018471bc404a59cbc17da3c5924421c54d97c"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/99/7c/96d4b5075e30c65ea2064e40c2d657c7c235d7b6ef18751cf89a935b9041/ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl",hashes = {sha256 = "915748cfc25b8cfd81b14d00f4bfdb2ab227a30d6d43459034533f4d1c207a2a"}}, - {name = "ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7d/8c/73ee2babd04e8bfcf1fd5c20aa553d18bf0ebc24b592b4f831d12ae46cc0/ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl",hashes = {sha256 = "4ccba93c1e5a40af45b2f08e4591969fa4697eae951c708f3f83dcbf9f6c6bb1"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/b4/56/35a0a752415ae01992c68f5a6513bdef0e1b6fbdb60d7619342ce12346a0/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "f8b2acb0ffdd2ce8208accbec2dca4a06937d556fdcaefd6473ba1b5daa7e3c4"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",url = "https://files.pythonhosted.org/packages/98/6a/9a68184ab93619f4607ff1675e4ef01e8accfcbff0d482f4ca44c10d8eab/ruamel.yaml.clib-0.2.14-cp310-cp310-macosx_13_0_arm64.whl",hashes = {sha256 = "aef953f3b8bd0b50bd52a2e52fb54a6a2171a1889d8dea4a5959d46c6624c451"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/3f/cfed5f088628128a9ec66f46794fd4d165642155c7b78c26d83b16c6bf7b/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux2014_aarch64.whl",hashes = {sha256 = "a0ac90efbc7a77b0d796c03c8cc4e62fd710b3f1e4c32947713ef2ef52e09543"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/d5/5ce2cc156c1da48160171968d91f066d305840fbf930ee955a509d025a44/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9bf6b699223afe6c7fe9f2ef76e0bfa6dd892c21e94ce8c957478987ade76cd8"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2b/71/d0b56bc902b38ebe4be8e270f730f929eec4edaf8a0fa7028f4ef64fa950/ruamel.yaml.clib-0.2.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "d73a0187718f6eec5b2f729b0f98e4603f7bd9c48aa65d01227d1a5dcdfbe9e8"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/db/1f37449dd89c540218598316ccafc1a0aed60215e72efa315c5367cfd015/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "81f6d3b19bc703679a5705c6a16dabdc79823c71d791d73c65949be7f3012c02"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/5d/53/c498b30f35efcd9f47cb084d7ad9374f2b907470f73913dec6396b81397d/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "b28caeaf3e670c08cb7e8de221266df8494c169bd6ed8875493fab45be9607a4"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/79/492cfad9baed68914840c39e5f3c1cc251f51a897ddb3f532601215cbb12/ruamel.yaml.clib-0.2.14-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "94f3efb718f8f49b031f2071ec7a27dd20cbfe511b4dfd54ecee54c956da2b31"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/ca/f5/479ebfd5ba396e209ade90f7282d84b90c57b3e07be8dc6fcd02a6df7ffc/ruamel.yaml.clib-0.2.14-cp310-cp310-win32.whl",hashes = {sha256 = "27c070cf3888e90d992be75dd47292ff9aa17dafd36492812a6a304a1aedc182"}}, - {name = "ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/57/31/a044520fdb3bd409889f67f1efebda0658033c7ab3f390cee37531cc9a9e/ruamel.yaml.clib-0.2.14-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4f4a150a737fccae13fb51234d41304ff2222e3b7d4c8e9428ed1a6ab48389b8"}}, -] -marker = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and \"lint\" in dependency_groups" - [packages.tool.pdm] dependencies = [] [[packages]] name = "anyio" -version = "4.11.0" +version = "4.12.1" requires-python = ">=3.9" -sdist = {name = "anyio-4.11.0.tar.gz", url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hashes = {sha256 = "82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}} +sdist = {name = "anyio-4.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hashes = {sha256 = "41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703"}} wheels = [ - {name = "anyio-4.11.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl",hashes = {sha256 = "0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}}, + {name = "anyio-4.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl",hashes = {sha256 = "d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c"}}, ] marker = "\"default\" in dependency_groups" @@ -752,30 +727,16 @@ marker = "\"default\" in dependency_groups" dependencies = [ "exceptiongroup>=1.0.2; python_version < \"3.11\"", "idna>=2.8", - "sniffio>=1.1", "typing-extensions>=4.5; python_version < \"3.13\"", ] [[packages]] name = "idna" -version = "3.10" -requires-python = ">=3.6" -sdist = {name = "idna-3.10.tar.gz", url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hashes = {sha256 = "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}} -wheels = [ - {name = "idna-3.10-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl",hashes = {sha256 = "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sniffio" -version = "1.3.1" -requires-python = ">=3.7" -sdist = {name = "sniffio-1.3.1.tar.gz", url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hashes = {sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}} +version = "3.11" +requires-python = ">=3.8" +sdist = {name = "idna-3.11.tar.gz", url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hashes = {sha256 = "795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}} wheels = [ - {name = "sniffio-1.3.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl",hashes = {sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}}, + {name = "idna-3.11-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl",hashes = {sha256 = "771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}}, ] marker = "\"default\" in dependency_groups" @@ -784,11 +745,11 @@ dependencies = [] [[packages]] name = "certifi" -version = "2025.8.3" +version = "2026.1.4" requires-python = ">=3.7" -sdist = {name = "certifi-2025.8.3.tar.gz", url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hashes = {sha256 = "e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}} +sdist = {name = "certifi-2026.1.4.tar.gz", url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hashes = {sha256 = "ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}} wheels = [ - {name = "certifi-2025.8.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl",hashes = {sha256 = "f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}}, + {name = "certifi-2026.1.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl",hashes = {sha256 = "9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}}, ] marker = "\"default\" in dependency_groups" @@ -813,11 +774,11 @@ dependencies = [ [[packages]] name = "types-requests" -version = "2.32.4.20250913" +version = "2.32.4.20260107" requires-python = ">=3.9" -sdist = {name = "types_requests-2.32.4.20250913.tar.gz", url = "https://files.pythonhosted.org/packages/36/27/489922f4505975b11de2b5ad07b4fe1dca0bca9be81a703f26c5f3acfce5/types_requests-2.32.4.20250913.tar.gz", hashes = {sha256 = "abd6d4f9ce3a9383f269775a9835a4c24e5cd6b9f647d64f88aa4613c33def5d"}} +sdist = {name = "types_requests-2.32.4.20260107.tar.gz", url = "https://files.pythonhosted.org/packages/0f/f3/a0663907082280664d745929205a89d41dffb29e89a50f753af7d57d0a96/types_requests-2.32.4.20260107.tar.gz", hashes = {sha256 = "018a11ac158f801bfa84857ddec1650750e393df8a004a8a9ae2a9bec6fcb24f"}} wheels = [ - {name = "types_requests-2.32.4.20250913-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2a/20/9a227ea57c1285986c4cf78400d0a91615d25b24e257fd9e2969606bdfae/types_requests-2.32.4.20250913-py3-none-any.whl",hashes = {sha256 = "78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1"}}, + {name = "types_requests-2.32.4.20260107-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1c/12/709ea261f2bf91ef0a26a9eed20f2623227a8ed85610c1e54c5805692ecb/types_requests-2.32.4.20260107-py3-none-any.whl",hashes = {sha256 = "b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d"}}, ] marker = "\"types\" in dependency_groups" @@ -828,11 +789,11 @@ dependencies = [ [[packages]] name = "urllib3" -version = "2.5.0" +version = "2.6.3" requires-python = ">=3.9" -sdist = {name = "urllib3-2.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hashes = {sha256 = "3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}} +sdist = {name = "urllib3-2.6.3.tar.gz", url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hashes = {sha256 = "1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}} wheels = [ - {name = "urllib3-2.5.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl",hashes = {sha256 = "e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}}, + {name = "urllib3-2.6.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl",hashes = {sha256 = "bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}}, ] marker = "\"types\" in dependency_groups" @@ -841,11 +802,11 @@ dependencies = [] [[packages]] name = "tzdata" -version = "2025.2" +version = "2025.3" requires-python = ">=2" -sdist = {name = "tzdata-2025.2.tar.gz", url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hashes = {sha256 = "b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}} +sdist = {name = "tzdata-2025.3.tar.gz", url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hashes = {sha256 = "de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7"}} wheels = [ - {name = "tzdata-2025.2-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl",hashes = {sha256 = "1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}}, + {name = "tzdata-2025.3-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl",hashes = {sha256 = "06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}}, ] marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" @@ -853,7 +814,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "a3b22dcb6e46e060513881b655a5824b61606a56fcce33d669d58321ed9c947f"} +hashes = {sha256 = "0c0e9208d38f65d8253d8fa6094d6d32dd41f91a12e3ab69ff765e694312f812"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pyproject.toml b/pyproject.toml index 6a1eefe..91ddeb8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "pdm.backend" [project] name = "ldlite" -version = "3.2.0" +version = "3.2.1" description = "Lightweight analytics tool for FOLIO services" authors = [ { name = "Katherine Bargar", email = "kbargar@fivecolleges.edu" }, @@ -16,8 +16,8 @@ dependencies = [ "duckdb>=0.9.2,<1.4", # 4.64 is the first release with type stubs "tqdm>=4.64.0", - # 0.2 has query parameter handling, 0.2.3 is a required bug fix version - "httpx-folio>=0.2.3", + # 0.3 allows checking the path for id based paging + "httpx-folio>=0.3.0", # 3.9 introduces orjson.Fragment "orjson>=3.9", # 3.2 changes the sql.SQL.format signature diff --git a/src/ldlite/_folio.py b/src/ldlite/_folio.py index 1fa87fa..a7deffe 100644 --- a/src/ldlite/_folio.py +++ b/src/ldlite/_folio.py @@ -58,11 +58,26 @@ def iterate_records( if is_srs: return (r, self._iterate_records_srs(client_opts, path, params)) - key = cast("str", next(iter(j.keys()))) + # folio records usually have additional keys besides the actual list + # the items are usually first but not always + # so we check for keys until we find a good one + # totalRecords and erm as of right now are the only keys like this + # but there may end up with more + keys = iter(j.keys()) + while (key := next(keys)) and key in [ + "totalRecords", + "pageSize", + "page", + "totalPages", + "meta", + "total", + ]: + continue + r1 = j[key][0] if ( nonid_key := cast("str", next(iter(r1.keys()))) if "id" not in r1 else None - ) or not params.can_page_by_id(): + ) or not params.can_page_by_id(path=path): return ( r, self._iterate_records_offset( diff --git a/tests/mock_response_case.py b/tests/mock_response_case.py index 353be9e..dffc56e 100644 --- a/tests/mock_response_case.py +++ b/tests/mock_response_case.py @@ -57,10 +57,13 @@ def patch_request_get( httpx_post_mock.return_value.cookies.__getitem__.return_value = "token" side_effects = [] - for call in self.calls_list: - key = next(iter(call.returns_list[0].keys())) + for i, call in enumerate(self.calls_list): + *_, key = iter(call.returns_list[0].keys()) total_mock = MagicMock() - total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' + if i % 2 == 0: + total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' + else: + total_mock.text = f'{{"totalRecords": 100000, "{key}": [{{"id": ""}}]}}' value_mocks = [] for v in call.returns_list: diff --git a/tests/test_query.py b/tests/test_query.py index fbc8ceb..5e686de 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -602,6 +602,41 @@ def case_null_records() -> QueryTC: ) +def case_erm_keys() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=3, + returns={ + "pageSize": 30, + "page": 1, + "totalPages": 10, + "meta": {"updated": "by"}, + "total": 285, + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + ], + }, + ), + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + ["id", "value"], + [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], + ), + "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ], + ) + + def _arrange( client_get_mock: MagicMock, httpx_post_mock: MagicMock, From 3999d6fe3f3044ce94f2e44ab0a8b39e5ab39320 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Tue, 10 Feb 2026 13:59:44 -0500 Subject: [PATCH 12/25] Rework history table to record intervals (#62) This has been running on the Five Colleges instance for awhile and works well for the most part. Thinking about the future, the download, transform, and index portions might not all happen one after another. The thing that we really care about is the time it takes so that is what we're recording. The download time is still relevant as that is how fresh the data is. The start time is relevant to group different loads together. This is a "breaking" change but only if someone has installed the unreleased v4 version. The code around the database setup has also been refactored to keep the postgres error handling in postgres and slim down the _database/__init__.py file as it was hard to work in for this PR. --- src/ldlite/__init__.py | 17 +- src/ldlite/_database/__init__.py | 206 +------------------------ src/ldlite/_database/duckdb.py | 3 +- src/ldlite/_database/postgres.py | 24 ++- src/ldlite/_database/typed_database.py | 192 +++++++++++++++++++++++ tests/test_load_history.py | 11 +- 6 files changed, 240 insertions(+), 213 deletions(-) create mode 100644 src/ldlite/_database/typed_database.py diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 271c791..c15b2e2 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -318,6 +318,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 file=sys.stderr, ) + download_started = datetime.now(timezone.utc) processed = self._db.ingest_records( prefix, cast( @@ -336,7 +337,9 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 ), ) download = datetime.now(timezone.utc) + download_elapsed = datetime.now(timezone.utc) - download_started + transform_started = datetime.now(timezone.utc) self._db.drop_extracted_tables(prefix) newtables = [table] newattrs = {} @@ -359,10 +362,11 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 if not keep_raw: self._db.drop_raw_table(prefix) + transform_elapsed = datetime.now(timezone.utc) - transform_started finally: - transformed = datetime.now(timezone.utc) autocommit(self.db, self.dbtype, True) # Create indexes on id columns (for postgres) + index_started = datetime.now(timezone.utc) if self.dbtype == DBType.POSTGRES: class PbarNoop: @@ -402,17 +406,18 @@ def close(self) -> None: ... cur.close() pbar.update(1) pbar.close() - index = datetime.now(timezone.utc) + index_elapsed = datetime.now(timezone.utc) - index_started self._db.record_history( LoadHistory( prefix, path, query if query and isinstance(query, str) else None, - start, - download, - transformed, - index, processed, + download, + start, + download_elapsed, + transform_elapsed, + index_elapsed, ), ) # Return table names diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py index 0cae6c7..afe28c9 100644 --- a/src/ldlite/_database/__init__.py +++ b/src/ldlite/_database/__init__.py @@ -1,17 +1,10 @@ import datetime from abc import ABC, abstractmethod -from collections.abc import Callable, Iterator, Sequence -from contextlib import closing +from collections.abc import Iterator from dataclasses import dataclass -from datetime import timezone -from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast -import psycopg from psycopg import sql -if TYPE_CHECKING: - import duckdb - class Prefix: def __init__(self, prefix: str): @@ -68,11 +61,12 @@ class LoadHistory: table_name: Prefix path: str query: str | None - start: datetime.datetime - download: datetime.datetime - transform: datetime.datetime - index: datetime.datetime total: int + download_time: datetime.datetime + start_time: datetime.datetime + download_interval: datetime.timedelta + transform_interval: datetime.timedelta + index_interval: datetime.timedelta class Database(ABC): @@ -90,191 +84,3 @@ def ingest_records(self, prefix: Prefix, records: Iterator[bytes]) -> int: ... @abstractmethod def record_history(self, history: LoadHistory) -> None: ... - - -DB = TypeVar("DB", bound="duckdb.DuckDBPyConnection | psycopg.Connection") - - -class TypedDatabase(Database, Generic[DB]): - def __init__(self, conn_factory: Callable[[], DB]): - self._conn_factory = conn_factory - with closing(self._conn_factory()) as conn: - try: - with conn.cursor() as cur: - cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') - cur.execute(""" -CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history" ( - "table_name" TEXT UNIQUE - ,"path" TEXT - ,"query" TEXT - ,"start_utc" TIMESTAMP - ,"download_complete_utc" TIMESTAMP - ,"transformation_complete_utc" TIMESTAMP - ,"index_complete_utc" TIMESTAMP - ,"row_count" INTEGER -);""") - - self._setup_jfuncs(conn) - except psycopg.errors.UniqueViolation: - # postgres throws a couple of errors when multiple threads try to create - # the same resource even if CREATE IF NOT EXISTS was used - # if we get it then something else created the ldlite_system - # resources and it is ok to not commit - # I'm not happy with this being in the base class but it's probably fine - ... - except psycopg.errors.InternalError_ as e: - if str(e) != "tuple concurrently updated": - raise - else: - conn.commit() - - @staticmethod - @abstractmethod - def _setup_jfuncs(conn: DB) -> None: ... - - @property - @abstractmethod - def _default_schema(self) -> str: ... - - def drop_prefix( - self, - prefix: Prefix, - ) -> None: - with closing(self._conn_factory()) as conn: - self._drop_extracted_tables(conn, prefix) - self._drop_raw_table(conn, prefix) - conn.execute( - 'DELETE FROM "ldlite_system"."load_history" WHERE "table_name" = $1', - (prefix.load_history_key,), - ) - conn.commit() - - def drop_raw_table( - self, - prefix: Prefix, - ) -> None: - with closing(self._conn_factory()) as conn: - self._drop_raw_table(conn, prefix) - conn.commit() - - def _drop_raw_table( - self, - conn: DB, - prefix: Prefix, - ) -> None: - with closing(conn.cursor()) as cur: - cur.execute( - sql.SQL("DROP TABLE IF EXISTS {table};") - .format(table=prefix.raw_table_identifier) - .as_string(), - ) - - def drop_extracted_tables( - self, - prefix: Prefix, - ) -> None: - with closing(self._conn_factory()) as conn: - self._drop_extracted_tables(conn, prefix) - conn.commit() - - def _drop_extracted_tables( - self, - conn: DB, - prefix: Prefix, - ) -> None: - tables: list[Sequence[Sequence[Any]]] = [] - with closing(conn.cursor()) as cur: - cur.execute( - """ -SELECT table_name FROM information_schema.tables -WHERE table_schema = $1 and table_name IN ($2, $3);""", - ( - prefix.schema or self._default_schema, - prefix.catalog_table_name, - prefix.legacy_jtable_name, - ), - ) - for (tname,) in cur.fetchall(): - if tname == prefix.catalog_table_name: - cur.execute( - sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.catalog_table_identifier) - .as_string(), - ) - tables.extend(cur.fetchall()) - - if tname == prefix.legacy_jtable_name: - cur.execute( - sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.legacy_jtable_identifier) - .as_string(), - ) - tables.extend(cur.fetchall()) - - with closing(conn.cursor()) as cur: - for (et,) in tables: - cur.execute( - sql.SQL("DROP TABLE IF EXISTS {table};") - .format(table=sql.Identifier(cast("str", et))) - .as_string(), - ) - cur.execute( - sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.catalog_table_identifier) - .as_string(), - ) - cur.execute( - sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.legacy_jtable_identifier) - .as_string(), - ) - - @property - @abstractmethod - def _create_raw_table_sql(self) -> sql.SQL: ... - def _prepare_raw_table( - self, - conn: DB, - prefix: Prefix, - ) -> None: - with closing(conn.cursor()) as cur: - if prefix.schema_identifier is not None: - cur.execute( - sql.SQL("CREATE SCHEMA IF NOT EXISTS {schema};") - .format(schema=prefix.schema_identifier) - .as_string(), - ) - self._drop_raw_table(conn, prefix) - with closing(conn.cursor()) as cur: - cur.execute( - self._create_raw_table_sql.format( - table=prefix.raw_table_identifier, - ).as_string(), - ) - - def record_history(self, history: LoadHistory) -> None: - with closing(self._conn_factory()) as conn, conn.cursor() as cur: - cur.execute( - """ -INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7,$8) -ON CONFLICT ("table_name") DO UPDATE SET - "path" = EXCLUDED."path" - ,"query" = EXCLUDED."query" - ,"start_utc" = EXCLUDED."start_utc" - ,"download_complete_utc" = EXCLUDED."download_complete_utc" - ,"transformation_complete_utc" = EXCLUDED."transformation_complete_utc" - ,"index_complete_utc" = EXCLUDED."index_complete_utc" - ,"row_count" = EXCLUDED."row_count" -""", - ( - history.table_name.load_history_key, - history.path, - history.query, - history.start.astimezone(timezone.utc), - history.download.astimezone(timezone.utc), - history.transform.astimezone(timezone.utc), - history.index.astimezone(timezone.utc), - history.total, - ), - ) - conn.commit() diff --git a/src/ldlite/_database/duckdb.py b/src/ldlite/_database/duckdb.py index c9b994a..898356d 100644 --- a/src/ldlite/_database/duckdb.py +++ b/src/ldlite/_database/duckdb.py @@ -4,7 +4,8 @@ import duckdb from psycopg import sql -from . import Prefix, TypedDatabase +from . import Prefix +from .typed_database import TypedDatabase class DuckDbDatabase(TypedDatabase[duckdb.DuckDBPyConnection]): diff --git a/src/ldlite/_database/postgres.py b/src/ldlite/_database/postgres.py index 7a78477..2c29977 100644 --- a/src/ldlite/_database/postgres.py +++ b/src/ldlite/_database/postgres.py @@ -4,14 +4,30 @@ import psycopg from psycopg import sql -from . import Prefix, TypedDatabase +from . import Prefix +from .typed_database import TypedDatabase class PostgresDatabase(TypedDatabase[psycopg.Connection]): def __init__(self, dsn: str): - # RawCursor lets us use $1, $2, etc to use the - # same sql between duckdb and postgres - super().__init__(lambda: psycopg.connect(dsn, cursor_factory=psycopg.RawCursor)) + try: + # RawCursor lets us use $1, $2, etc to use the + # same sql between duckdb and postgres + super().__init__( + lambda: psycopg.connect( + dsn, + cursor_factory=psycopg.RawCursor, + ), + ) + except psycopg.errors.UniqueViolation: + # postgres throws a couple of errors when multiple threads try to create + # the same resource even if CREATE IF NOT EXISTS was used + # if we get it then something else created the ldlite_system + # resources and it is ok to not commit + pass + except psycopg.errors.InternalError_ as e: + if str(e) != "tuple concurrently updated": + raise @staticmethod def _setup_jfuncs(conn: psycopg.Connection) -> None: diff --git a/src/ldlite/_database/typed_database.py b/src/ldlite/_database/typed_database.py new file mode 100644 index 0000000..1927d4c --- /dev/null +++ b/src/ldlite/_database/typed_database.py @@ -0,0 +1,192 @@ +from abc import abstractmethod +from collections.abc import Callable, Sequence +from contextlib import closing +from datetime import timezone +from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast + +import psycopg +from psycopg import sql + +from . import Database, LoadHistory, Prefix + +if TYPE_CHECKING: + import duckdb + + +DB = TypeVar("DB", bound="duckdb.DuckDBPyConnection | psycopg.Connection") + + +class TypedDatabase(Database, Generic[DB]): + def __init__(self, conn_factory: Callable[[], DB]): + self._conn_factory = conn_factory + with closing(self._conn_factory()) as conn: + with conn.cursor() as cur: + cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') + cur.execute(""" +CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history" ( + "table_name" TEXT UNIQUE + ,"path" TEXT + ,"query" TEXT + ,"row_count" INTEGER + ,"download_complete_utc" TIMESTAMP + ,"start_utc" TIMESTAMP + ,"download_time" INTERVAL + ,"transform_time" INTERVAL + ,"index_time" INTERVAL +);""") + + self._setup_jfuncs(conn) + conn.commit() + + @staticmethod + @abstractmethod + def _setup_jfuncs(conn: DB) -> None: ... + + @property + @abstractmethod + def _default_schema(self) -> str: ... + + def drop_prefix( + self, + prefix: Prefix, + ) -> None: + with closing(self._conn_factory()) as conn: + self._drop_extracted_tables(conn, prefix) + self._drop_raw_table(conn, prefix) + conn.execute( + 'DELETE FROM "ldlite_system"."load_history" WHERE "table_name" = $1', + (prefix.load_history_key,), + ) + conn.commit() + + def drop_raw_table( + self, + prefix: Prefix, + ) -> None: + with closing(self._conn_factory()) as conn: + self._drop_raw_table(conn, prefix) + conn.commit() + + def _drop_raw_table( + self, + conn: DB, + prefix: Prefix, + ) -> None: + with closing(conn.cursor()) as cur: + cur.execute( + sql.SQL("DROP TABLE IF EXISTS {table};") + .format(table=prefix.raw_table_identifier) + .as_string(), + ) + + def drop_extracted_tables( + self, + prefix: Prefix, + ) -> None: + with closing(self._conn_factory()) as conn: + self._drop_extracted_tables(conn, prefix) + conn.commit() + + def _drop_extracted_tables( + self, + conn: DB, + prefix: Prefix, + ) -> None: + tables: list[Sequence[Sequence[Any]]] = [] + with closing(conn.cursor()) as cur: + cur.execute( + """ +SELECT table_name FROM information_schema.tables +WHERE table_schema = $1 and table_name IN ($2, $3);""", + ( + prefix.schema or self._default_schema, + prefix.catalog_table_name, + prefix.legacy_jtable_name, + ), + ) + for (tname,) in cur.fetchall(): + if tname == prefix.catalog_table_name: + cur.execute( + sql.SQL("SELECT table_name FROM {catalog};") + .format(catalog=prefix.catalog_table_identifier) + .as_string(), + ) + tables.extend(cur.fetchall()) + + if tname == prefix.legacy_jtable_name: + cur.execute( + sql.SQL("SELECT table_name FROM {catalog};") + .format(catalog=prefix.legacy_jtable_identifier) + .as_string(), + ) + tables.extend(cur.fetchall()) + + with closing(conn.cursor()) as cur: + for (et,) in tables: + cur.execute( + sql.SQL("DROP TABLE IF EXISTS {table};") + .format(table=sql.Identifier(cast("str", et))) + .as_string(), + ) + cur.execute( + sql.SQL("DROP TABLE IF EXISTS {catalog};") + .format(catalog=prefix.catalog_table_identifier) + .as_string(), + ) + cur.execute( + sql.SQL("DROP TABLE IF EXISTS {catalog};") + .format(catalog=prefix.legacy_jtable_identifier) + .as_string(), + ) + + @property + @abstractmethod + def _create_raw_table_sql(self) -> sql.SQL: ... + def _prepare_raw_table( + self, + conn: DB, + prefix: Prefix, + ) -> None: + with closing(conn.cursor()) as cur: + if prefix.schema_identifier is not None: + cur.execute( + sql.SQL("CREATE SCHEMA IF NOT EXISTS {schema};") + .format(schema=prefix.schema_identifier) + .as_string(), + ) + self._drop_raw_table(conn, prefix) + with closing(conn.cursor()) as cur: + cur.execute( + self._create_raw_table_sql.format( + table=prefix.raw_table_identifier, + ).as_string(), + ) + + def record_history(self, history: LoadHistory) -> None: + with closing(self._conn_factory()) as conn, conn.cursor() as cur: + cur.execute( + """ +INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9) +ON CONFLICT ("table_name") DO UPDATE SET + "path" = EXCLUDED."path" + ,"query" = EXCLUDED."query" + ,"row_count" = EXCLUDED."row_count" + ,"download_complete_utc" = EXCLUDED."download_complete_utc" + ,"start_utc" = EXCLUDED."start_utc" + ,"download_time" = EXCLUDED."download_time" + ,"transform_time" = EXCLUDED."transform_time" + ,"index_time" = EXCLUDED."index_time" +""", + ( + history.table_name.load_history_key, + history.path, + history.query, + history.total, + history.download_time.astimezone(timezone.utc), + history.start_time.astimezone(timezone.utc), + history.download_interval, + history.transform_interval, + history.index_interval, + ), + ) + conn.commit() diff --git a/tests/test_load_history.py b/tests/test_load_history.py index 78899aa..b6afa24 100644 --- a/tests/test_load_history.py +++ b/tests/test_load_history.py @@ -1,6 +1,7 @@ from collections.abc import Callable from contextlib import closing from dataclasses import dataclass +from datetime import timedelta from typing import TYPE_CHECKING, cast from unittest import mock from unittest.mock import MagicMock @@ -137,8 +138,14 @@ def _assert( assert (d := cur.fetchone()) is not None assert d[1] == "/patched" assert d[2] == q - assert d[7] == t - assert d[6] > d[5] > d[4] > d[3] + assert d[3] == t + assert d[4] > d[5] + assert d[6] > timedelta(microseconds=0) + assert d[6] < timedelta(seconds=1) + assert d[7] > timedelta(microseconds=0) + assert d[7] < timedelta(seconds=1) + assert d[8] > timedelta(microseconds=0) + assert d[8] < timedelta(seconds=1) @mock.patch("httpx_folio.auth.httpx.post") From f141ab5271aa895807cf956122b64b954ea156f9 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Wed, 25 Feb 2026 16:15:47 -0500 Subject: [PATCH 13/25] Implement server side transform for json (#64) Currently LDLite reads every row back 1 by 1 from the server (maybe twice). It then goes through an elaborate hand parsing and conversion process. So far I've avoided touching this part of the code because it isn't possible to test but there are improvements I want to make to it and it is the last real "here be dragons" section. The biggest improvement I'd like to make is the performance. For small tables performance doesn't really matter but the largest table at Five Colleges takes over a day to transform. The next three largest take over 12 hours and there are five more tables that take over 30 minutes. In order to accomplish this I've move the transformation logic into the database. This means that the data never has to leave the server and can take full advantage of the resources of the database to do batch operations. A side effect of doing the transformation in SQL is getting better type information since we're able to operate on all the data at once. It isn't happening in this PR but we have information to differentiate integers/numeric, bools, datetimes, and uuids. (we always could do uuids but it required manually trying to cast it in python which is sloooow). A hope is that if this proves to be maintainable and fast is that we can use a similar pattern for the marc transformations and no longer have to use the ldpmarc standalone tool which requires having a disk. That would allow us to dockerize LDLite. As far as the implementation... This was a nightmare to make work and also make maintainable. I feel like a struck on ok balance for the first pass but I'm not 100% happy with how everything is abstracted. I'm especially unhappy about the CTE hack for postgres and monkey patching the close method hack for duckdb. There were necessary to make them work like each other. The actual algorithm for expansion is roughly 1. Choose the raw table as the root table 2. Recursively unnest all objects into the same table (this actually uses a queue and not pure recursion) 3. Get all the array columns and explode each of them into a new table 4. Run the unnest/explode algorithm again with the new array table as the root table (this is actually recursive) A tree structure built via nodes was used to track the relationships. This helps us track the json_depth without having to explicitly keep a depth count because we can just count the parents. It also helps us fill the array table with the appropriate values. Array tables only have columns from parent and grandparent objects even if those objects have siblings and uncles. This has been tested as a proof of concept independently of LDLite just running queries against postgres and I estimate at least a 10x improvement. This does not actually setup LDLite to use this new method. That will be in a future PR because this one was already getting unruly. Additionally, the minimal set of depths is broken because DuckDB will have to be upgraded to 1.3 in order to utilize the json_each function and make the MonkeyPatching hack work. This will happen in another PR. --- src/ldlite/__init__.py | 40 +- src/ldlite/_database/__init__.py | 86 --- src/ldlite/database/__init__.py | 55 ++ .../duckdb.py => database/_duckdb.py} | 90 ++- src/ldlite/database/_expansion/__init__.py | 173 +++++ src/ldlite/database/_expansion/metadata.py | 63 ++ src/ldlite/database/_expansion/nodes.py | 309 +++++++++ .../postgres.py => database/_postgres.py} | 158 +++-- src/ldlite/database/_prefix.py | 64 ++ .../_typed_database.py} | 101 ++- tests/test_expansion.py | 601 ++++++++++++++++++ tests/test_json_operators.py | 91 ++- tests/test_query.py | 117 ++++ 13 files changed, 1746 insertions(+), 202 deletions(-) delete mode 100644 src/ldlite/_database/__init__.py create mode 100644 src/ldlite/database/__init__.py rename src/ldlite/{_database/duckdb.py => database/_duckdb.py} (58%) create mode 100644 src/ldlite/database/_expansion/__init__.py create mode 100644 src/ldlite/database/_expansion/metadata.py create mode 100644 src/ldlite/database/_expansion/nodes.py rename src/ldlite/{_database/postgres.py => database/_postgres.py} (54%) create mode 100644 src/ldlite/database/_prefix.py rename src/ldlite/{_database/typed_database.py => database/_typed_database.py} (63%) create mode 100644 tests/test_expansion.py diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index c15b2e2..42d3cf0 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -44,7 +44,6 @@ from tqdm import tqdm from ._csv import to_csv -from ._database import Database, LoadHistory, Prefix from ._folio import FolioClient from ._jsonx import Attr, transform_json from ._select import select @@ -54,6 +53,7 @@ autocommit, sqlid, ) +from .database import Database, LoadHistory if TYPE_CHECKING: from collections.abc import Iterator @@ -78,7 +78,7 @@ def __init__(self) -> None: self._quiet = False self.dbtype: DBType = DBType.UNDEFINED self.db: dbapi.DBAPIConnection | None = None - self._db: Database | None = None + self._database: Database | None = None self._folio: FolioClient | None = None self.page_size = 1000 self._okapi_timeout = 60 @@ -125,13 +125,13 @@ def _connect_db_duckdb( db = ld.connect_db_duckdb(filename='ldlite.db') """ - from ._database.duckdb import DuckDbDatabase # noqa: PLC0415 + from .database._duckdb import DuckDbDatabase # noqa: PLC0415 self.dbtype = DBType.DUCKDB fn = filename if filename is not None else ":memory:" db = duckdb.connect(database=fn) self.db = cast("dbapi.DBAPIConnection", db.cursor()) - self._db = DuckDbDatabase(lambda: db.cursor()) + self._database = DuckDbDatabase(db) return db.cursor() @@ -146,18 +146,26 @@ def connect_db_postgresql(self, dsn: str) -> psycopg.Connection: db = ld.connect_db_postgresql(dsn='dbname=ld host=localhost user=ldlite') """ - from ._database.postgres import PostgresDatabase # noqa: PLC0415 + from .database._postgres import PostgresDatabase # noqa: PLC0415 self.dbtype = DBType.POSTGRES db = psycopg.connect(dsn) self.db = cast("dbapi.DBAPIConnection", db) - self._db = PostgresDatabase(dsn) + self._database = PostgresDatabase(dsn) ret_db = psycopg.connect(dsn) ret_db.rollback() ret_db.set_autocommit(True) return ret_db + @property + def database_experimental(self) -> Database | None: + """The current Database implementation used by LDLite. + + This is experimental and isn't really intended for public consumption. + """ + return self._database + def _check_folio(self) -> None: if self._folio is None: msg = "connection to folio not configured: use connect_folio()" @@ -196,11 +204,10 @@ def drop_tables(self, table: str) -> None: ld.drop_tables('g') """ - if self.db is None or self._db is None: + if self.db is None or self._database is None: self._check_db() return - prefix = Prefix(table) - self._db.drop_prefix(prefix) + self._database.drop_prefix(table) def set_folio_max_retries(self, max_retries: int) -> None: """Sets the maximum number of retries for FOLIO requests. @@ -294,11 +301,10 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 if self._folio is None: self._check_folio() return [] - if self.db is None or self._db is None: + if self.db is None or self._database is None: self._check_db() return [] start = datetime.now(timezone.utc) - prefix = Prefix(table) if not self._quiet: print("ldlite: querying: " + path, file=sys.stderr) try: @@ -319,8 +325,8 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 ) download_started = datetime.now(timezone.utc) - processed = self._db.ingest_records( - prefix, + processed = self._database.ingest_records( + table, cast( "Iterator[bytes]", tqdm( @@ -340,7 +346,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 download_elapsed = datetime.now(timezone.utc) - download_started transform_started = datetime.now(timezone.utc) - self._db.drop_extracted_tables(prefix) + self._database.drop_extracted_tables(table) newtables = [table] newattrs = {} if json_depth > 0: @@ -360,7 +366,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 newattrs[table] = {"__id": Attr("__id", "bigint")} if not keep_raw: - self._db.drop_raw_table(prefix) + self._database.drop_raw_table(table) transform_elapsed = datetime.now(timezone.utc) - transform_started finally: @@ -407,9 +413,9 @@ def close(self) -> None: ... pbar.update(1) pbar.close() index_elapsed = datetime.now(timezone.utc) - index_started - self._db.record_history( + self._database.record_history( LoadHistory( - prefix, + table, path, query if query and isinstance(query, str) else None, processed, diff --git a/src/ldlite/_database/__init__.py b/src/ldlite/_database/__init__.py deleted file mode 100644 index afe28c9..0000000 --- a/src/ldlite/_database/__init__.py +++ /dev/null @@ -1,86 +0,0 @@ -import datetime -from abc import ABC, abstractmethod -from collections.abc import Iterator -from dataclasses import dataclass - -from psycopg import sql - - -class Prefix: - def __init__(self, prefix: str): - self.schema: str | None = None - sandt = prefix.split(".") - if len(sandt) > 2: - msg = f"Expected one or two identifiers but got {prefix}" - raise ValueError(msg) - - if len(sandt) == 1: - (self._prefix,) = sandt - else: - (self.schema, self._prefix) = sandt - - def _identifier(self, table: str) -> sql.Identifier: - if self.schema is None: - return sql.Identifier(table) - return sql.Identifier(self.schema, table) - - @property - def schema_identifier(self) -> sql.Identifier | None: - return None if self.schema is None else sql.Identifier(self.schema) - - @property - def raw_table_identifier(self) -> sql.Identifier: - return self._identifier(self._prefix) - - @property - def catalog_table_name(self) -> str: - return f"{self._prefix}__tcatalog" - - @property - def catalog_table_identifier(self) -> sql.Identifier: - return self._identifier(self.catalog_table_name) - - @property - def legacy_jtable_name(self) -> str: - return f"{self._prefix}_jtable" - - @property - def legacy_jtable_identifier(self) -> sql.Identifier: - return self._identifier(self.legacy_jtable_name) - - @property - def load_history_key(self) -> str: - if self.schema is None: - return self._prefix - - return self.schema + "." + self._prefix - - -@dataclass(frozen=True) -class LoadHistory: - table_name: Prefix - path: str - query: str | None - total: int - download_time: datetime.datetime - start_time: datetime.datetime - download_interval: datetime.timedelta - transform_interval: datetime.timedelta - index_interval: datetime.timedelta - - -class Database(ABC): - @abstractmethod - def drop_prefix(self, prefix: Prefix) -> None: ... - - @abstractmethod - def drop_raw_table(self, prefix: Prefix) -> None: ... - - @abstractmethod - def drop_extracted_tables(self, prefix: Prefix) -> None: ... - - @abstractmethod - def ingest_records(self, prefix: Prefix, records: Iterator[bytes]) -> int: ... - - @abstractmethod - def record_history(self, history: LoadHistory) -> None: ... diff --git a/src/ldlite/database/__init__.py b/src/ldlite/database/__init__.py new file mode 100644 index 0000000..1e67fb7 --- /dev/null +++ b/src/ldlite/database/__init__.py @@ -0,0 +1,55 @@ +"""A module for implementing ldlite database targets.""" + +import datetime +from abc import ABC, abstractmethod +from collections.abc import Iterator +from dataclasses import dataclass + + +@dataclass(frozen=True) +class LoadHistory: + """Represents the statistics and history of a single ldlite operation.""" + + table_name: str + path: str + query: str | None + total: int + download_time: datetime.datetime + start_time: datetime.datetime + download_interval: datetime.timedelta + transform_interval: datetime.timedelta + index_interval: datetime.timedelta + + +class Database(ABC): + """The required interface for LDLite to utilite a database.""" + + @abstractmethod + def drop_prefix(self, prefix: str) -> None: + """Drops all tables with the given prefix.""" + + @abstractmethod + def drop_raw_table(self, prefix: str) -> None: + """Drops the raw table for a given prefix. + + This is deprecated and will be removed in a future release. + """ + + @abstractmethod + def drop_extracted_tables(self, prefix: str) -> None: + """Drops any extracted tables for a given prefix. + + This is deprecated and will be removed in a future release. + """ + + @abstractmethod + def ingest_records(self, prefix: str, records: Iterator[bytes]) -> int: + """Ingests a stream of records dowloaded from FOLIO to the raw table.""" + + @abstractmethod + def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> None: + """Unnests and explodes the raw data at the given prefix.""" + + @abstractmethod + def record_history(self, history: LoadHistory) -> None: + """Records the statistics and history of a single ldlite operation.""" diff --git a/src/ldlite/_database/duckdb.py b/src/ldlite/database/_duckdb.py similarity index 58% rename from src/ldlite/_database/duckdb.py rename to src/ldlite/database/_duckdb.py index 898356d..a11045e 100644 --- a/src/ldlite/_database/duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -1,14 +1,27 @@ from collections.abc import Iterator from itertools import count +from typing import TYPE_CHECKING, Any, cast import duckdb from psycopg import sql -from . import Prefix -from .typed_database import TypedDatabase +from ._prefix import Prefix +from ._typed_database import TypedDatabase + +if TYPE_CHECKING: + from typing_extensions import Self class DuckDbDatabase(TypedDatabase[duckdb.DuckDBPyConnection]): + def __init__(self, db: duckdb.DuckDBPyConnection) -> None: + # See the notes below for why we're monkey patching DuckDB + super().__init__( + lambda: cast( + "duckdb.DuckDBPyConnection", + _MonkeyDBPyConnection(db.cursor()), + ), + ) + @staticmethod def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: with conn.cursor() as cur: @@ -80,9 +93,17 @@ def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: ; CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j) AS - coalesce(main.json_type(j), 'NULL')='DOUBLE' + coalesce(main.json_type(j), 'NULL') == 'DOUBLE' ; +CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j) AS + j is NULL or j == 'null'::JSON +; + +CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j) AS TABLE ( + SELECT value FROM main.json_each(j) +); + """, # noqa: E501 ) @@ -96,18 +117,17 @@ def _create_raw_table_sql(self) -> sql.SQL: def ingest_records( self, - prefix: Prefix, + prefix: str, records: Iterator[bytes], ) -> int: + pfx = Prefix(prefix) pkey = count(1) with self._conn_factory() as conn: - self._prepare_raw_table(conn, prefix) + self._prepare_raw_table(conn, pfx) insert_sql = ( sql.SQL("INSERT INTO {table} VALUES(?, ?);") - .format( - table=prefix.raw_table_identifier, - ) + .format(table=pfx.schemafy(pfx.raw_table)) .as_string() ) # duckdb has better performance bulk inserting in a transaction @@ -117,3 +137,57 @@ def ingest_records( tx.commit() return next(pkey) - 1 + + def source_table_cte_stmt(self, keep_source: bool) -> str: # noqa: ARG002 + return "WITH ld_source AS (SELECT * FROM {source_table})" + + +# DuckDB has some strong opinions about cursors that are different than postgres +# https://github.com/duckdb/duckdb/issues/11018 +class _MonkeyDBPyCursor: + def __init__(self, cur: duckdb.DuckDBPyConnection) -> None: + self._cur = cur + + # We're patching out the close on the cursor + # This is so that temp tables aren't closed with the cursor + def close(self) -> None: + return None + + """ + # This exists to quickly print out any sql executed during tests + # Uncomment in production at your own peril + def execute(self, *args, **kwargs) -> duckdb.DuckDBPyConnection: + print(args[0]) + return self._cur.execute(*args, **kwargs) + """ + + def __enter__(self) -> "Self": + return self + + def __exit__(self, exc_type, exc, tb) -> None: # type: ignore[no-untyped-def] # noqa: ANN001 + return None + + def __getattr__(self, name: str) -> Any: # noqa: ANN401 + return getattr(self._cur, name) + + +class _MonkeyDBPyConnection: + def __init__(self, conn: duckdb.DuckDBPyConnection) -> None: + self._conn = conn + + # This fakes creating a cursor + # DuckDB doesn't need them and they're each essentially a new connection + def cursor(self) -> _MonkeyDBPyCursor: + return _MonkeyDBPyCursor(self._conn) + + def __enter__(self) -> "Self": + return self + + def __exit__(self, exc_type, exc, tb) -> None: # type: ignore[no-untyped-def] # noqa: ANN001 + return self.close() + + def close(self) -> None: + return self._conn.close() + + def __getattr__(self, name: str) -> Any: # noqa: ANN401 + return getattr(self._conn, name) diff --git a/src/ldlite/database/_expansion/__init__.py b/src/ldlite/database/_expansion/__init__.py new file mode 100644 index 0000000..0afc37e --- /dev/null +++ b/src/ldlite/database/_expansion/__init__.py @@ -0,0 +1,173 @@ +from __future__ import annotations + +from collections import deque +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from psycopg import sql + +from .nodes import ArrayNode, ObjectNode + +if TYPE_CHECKING: + from collections.abc import Callable + + import duckdb + import psycopg + + +@dataclass +class ExpandContext: + conn: duckdb.DuckDBPyConnection | psycopg.Connection + source_table: sql.Identifier + json_depth: int + get_transform_table: Callable[[int], sql.Identifier] + get_output_table: Callable[[str], sql.Identifier] + # This is necessary for Analyzing the table in pg before querying it + # I don't love how this is implemented + preprocess: Callable[ + [ + duckdb.DuckDBPyConnection | psycopg.Connection, + sql.Identifier, + list[sql.Identifier], + ], + None, + ] + # source_cte will go away when DuckDB implements CTAS RETURNING + source_cte: Callable[[bool], str] + + def array_context( + self, + new_source_table: sql.Identifier, + new_json_depth: int, + ) -> ExpandContext: + return ExpandContext( + self.conn, + new_source_table, + new_json_depth, + self.get_transform_table, + self.get_output_table, + self.preprocess, + self.source_cte, + ) + + +def expand_nonmarc( + root_name: str, + root_values: list[str], + ctx: ExpandContext, +) -> None: + _expand_nonmarc( + ObjectNode(root_name, "", None, root_values), + 0, + ctx, + ) + + +def _expand_nonmarc( + root: ObjectNode, + count: int, + ctx: ExpandContext, +) -> int: + initial_count = count + ctx.preprocess(ctx.conn, ctx.source_table, [root.identifier]) + root.unnest( + ctx.conn, + ctx.source_table, + ctx.get_transform_table(count), + ctx.source_cte(False), + ) + + expand_children_of = deque([root]) + while expand_children_of: + on = expand_children_of.popleft() + for c in on.object_children: + if len(c.parents) >= ctx.json_depth: + if c.parent is not None: + c.parent.values.append(c.name) + continue + ctx.preprocess(ctx.conn, ctx.get_transform_table(count), [c.identifier]) + c.unnest( + ctx.conn, + ctx.get_transform_table(count), + ctx.get_transform_table(count + 1), + ctx.source_cte(False), + ) + expand_children_of.append(c) + count += 1 + + new_source_table = ctx.get_transform_table(count) + arrays = root.descendents_oftype(ArrayNode) + ctx.preprocess(ctx.conn, new_source_table, [a.identifier for a in arrays]) + for an in arrays: + if len(an.parents) >= ctx.json_depth: + continue + values = an.explode( + ctx.conn, + new_source_table, + ctx.get_transform_table(count + 1), + ctx.source_cte(True), + ) + count += 1 + + if an.meta.is_object: + count += _expand_nonmarc( + ObjectNode( + an.name, + an.name, + None, + values, + ), + count + 1, + ctx.array_context( + ctx.get_transform_table(count), + ctx.json_depth - len(an.parents), + ), + ) + else: + with ctx.conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +CREATE TABLE {dest_table} AS +""" + + ctx.source_cte(False) + + """ +SELECT {cols} FROM ld_source +""", + ) + .format( + dest_table=ctx.get_output_table(an.name), + source_table=ctx.get_transform_table(count), + cols=sql.SQL("\n ,").join( + [sql.Identifier(v) for v in [*values, an.name]], + ), + ) + .as_string(), + ) + + stamped_values = [ + sql.Identifier(v) + for n in set(root.descendents).difference(arrays) + for v in n.values + ] + + with ctx.conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +CREATE TABLE {dest_table} AS +""" + + ctx.source_cte(False) + + """ +SELECT {cols} FROM ld_source +""", + ) + .format( + dest_table=ctx.get_output_table(root.path), + source_table=new_source_table, + cols=sql.SQL("\n ,").join(stamped_values), + ) + .as_string(), + ) + + return count + 1 - initial_count diff --git a/src/ldlite/database/_expansion/metadata.py b/src/ldlite/database/_expansion/metadata.py new file mode 100644 index 0000000..755cd78 --- /dev/null +++ b/src/ldlite/database/_expansion/metadata.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Literal + +from psycopg import sql + + +@dataclass +class Metadata: + prop: str + # array is technically a type + # but the metadata query returns inner type of the array + # the jtype_of function normalizes the names between pg and duckdb + json_type: Literal["string", "number", "object", "boolean"] + is_array: bool + is_uuid: bool + is_datetime: bool + is_float: bool + + def __post_init__(self) -> None: + # Mixed json_type columns (which shouldn't really happen) + # get STRING_AGG'ed with a pipe delimeter. + # Fallback to the lowest common denominator in this case. + if "|" in self.json_type: + object.__setattr__(self, "json_type", "string") + + @property + def is_object(self) -> bool: + return self.json_type == "object" + + @property + def snake(self) -> str: + return "".join("_" + c.lower() if c.isupper() else c for c in self.prop) + + def select_column( + self, + json_col: sql.Identifier, + alias: str, + ) -> sql.Composed: + if self.is_array or self.is_object: + stmt = sql.SQL( + "(ldlite_system.jextract({json_col}, {prop})) AS {alias}", + ) + elif self.json_type == "number": + stmt = sql.SQL( + "(ldlite_system.jextract_string({json_col}, {prop}))" + "::numeric AS {alias}", + ) + elif self.json_type == "string" and self.is_uuid: + stmt = sql.SQL( + "(ldlite_system.jextract_string({json_col}, {prop}))::uuid AS {alias}", + ) + else: + stmt = sql.SQL( + "(ldlite_system.jextract_string({json_col}, {prop})) AS {alias}", + ) + + return stmt.format( + json_col=json_col, + prop=self.prop, + alias=sql.Identifier(alias), + ) diff --git a/src/ldlite/database/_expansion/nodes.py b/src/ldlite/database/_expansion/nodes.py new file mode 100644 index 0000000..4b5ab5a --- /dev/null +++ b/src/ldlite/database/_expansion/nodes.py @@ -0,0 +1,309 @@ +from __future__ import annotations + +from collections import deque +from typing import TYPE_CHECKING, TypeVar + +from psycopg import sql + +if TYPE_CHECKING: + from collections.abc import Iterator + + import duckdb + import psycopg + +from .metadata import Metadata + +TNode = TypeVar("TNode", bound="ExpansionNode") + + +class ExpansionNode: + def __init__( + self, + name: str, + path: str, + parent: ExpansionNode | None, + values: list[str] | None = None, + ): + self.name = name + self.path = path + self.identifier = sql.Identifier(name) + self.parent = parent + self.values: list[str] = values or [] + self.children: list[ExpansionNode] = [] + + def add(self, meta: Metadata) -> str: + snake = meta.snake + prefixed_name = self.prefix + snake + + if meta.is_array: + self.children.append(ArrayNode(prefixed_name, snake, self, meta)) + elif meta.is_object: + self.children.append(ObjectNode(prefixed_name, snake, self)) + else: + prefixed_name = self.prefix + snake + self.values.append(prefixed_name) + + return prefixed_name + + def _parents(self) -> Iterator[ExpansionNode]: + n = self + while n.parent is not None: + yield n.parent + n = n.parent + + @property + def parents(self) -> list[ExpansionNode]: + return list(self._parents()) + + @property + def prefix(self) -> str: + if len(self.parents) == 0 and len(self.path) == 0: + return "" + + return ( + "__".join( + [*[p.path for p in self.parents if len(p.path) != 0], self.path], + ) + + "__" + ) + + @property + def root(self) -> ExpansionNode: + if self.parent is None: + return self + + root = [p for p in self.parents if p.parent is None] + return root[0] + + def _descendents(self, cls: type[TNode]) -> Iterator[TNode]: + to_visit = deque([self]) + while to_visit: + n = to_visit.pop() + if isinstance(n, cls): + yield n + + to_visit.extend(n.children) + + @property + def descendents(self) -> list[ExpansionNode]: + return list(self._descendents(ExpansionNode)) + + def descendents_oftype(self, cls: type[TNode]) -> list[TNode]: + return list(self._descendents(cls)) + + def __str__(self) -> str: + return "->".join([n.name for n in reversed([self, *self.parents])]) + + +class ObjectNode(ExpansionNode): + def __init__( + self, + name: str, + path: str, + parent: ExpansionNode | None, + values: list[str] | None = None, + ): + super().__init__(name, path, parent, values) + self.unnested = False + + def _object_children(self) -> Iterator[ObjectNode]: + for c in self.children: + if isinstance(c, ObjectNode): + yield c + + @property + def object_children(self) -> list[ObjectNode]: + return list(self._object_children()) + + def unnest( + self, + conn: duckdb.DuckDBPyConnection | psycopg.Connection, + source_table: sql.Identifier, + dest_table: sql.Identifier, + source_cte: str, + ) -> None: + self.unnested = True + create_columns: list[sql.Composable] = [ + sql.Identifier(v) for v in self.carryover + ] + + with conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +WITH + one_object AS ( + SELECT {json_col} AS json + FROM {table} + WHERE NOT ldlite_system.jis_null({json_col}) + LIMIT 1 + ), + props AS (SELECT ldlite_system.jobject_keys(json) AS prop FROM one_object), + values AS ( + SELECT + prop + ,ldlite_system.jextract({json_col}, prop) as value + FROM {table}, props + ), + value_and_types AS ( + SELECT + prop + ,ldlite_system.jtype_of(value) AS json_type + ,value + FROM values + WHERE NOT ldlite_system.jis_null(value) + ), + array_values AS ( + SELECT + v.prop + ,ldlite_system.jtype_of(a.value) AS json_type + ,v.value + FROM value_and_types v, ldlite_system.jexplode(v.value) a + WHERE v.json_type = 'array' + ), + all_values AS ( + SELECT + prop + ,json_type + ,value + ,FALSE AS is_array + FROM value_and_types + WHERE json_type <> 'array' + UNION + SELECT + prop + ,json_type + ,value + ,TRUE AS is_array + FROM array_values + WHERE NOT ldlite_system.jis_null(value) + ) +SELECT + prop + ,STRING_AGG(DISTINCT json_type, '|') AS json_type + ,bool_and(is_array) AS is_array + ,bool_and(ldlite_system.jis_uuid(value)) AS is_uuid + ,bool_and(ldlite_system.jis_datetime(value)) AS is_datetime + ,bool_and(ldlite_system.jis_float(value)) AS is_float +FROM all_values +GROUP BY prop +""", + ) + .format(table=source_table, json_col=self.identifier) + .as_string(), + ) + + create_columns.extend( + [ + row.select_column(self.identifier, self.add(row)) + for row in [Metadata(*r) for r in cur.fetchall()] + ], + ) + + with conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +CREATE TEMP TABLE {dest_table} ON COMMIT DROP AS +""" + + source_cte + + """ +SELECT + {cols} +FROM ld_source; +""", + ) + .format( + source_table=source_table, + dest_table=dest_table, + cols=sql.SQL("\n ,").join(create_columns), + ) + .as_string(), + ) + + def _carryover(self) -> Iterator[str]: + for n in self.root.descendents: + if isinstance(n, ObjectNode) and not n.unnested: + yield n.name + else: + yield n.name + yield from n.values + + @property + def carryover(self) -> list[str]: + return list(self._carryover()) + + +class ArrayNode(ExpansionNode): + def __init__( + self, + name: str, + path: str, + parent: ExpansionNode | None, + meta: Metadata, + values: list[str] | None = None, + ): + super().__init__(name, path, parent, values) + self.meta = Metadata( + "$", + meta.json_type, + False, + meta.is_uuid, + meta.is_datetime, + meta.is_float, + ) + + def explode( + self, + conn: duckdb.DuckDBPyConnection | psycopg.Connection, + source_table: sql.Identifier, + dest_table: sql.Identifier, + source_cte: str, + ) -> list[str]: + with conn.cursor() as cur: + o_col = self.name + "_o" + create_columns: list[sql.Composable] = [ + sql.SQL("ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS __id"), + *[sql.Identifier(v) for v in self.carryover], + sql.SQL("ROW_NUMBER() OVER (PARTITION BY s.__id) AS {id_alias}").format( + id_alias=sql.Identifier(o_col), + ), + self.meta.select_column( + sql.Identifier("a", "value"), + self.name, + ), + ] + + cur.execute( + sql.SQL( + """ +CREATE TEMP TABLE {dest_table} ON COMMIT DROP AS +""" + + source_cte + + """ +SELECT + {cols} +FROM + ld_source s + ,ldlite_system.jexplode({json_col}) a +WHERE NOT ldlite_system.jis_null({json_col}) +""", + ) + .format( + source_table=source_table, + dest_table=dest_table, + cols=sql.SQL("\n ,").join(create_columns), + json_col=sql.Identifier("s", self.name), + ) + .as_string(), + ) + + return ["__id", *self.carryover, o_col] + + def _carryover(self) -> Iterator[str]: + for n in reversed(self.parents): + yield from [v for v in n.values if v != "__id"] + + @property + def carryover(self) -> list[str]: + return list(self._carryover()) diff --git a/src/ldlite/_database/postgres.py b/src/ldlite/database/_postgres.py similarity index 54% rename from src/ldlite/_database/postgres.py rename to src/ldlite/database/_postgres.py index 2c29977..987810c 100644 --- a/src/ldlite/_database/postgres.py +++ b/src/ldlite/database/_postgres.py @@ -4,8 +4,8 @@ import psycopg from psycopg import sql -from . import Prefix -from .typed_database import TypedDatabase +from ._prefix import Prefix +from ._typed_database import TypedDatabase class PostgresDatabase(TypedDatabase[psycopg.Connection]): @@ -35,74 +35,117 @@ def _setup_jfuncs(conn: psycopg.Connection) -> None: cur.execute( r""" CREATE OR REPLACE FUNCTION ldlite_system.jtype_of(j JSONB) RETURNS TEXT AS $$ -BEGIN - RETURN jsonb_typeof(j); -END -$$ LANGUAGE plpgsql; +SELECT jsonb_typeof(j); +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; CREATE OR REPLACE FUNCTION ldlite_system.jextract(j JSONB, p TEXT) RETURNS JSONB AS $$ -BEGIN - RETURN CASE - WHEN ldlite_system.jtype_of(j->p) = 'string' THEN +WITH jp AS ( + -- This is somewhat of a hack. + -- There isn't a really good way to get the element unchanged + -- which works for duckdb and postgres AND CRUCIALLY + -- has a similar syntax to everything else so that we don't + -- have to have special cases for exploding the array and it + -- can share all the same type checking / statement generation code. + -- We're pretending that postgres supports -> '$' style syntax like duckdb. + SELECT + CASE + WHEN p = '$' THEN j #> '{}' + ELSE j->p + END AS val + ,CASE + WHEN p = '$' THEN j #>> '{}' + ELSE j->>p + END AS str +) +SELECT + CASE + WHEN ldlite_system.jtype_of(jp.val) = 'string' THEN CASE - WHEN lower(j->>p) = 'null' THEN 'null'::JSONB - WHEN length(j->>p) = 0 THEN 'null'::JSONB - ELSE j->p + WHEN lower(jp.str) = 'null' THEN 'null'::JSONB + WHEN length(jp.str) = 0 THEN 'null'::JSONB + ELSE jp.val END - WHEN ldlite_system.jtype_of(j->p) = 'array' THEN + WHEN ldlite_system.jtype_of(jp.val) = 'array' THEN CASE - WHEN jsonb_array_length(jsonb_path_query_array(j->p, '$[*] ? (@ != null)')) = 0 THEN 'null'::JSONB - ELSE jsonb_path_query_array(j->p, '$[*] ? (@ != null)') + WHEN jsonb_array_length(jsonb_path_query_array(jp.val, '$[*] ? (@ != null)')) = 0 THEN 'null'::JSONB + ELSE jsonb_path_query_array(jp.val, '$[*] ? (@ != null)') END - WHEN ldlite_system.jtype_of(j->p) = 'object' THEN + WHEN ldlite_system.jtype_of(jp.val) = 'object' THEN CASE - WHEN j->>p = '{}' THEN 'null'::JSONB - ELSE j->p + WHEN jp.str = '{}' THEN 'null'::JSONB + ELSE jp.val END - ELSE j->p - END; -END -$$ LANGUAGE plpgsql; + ELSE jp.val + END +FROM jp; +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; CREATE OR REPLACE FUNCTION ldlite_system.jextract_string(j JSONB, p TEXT) RETURNS TEXT AS $$ -BEGIN - RETURN ldlite_system.jextract(j, p) ->> 0; -END -$$ LANGUAGE plpgsql; +SELECT ldlite_system.jextract(j, p) #>> '{}' +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j JSONB) RETURNS SETOF TEXT AS $$ -BEGIN - RETURN QUERY SELECT jsonb_object_keys(j); -END -$$ LANGUAGE plpgsql; +SELECT jsonb_object_keys(j); +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; CREATE OR REPLACE FUNCTION ldlite_system.jis_uuid(j JSONB) RETURNS BOOLEAN AS $$ -BEGIN - RETURN CASE +SELECT + CASE WHEN ldlite_system.jtype_of(j) = 'string' THEN j->>0 ~ '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$' ELSE FALSE END; -END -$$ LANGUAGE plpgsql; +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; CREATE OR REPLACE FUNCTION ldlite_system.jis_datetime(j JSONB) RETURNS BOOLEAN AS $$ -BEGIN - RETURN CASE +SELECT + CASE WHEN ldlite_system.jtype_of(j) = 'string' THEN j->>0 ~ '^\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?$' ELSE FALSE END; -END -$$ LANGUAGE plpgsql; - +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j JSONB) RETURNS BOOLEAN AS $$ -BEGIN - RETURN CASE +SELECT + CASE WHEN ldlite_system.jtype_of(j) = 'number' THEN j->>0 LIKE '%.%' ELSE FALSE END; -END -$$ LANGUAGE plpgsql; +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j JSONB) RETURNS BOOLEAN AS $$ +SELECT j IS NULL OR j = 'null'::JSONB; +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j JSONB) RETURNS TABLE (value JSONB) AS $$ +SELECT * FROM jsonb_array_elements(j); +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; """, # noqa: E501 ) @@ -118,19 +161,20 @@ def _create_raw_table_sql(self) -> sql.SQL: def ingest_records( self, - prefix: Prefix, + prefix: str, records: Iterator[bytes], ) -> int: + pfx = Prefix(prefix) pkey = count(1) with self._conn_factory() as conn: - self._prepare_raw_table(conn, prefix) + self._prepare_raw_table(conn, pfx) with ( conn.cursor() as cur, cur.copy( sql.SQL( "COPY {table} (__id, jsonb) FROM STDIN (FORMAT BINARY)", - ).format(table=prefix.raw_table_identifier), + ).format(table=pfx.schemafy(pfx.raw_table)), ) as copy, ): # postgres jsonb is always version 1 @@ -144,3 +188,25 @@ def ingest_records( conn.commit() return next(pkey) - 1 + + def preprocess_source_table( + self, + conn: psycopg.Connection, + table_name: sql.Identifier, + column_names: list[sql.Identifier], + ) -> None: + if len(column_names) == 0: + return + + with conn.cursor() as cur: + cur.execute( + sql.SQL("ANALYZE {table_name} ({column_name})").format( + table_name=table_name, + column_name=sql.SQL(",").join(column_names), + ), + ) + + def source_table_cte_stmt(self, keep_source: bool) -> str: + if keep_source: + return "WITH ld_source AS (SELECT * FROM {source_table})" + return "WITH ld_source AS (DELETE FROM {source_table} RETURNING *)" diff --git a/src/ldlite/database/_prefix.py b/src/ldlite/database/_prefix.py new file mode 100644 index 0000000..d4ef74d --- /dev/null +++ b/src/ldlite/database/_prefix.py @@ -0,0 +1,64 @@ +from psycopg import sql + + +class Prefix: + def __init__(self, prefix: str): + self.schema: str | None = None + sandt = prefix.split(".") + if len(sandt) > 2: + msg = f"Expected one or two identifiers but got {prefix}" + raise ValueError(msg) + + if len(sandt) == 1: + (self._prefix,) = sandt + else: + (self.schema, self._prefix) = sandt + + def schemafy(self, table: str) -> sql.Identifier: + if self.schema is None: + return sql.Identifier(table) + return sql.Identifier(self.schema, table) + + @property + def raw_table(self) -> str: + return self._prefix + + @property + def _output_table(self) -> str: + return self._prefix + "__t" + + def output_table(self, prefix: str) -> sql.Identifier: + if len(prefix) == 0: + return self.schemafy(self._output_table) + + return self.schemafy(self._output_table + "__" + prefix) + + @property + def catalog_table(self) -> str: + return f"{self._prefix}__tcatalog" + + @property + def legacy_jtable(self) -> str: + return f"{self._prefix}_jtable" + + @property + def load_history_key(self) -> str: + if self.schema is None: + return self._prefix + + return self.schema + "." + self._prefix + + @property + def origin_table(self) -> sql.Identifier: + return sql.Identifier( + ("" if self.schema is None else self.schema + "_") + + self._output_table + + "_origin", + ) + + def transform_table(self, count: int) -> sql.Identifier: + return sql.Identifier( + ("" if self.schema is None else self.schema + "_") + + self._output_table + + f"_{count}", + ) diff --git a/src/ldlite/_database/typed_database.py b/src/ldlite/database/_typed_database.py similarity index 63% rename from src/ldlite/_database/typed_database.py rename to src/ldlite/database/_typed_database.py index 1927d4c..6ef07c7 100644 --- a/src/ldlite/_database/typed_database.py +++ b/src/ldlite/database/_typed_database.py @@ -1,3 +1,4 @@ +# pyright: reportArgumentType=false from abc import abstractmethod from collections.abc import Callable, Sequence from contextlib import closing @@ -7,7 +8,9 @@ import psycopg from psycopg import sql -from . import Database, LoadHistory, Prefix +from . import Database, LoadHistory +from ._expansion import ExpandContext, expand_nonmarc +from ._prefix import Prefix if TYPE_CHECKING: import duckdb @@ -48,23 +51,24 @@ def _default_schema(self) -> str: ... def drop_prefix( self, - prefix: Prefix, + prefix: str, ) -> None: + pfx = Prefix(prefix) with closing(self._conn_factory()) as conn: - self._drop_extracted_tables(conn, prefix) - self._drop_raw_table(conn, prefix) + self._drop_extracted_tables(conn, pfx) + self._drop_raw_table(conn, pfx) conn.execute( 'DELETE FROM "ldlite_system"."load_history" WHERE "table_name" = $1', - (prefix.load_history_key,), + (pfx.load_history_key,), ) conn.commit() def drop_raw_table( self, - prefix: Prefix, + prefix: str, ) -> None: with closing(self._conn_factory()) as conn: - self._drop_raw_table(conn, prefix) + self._drop_raw_table(conn, Prefix(prefix)) conn.commit() def _drop_raw_table( @@ -75,16 +79,16 @@ def _drop_raw_table( with closing(conn.cursor()) as cur: cur.execute( sql.SQL("DROP TABLE IF EXISTS {table};") - .format(table=prefix.raw_table_identifier) + .format(table=prefix.schemafy(prefix.raw_table)) .as_string(), ) def drop_extracted_tables( self, - prefix: Prefix, + prefix: str, ) -> None: with closing(self._conn_factory()) as conn: - self._drop_extracted_tables(conn, prefix) + self._drop_extracted_tables(conn, Prefix(prefix)) conn.commit() def _drop_extracted_tables( @@ -100,23 +104,23 @@ def _drop_extracted_tables( WHERE table_schema = $1 and table_name IN ($2, $3);""", ( prefix.schema or self._default_schema, - prefix.catalog_table_name, - prefix.legacy_jtable_name, + prefix.catalog_table, + prefix.legacy_jtable, ), ) for (tname,) in cur.fetchall(): - if tname == prefix.catalog_table_name: + if tname == prefix.catalog_table: cur.execute( sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.catalog_table_identifier) + .format(catalog=prefix.schemafy(prefix.catalog_table)) .as_string(), ) tables.extend(cur.fetchall()) - if tname == prefix.legacy_jtable_name: + if tname == prefix.legacy_jtable: cur.execute( sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.legacy_jtable_identifier) + .format(catalog=prefix.schemafy(prefix.legacy_jtable)) .as_string(), ) tables.extend(cur.fetchall()) @@ -130,12 +134,12 @@ def _drop_extracted_tables( ) cur.execute( sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.catalog_table_identifier) + .format(catalog=prefix.schemafy(prefix.catalog_table)) .as_string(), ) cur.execute( sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.legacy_jtable_identifier) + .format(catalog=prefix.schemafy(prefix.legacy_jtable)) .as_string(), ) @@ -148,20 +152,73 @@ def _prepare_raw_table( prefix: Prefix, ) -> None: with closing(conn.cursor()) as cur: - if prefix.schema_identifier is not None: + if prefix.schema is not None: cur.execute( sql.SQL("CREATE SCHEMA IF NOT EXISTS {schema};") - .format(schema=prefix.schema_identifier) + .format(schema=sql.Identifier(prefix.schema)) .as_string(), ) self._drop_raw_table(conn, prefix) with closing(conn.cursor()) as cur: cur.execute( self._create_raw_table_sql.format( - table=prefix.raw_table_identifier, + table=prefix.schemafy(prefix.raw_table), ).as_string(), ) + def preprocess_source_table( + self, + conn: DB, + table_name: sql.Identifier, + column_names: list[sql.Identifier], + ) -> None: ... + + # TODO: Refactor this to use DELETE RETURNING when DuckDb resolves + # https://github.com/duckdb/duckdb/issues/3417 + # Only postgres supports it which is why we have an abstraction here + @abstractmethod + def source_table_cte_stmt(self, keep_source: bool) -> str: ... + + def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> None: + pfx = Prefix(prefix) + with closing(self._conn_factory()) as conn: + with conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +CREATE TEMP TABLE {dest_table} ON COMMIT DROP AS +""" + + self.source_table_cte_stmt(keep_source=keep_raw) + + """ +SELECT * from ld_source; +""", + ) + .format( + dest_table=pfx.origin_table, + source_table=pfx.schemafy(pfx.raw_table), + ) + .as_string(), + ) + + if not keep_raw: + self._drop_raw_table(conn, pfx) + + expand_nonmarc( + "jsonb", + ["__id"], + ExpandContext( + conn, + pfx.origin_table, + json_depth, + pfx.transform_table, + pfx.output_table, + self.preprocess_source_table, # type: ignore [arg-type] + self.source_table_cte_stmt, + ), + ) + + conn.commit() + def record_history(self, history: LoadHistory) -> None: with closing(self._conn_factory()) as conn, conn.cursor() as cur: cur.execute( @@ -178,7 +235,7 @@ def record_history(self, history: LoadHistory) -> None: ,"index_time" = EXCLUDED."index_time" """, ( - history.table_name.load_history_key, + Prefix(history.table_name).load_history_key, history.path, history.query, history.total, diff --git a/tests/test_expansion.py b/tests/test_expansion.py new file mode 100644 index 0000000..33421ae --- /dev/null +++ b/tests/test_expansion.py @@ -0,0 +1,601 @@ +from collections.abc import Callable +from contextlib import closing +from dataclasses import dataclass +from typing import TYPE_CHECKING, cast +from uuid import uuid4 + +import duckdb +import psycopg +import pytest +from pytest_cases import parametrize, parametrize_with_cases + +if TYPE_CHECKING: + from _typeshed import dbapi + + +def _db() -> str: + db = "db" + str(uuid4()).split("-")[0] + print(db) # noqa: T201 + return db + + +@dataclass +class Assertion: + statement: str + + expect: int | str | list[tuple[str | int, ...]] | None = None + exp_pg: int | str | list[tuple[str | int, ...]] | None = None + exp_duck: int | str | list[tuple[str | int, ...]] | None = None + + def expected(self, db: str) -> int | str | list[tuple[str | int, ...]] | None: + if db == "postgres": + return self.exp_pg or self.expect + if db == "duckdb": + return self.exp_duck or self.expect + return self.expect + + +@dataclass +class ExpansionTC: + records: list[bytes] + assertions: list[Assertion] + json_depth: int = 999 + keep_raw: bool = True + + +def case_typed_columns() -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "id": "id1", + "numeric": 1, + "text": "value", + "uuid": "88888888-8888-1888-8888-888888888888" +} +""", + b""" +{ + "id": "id2", + "numeric": 2, + "text": "00000000-0000-1000-A000-000000000000", + "uuid": "11111111-1111-1111-8111-111111111111" +} +""", + ], + assertions=[ + Assertion( + f""" +SELECT DATA_TYPE +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME = 'prefix__t' AND COLUMN_NAME = '{a[0]}' +""", + exp_pg=a[0], + exp_duck=a[1], + ) + for a in [ + ("numeric", "DECIMAL(18,3)"), + ("text", "VARCHAR"), + ("uuid", "UUID"), + ] + ], + ) + + +@parametrize( + "assertion", + [ + ("all_null", None, None), + ("nullable_numeric", "numeric", "DECIMAL(18,3)"), + ("nullable_uuid", "uuid", "UUID"), + ("nullable_object__id", "numeric", "DECIMAL(18,3)"), + ("nullable_array", "numeric", "DECIMAL(18,3)"), + ("sortof_nullable_array__id", "numeric", "DECIMAL(18,3)"), + ], + idgen="prop={assertion[0]}", +) +def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "all_null": null, + "nullable_numeric": null, + "nullable_uuid": null, + "nullable_object": null, + "nullable_array": [], + "sortof_nullable_array": [{ "id": 5 }] +} +""", + b""" +{ + "all_null": null, + "nullable_numeric": 5, + "nullable_uuid": null, + "nullable_object": { "id": 5 }, + "nullable_array": null, + "sortof_nullable_array": [{}, {}] +} +""", + b""" +{ + "all_null": null, + "nullable_numeric": null, + "nullable_uuid": "0b03c888-102b-18e9-afb7-85e22229ca4d", + "nullable_object": { "id": null}, + "nullable_array": [null, 5, null], + "sortof_nullable_array": [{ "id": 5 }] +} +""", + ], + assertions=[ + Assertion( + f""" +SELECT DATA_TYPE +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME LIKE 'prefix__t%' AND COLUMN_NAME = '{assertion[0]}' +""", + exp_pg=assertion[1], + exp_duck=assertion[2], + ) + for _ in range(15) + ], + ) + + +@parametrize( + "prop", + [ + "some_uuid", + "some_numeric", + "some_object", + "some_array", + ], +) +def case_mixed_types(prop: str) -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "some_uuid": "0b03c888-102b-18e9-afb7-85e22229ca4d", + "some_numeric": 5, + "some_object": { "id": 5 }, + "some_array": [5] +} +""", + b""" +{ + "some_uuid": "not-uuid", + "some_numeric": "not-numeric", + "some_object": "not-object", + "some_array": "not-array" +} +""", + b""" +{ + "some_uuid": "0b03c888-102b-18e9-afb7-85e22229ca4d", + "some_numeric": 5, + "some_object": { "id": 5 }, + "some_array": [5] +} +""", + ], + assertions=[ + Assertion( + f""" +SELECT DATA_TYPE +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME = 'prefix__t' AND COLUMN_NAME = '{prop}' +""", + exp_pg="text", + exp_duck="VARCHAR", + ) + for _ in range(15) + ], + ) + + +def case_basic_array() -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "id": "id1", + "list1": ["a1", "b1", "c1"], + "list2": [1] +} +""", + b""" +{ + "id": "id2", + "list1": ["a2", "b2", "c2"], + "list2": [2] +} +""", + ], + assertions=[ + Assertion("""SELECT COUNT(*) FROM tests.prefix__t__list1""", expect=6), + Assertion("""SELECT COUNT(*) FROM tests.prefix__t__list2""", expect=2), + Assertion( + """ +SELECT id, list1_o, list1 +FROM tests.prefix__t__list1 +ORDER BY id, list1_o + """, + expect=[ + ("id1", 1, "a1"), + ("id1", 2, "b1"), + ("id1", 3, "c1"), + ("id2", 1, "a2"), + ("id2", 2, "b2"), + ("id2", 3, "c2"), + ], + ), + *[ + Assertion( + f""" +SELECT COLUMN_NAME, DATA_TYPE +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME = 'prefix__t__{a[0]}' +ORDER BY ORDINAL_POSITION +""", + exp_duck=[ + ("__id", "BIGINT"), + ("id", "VARCHAR"), + (f"{a[0]}_o", "BIGINT"), + (f"{a[0]}", a[1]), + ], + exp_pg=[ + ("__id", "bigint"), + ("id", "text"), + (f"{a[0]}_o", "bigint"), + (f"{a[0]}", a[2]), + ], + ) + for a in [ + ("list1", "VARCHAR", "text"), + ("list2", "DECIMAL(18,3)", "numeric"), + ] + ], + ], + ) + + +def case_nested_arrays() -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "id": "id1", + "sub": [{ "id": "sub1id1"}, { "id": "sub2id1" }] +} +""", + b""" +{ + "id": "id2", + "sub": [{ "id": "sub1id2" }, { "id": "sub2id2" }] +} +""", + ], + assertions=[ + Assertion("""SELECT COUNT(*) FROM tests.prefix__t__sub""", expect=4), + Assertion( + """ +SELECT id, sub_o, sub__id +FROM tests.prefix__t__sub +ORDER BY id, sub_o + """, + expect=[ + ("id1", 1, "sub1id1"), + ("id1", 2, "sub2id1"), + ("id2", 1, "sub1id2"), + ("id2", 2, "sub2id2"), + ], + ), + Assertion( + """ +SELECT COLUMN_NAME, DATA_TYPE +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME = 'prefix__t__sub' +ORDER BY ORDINAL_POSITION +""", + exp_duck=[ + ("__id", "BIGINT"), + ("id", "VARCHAR"), + ("sub_o", "BIGINT"), + ("sub__id", "VARCHAR"), + ], + exp_pg=[ + ("__id", "bigint"), + ("id", "text"), + ("sub_o", "bigint"), + ("sub__id", "text"), + ], + ), + ], + ) + + +def case_basic_object() -> ExpansionTC: + return ExpansionTC( + records=[ + b"""{"id": "id1", "camelValue": "value1"}""", + b"""{"id": "id2", "camelValue": "value2"}""", + ], + assertions=[ + Assertion("SELECT COUNT(*) FROM tests.prefix__t;", 2), + Assertion("SELECT id FROM tests.prefix__t WHERE __id = 1", "id1"), + Assertion( + "SELECT camel_value FROM tests.prefix__t WHERE __id = 1", + "value1", + ), + Assertion("SELECT id FROM tests.prefix__t WHERE __id = 2", "id2"), + Assertion( + "SELECT camel_value FROM tests.prefix__t WHERE __id = 2", + "value2", + ), + ], + ) + + +def case_nested_objects() -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "id": "id1", + "value": "value1", + "intEr": { + "mediate": {"id": "snake"} + }, + "sub": { + "id": "sub_id1", + "subSub": {"id": "subsub_id1"}, + "subSib": {"id": "subsib_id1"} + }, + "sib": { + "id": "sib_id1", + "sibSub": {"id": "sibsub_id1"}, + "sibSib": {"id": "sibsib_id1"} + } +} +""", + b""" +{ + "id": "id2", + "value": "value2", + "intEr": { + "mediate": {"id": "case"} + }, + "sub": { + "id": "sub_id2", + "subSub": {"id": "subsub_id2"}, + "subSib": {"id": "subsib_id2"} + }, + "sib": { + "id": "sib_id2", + "sibSub": {"id": "sibsub_id2"}, + "sibSib": {"id": "sibsib_id2"} + } +} +""", + ], + assertions=[ + Assertion("SELECT COUNT(*) FROM tests.prefix__t;", 2), + Assertion("SELECT id FROM tests.prefix__t WHERE __id = 1", "id1"), + Assertion("SELECT sub__id FROM tests.prefix__t WHERE __id = 1", "sub_id1"), + Assertion( + "SELECT int_er__mediate__id FROM tests.prefix__t WHERE __id = 1", + "snake", + ), + Assertion( + "SELECT sub__sub_sub__id FROM tests.prefix__t WHERE __id = 1", + "subsub_id1", + ), + Assertion( + "SELECT sub__sub_sib__id FROM tests.prefix__t WHERE __id = 1", + "subsib_id1", + ), + Assertion("SELECT id FROM tests.prefix__t WHERE __id = 2", "id2"), + Assertion("SELECT sib__id FROM tests.prefix__t WHERE __id = 2", "sib_id2"), + Assertion( + "SELECT int_er__mediate__id FROM tests.prefix__t WHERE __id = 2", + "case", + ), + Assertion( + "SELECT sib__sib_sub__id FROM tests.prefix__t WHERE __id = 2", + "sibsub_id2", + ), + Assertion( + "SELECT sib__sib_sib__id FROM tests.prefix__t WHERE __id = 2", + "sibsib_id2", + ), + ], + ) + + +def case_json_depth() -> ExpansionTC: + return ExpansionTC( + json_depth=3, + records=[ + b""" +{ + "id": "id1", + "depth2Obj": { + "id": "id2", + "depth3Obj": { + "id": "id3", + "depth4Obj": { + "id": "id4" + }, + "depth4Arr": ["id4"] + }, + "depth3Arr": ["id3"] + }, + "depth2Arr": [ + { + "id": "id2", + "depth3Arr": [ + { + "id": "id3", + "depth4Arr": ["id4"] + } + ], + "depth3Obj": { + "id": "id3", + "depth4Obj": { "id": "id4" }, + "depth4Arr": ["id4"] + } + } + ], + "depth2Obj2": { "id": "id2" }, + "depth2Obj3": { "id": "id2" }, + "depth2Obj4": { "id": "id2" } +}""", + ], + assertions=[ + Assertion("""SELECT "depth2_obj4__id" FROM tests.prefix__t""", "id2"), + Assertion( + """ +SELECT "depth2_obj__depth3_obj__id" +FROM tests.prefix__t +""", + "id3", + ), + Assertion( + """ +SELECT "depth2_obj__depth3_arr" +FROM tests.prefix__t__depth2_obj__depth3_arr +""", + "id3", + ), + Assertion( + """ +SELECT "depth2_arr__depth3_arr__id" +FROM tests.prefix__t__depth2_arr__depth3_arr +""", + "id3", + ), + Assertion( + """ +SELECT "depth2_arr__depth3_obj__id" +FROM tests.prefix__t__depth2_arr +""", + "id3", + ), + Assertion( + """ +SELECT COUNT(DISTINCT DATA_TYPE), ANY_VALUE(DATA_TYPE) +FROM INFORMATION_SCHEMA.COLUMNS +WHERE COLUMN_NAME IN ( + 'depth2_obj__depth3_obj__depth4_obj' + ,'depth2_obj__depth3_obj__depth4_arr' + ,'depth2_arr__depth3_arr__depth4_arr' + ,'depth2_arr__depth3_obj__depth4_arr' + ,'depth2_arr__depth3_obj__depth4_obj' +) +""", + exp_duck=[(1, "JSON")], + exp_pg=[(1, "jsonb")], + ), + ], + ) + + +def case_keep_raw() -> ExpansionTC: + return ExpansionTC( + keep_raw=True, + records=[ + b"""{ "id": "id1" }""", + b"""{ "id": "id2" }""", + ], + assertions=[ + Assertion( + """ +SELECT COUNT(*) +FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME = 'prefix' +""", + 1, + ), + ], + ) + + +def case_dont_keep_raw() -> ExpansionTC: + return ExpansionTC( + keep_raw=False, + records=[ + b"""{ "id": "id1" }""", + b"""{ "id": "id2" }""", + ], + assertions=[ + Assertion( + """ +SELECT COUNT(*) +FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME = 'prefix' +""", + 0, + ), + ], + ) + + +def _assert( + conn: "dbapi.DBAPIConnection", + db: str, + tc: ExpansionTC, +) -> None: + with closing(conn.cursor()) as cur: + for a in tc.assertions: + cur.execute(a.statement.format()) + + if isinstance(expected := a.expected(db), list): + for e in expected: + assert cur.fetchone() == e + assert cur.fetchone() is None + else: + actual = cur.fetchone() + if a.expected(db) is None: + assert actual is None + else: + assert actual is not None + assert actual[0] == a.expected(db) + + +@parametrize_with_cases("tc", cases=".") +def test_duckdb(tc: ExpansionTC) -> None: + from ldlite import LDLite + + dsn = f":memory:{_db()}" + + ld = LDLite() + ld.connect_db(dsn) + assert ld.database_experimental is not None + + ld.database_experimental.ingest_records("tests.prefix", iter(tc.records)) + ld.database_experimental.expand_prefix("tests.prefix", tc.json_depth, tc.keep_raw) + + with duckdb.connect(dsn) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "duckdb", tc) + + +@parametrize_with_cases("tc", cases=".") +def test_postgres(pg_dsn: None | Callable[[str], str], tc: ExpansionTC) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + from ldlite import LDLite + + dsn = pg_dsn(_db()) + + ld = LDLite() + ld.connect_db_postgresql(dsn) + assert ld.database_experimental is not None + + ld.database_experimental.ingest_records("tests.prefix", iter(tc.records)) + ld.database_experimental.expand_prefix("tests.prefix", tc.json_depth, tc.keep_raw) + + with psycopg.connect(dsn, cursor_factory=psycopg.RawCursor) as conn: + _assert(cast("dbapi.DBAPIConnection", conn), "postgres", tc) diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index 5eec23e..995964c 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -102,7 +102,7 @@ def case_jobject_keys() -> JsonTC: ("na", "null"), ], ) -def case_jtypeof(p: tuple[Any, ...]) -> JsonTC: +def case_jtype_of(p: tuple[Any, ...]) -> JsonTC: return JsonTC( """ SELECT ldlite_system.jtype_of(jc->$1){assertion} @@ -113,6 +113,31 @@ def case_jtypeof(p: tuple[Any, ...]) -> JsonTC: ) +@parametrize( + p=[ + ("arr_str", ['"s1"', '"s2"', '"s3"']), + ("arr_obj", ['{"k1":"v1"}', '{"k2":"v2"}']), + ("arr_num", [1, 2, 3]), + ], +) +def case_jexplode(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +{assertion} +( + SELECT a.value FROM j, ldlite_system.jexplode(j.jc->$1) a + EXCEPT SELECT value::{jtype} FROM unnest($2::text[]) AS expect(value) + UNION ALL + SELECT value::{jtype} FROM unnest($2::text[]) AS expect(value) + EXCEPT SELECT a.value FROM j, ldlite_system.jexplode(j.jc->$1) a +) +""", + p, + """SELECT COUNT(1) = 0 FROM""", + (), + ) + + @parametrize( p=[ ("str", False), @@ -136,6 +161,24 @@ def case_jis_uuid(p: tuple[Any, ...]) -> JsonTC: ) +@parametrize( + p=[ + ("na", True), + ("obj_empty", False), + ("arr_zero", False), + ("na_str1", False), + ("na_str2", False), + ], +) +def case_jis_null(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """SELECT ldlite_system.jis_null(jc->$1){assertion} FROM j;""", + p[:1], + """= $2""", + p[1:], + ) + + @parametrize( p=[ ("str", False), @@ -212,28 +255,30 @@ def _assert(conn: "dbapi.DBAPIConnection", jtype: str, tc: JsonTC) -> None: def _arrange(conn: "dbapi.DBAPIConnection") -> None: with closing(conn.cursor()) as cur: cur.execute( - "INSERT INTO j VALUES " - "('{" - """ "str": "str_val",""" - """ "str_empty": "",""" - """ "num": 12,""" - """ "float": 16.3,""" - """ "bool": true,""" - """ "uuid": "5b285d03-5490-1111-8888-52b2003b475c",""" - """ "uuid_nof": "5b285d03-5490-FFFF-0000-52b2003b475c",""" - """ "obj": {"k1": "v1", "k2": "v2"},""" - """ "obj_some": {"k1": "v1", "k2": null},""" - """ "obj_empty": {},""" - """ "arr_zero": [],""" - """ "arr_str": ["s1", "s2", "s3"],""" - """ "arr_str_some": ["s1", "s2", null],""" - """ "arr_obj": [{"k1": "v1"}, {"k2": "v2"}],""" - """ "arr_obj_some": [{"k1": "v1"}, null],""" - """ "dt": "2022-04-21T18:47:33.581+00:00",""" - """ "na": null,""" - """ "na_str1": "null", """ - """ "na_str2": "NULL" """ - " }')", + """ +INSERT INTO j VALUES ( +'{ + "str": "str_val", + "str_empty": "", + "num": 12, + "float": 16.3, + "bool": true, + "uuid": "5b285d03-5490-1111-8888-52b2003b475c", + "uuid_nof": "5b285d03-5490-FFFF-0000-52b2003b475c", + "obj": {"k1": "v1", "k2": "v2"}, + "obj_some": {"k1": "v1", "k2": null}, + "obj_empty": {}, + "arr_zero": [], + "arr_str": ["s1", "s2", "s3"], + "arr_str_some": ["s1", "s2", null], + "arr_obj": [{"k1": "v1"}, {"k2": "v2"}], + "arr_obj_some": [{"k1": "v1"}, null], + "arr_num": [1, 2, 3], + "dt": "2022-04-21T18:47:33.581+00:00", + "na": null, + "na_str1": "null", + "na_str2": "NULL" +}')""", ) diff --git a/tests/test_query.py b/tests/test_query.py index 5e686de..f75a369 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -24,6 +24,7 @@ class QueryTC(MockedResponseTestCase): expected_tables: list[str] expected_values: dict[str, tuple[list[str], list[tuple[Any, ...]]]] + unexpected_columns: list[tuple[str, str]] | None = None expected_indexes: list[tuple[str, str]] | None = None @@ -436,6 +437,110 @@ def case_nested_object_underexpansion() -> QueryTC: ) +def case_tables_and_lists() -> QueryTC: + return QueryTC( + Call( + "prefix", + json_depth=3, + returns={ + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "subObjects": [ + { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + }, + { + "id": "f5bda109-a719-4f72-b797-b9c22f45e4e1", + }, + ], + "excludedFromLists": { + "id": "b0f3e260-8eb7-4dd2-b9c6-be74e00229a8", + }, + "subObject": { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + "subSubObject": { + "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", + }, + "subObjects": [ + { + "id": "15f1d05d-6a54-4704-9d53-90718a8339b1", + }, + { + "id": "37de4f71-cc99-4e8c-90c6-5a17f168f21d", + }, + ], + }, + }, + ], + }, + ), + expected_tables=[ + "prefix", + "prefix__t", + "prefix__t__sub_objects", + "prefix__t__sub_object__sub_objects", + "prefix__tcatalog", + ], + expected_values={ + "prefix__t": ( + ["id", "sub_object__id", "sub_object__sub_sub_object__id"], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + ), + ], + ), + "prefix__t__sub_objects": ( + ["id", "sub_objects__id"], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + ), + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "f5bda109-a719-4f72-b797-b9c22f45e4e1", + ), + ], + ), + "prefix__t__sub_object__sub_objects": ( + [ + "id", + "sub_object__id", + "sub_object__sub_objects__id", + ], + [ + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "15f1d05d-6a54-4704-9d53-90718a8339b1", + ), + ( + "b096504a-3d54-4664-9bf5-1b872466fd66", + "2b94c631-fca9-4892-a730-03ee529ffe2a", + "37de4f71-cc99-4e8c-90c6-5a17f168f21d", + ), + ], + ), + "prefix__tcatalog": ( + ["table_name"], + [ + ("prefix__t",), + ("prefix__t__sub_object__sub_objects",), + ("prefix__t__sub_objects",), + ], + ), + }, + unexpected_columns=[ + ("prefix__t__sub_objects", "sub_object__id"), + ("prefix__t__sub_object__sub_objects", "excluded_from_lists__id"), + ], + ) + + def case_id_generation() -> QueryTC: return QueryTC( Call( @@ -692,6 +797,18 @@ def _assert( assert cur.fetchone() is None + if tc.unexpected_columns is not None: + for exp in tc.unexpected_columns: + cur.execute( + """ + SELECT COUNT(*) + FROM information_schema.columns + WHERE table_name=$1 and column_name=$2 + """, + exp, + ) + assert cur.fetchone() == (0,) + @mock.patch("httpx_folio.auth.httpx.post") @mock.patch("httpx_folio.factories.httpx.Client.get") From 156e165ee89168aebe906c1b9e1580964d63643d Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Thu, 26 Feb 2026 11:02:07 -0500 Subject: [PATCH 14/25] Upgrade duckdb and raise maximum tested python version (#65) The last PR caught that the changes for the server side transform aren't compatible with older versions of duckdb. It was already getting unwieldy and so I chose to make the necessary changes in another PR. This raises the minimum supported version of DuckDB and also starts testing against python 3.14. There has been an ongoing cache contention issue resulting in long build times that is also resolved here. --- .github/workflows/lint.yaml | 4 +- .github/workflows/test.yaml | 2 +- environment.yaml | 4 +- pylock.lint.toml | 827 +++++++++++++++++++++++++++++++++ pylock.maximal.toml | 179 +++---- pylock.minimal.toml | 82 ++-- pylock.toml | 106 +++-- pyproject.toml | 11 +- src/ldlite/_csv.py | 1 + src/ldlite/database/_duckdb.py | 11 +- tests/test_expansion.py | 52 ++- tests/test_json_operators.py | 54 ++- 12 files changed, 1097 insertions(+), 236 deletions(-) create mode 100644 pylock.lint.toml diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 88c0bbb..1bea948 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -21,8 +21,8 @@ jobs: - uses: pdm-project/setup-pdm@v4 with: cache: true - cache-dependency-path: pylock.toml - - run: pdm install -G:all --lockfile pylock.toml + cache-dependency-path: pylock.lint.toml + - run: pdm install -G:all --lockfile pylock.lint.toml - uses: jaxxstorm/action-install-gh-release@v1.10.0 with: repo: houseabsolute/precious diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a49e391..3570639 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -51,7 +51,7 @@ jobs: # install dependencies - uses: pdm-project/setup-pdm@v4 with: - python-version: 3.13 + python-version: 3.14 cache: true cache-dependency-path: pylock.maximal.toml - run: pdm install -G:all --lockfile pylock.maximal.toml diff --git a/environment.yaml b/environment.yaml index 31a8402..22c24ca 100644 --- a/environment.yaml +++ b/environment.yaml @@ -5,6 +5,6 @@ channels: - nodefaults dependencies: - python>=3.10,<3.11 - - pdm==2.25.5 - - precious==0.10.0 + - pdm==2.26.6 + - precious==0.10.2 - libpq>=13.0 diff --git a/pylock.lint.toml b/pylock.lint.toml new file mode 100644 index 0000000..fb6f477 --- /dev/null +++ b/pylock.lint.toml @@ -0,0 +1,827 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. +lock-version = "1.0" +requires-python = ">=3.10" +environments = [ + "python_version >= \"3.10\"", +] +extras = [] +dependency-groups = ["default", "lint", "test", "types"] +default-groups = ["default"] +created-by = "pdm" + +[[packages]] +name = "mypy" +version = "1.18.2" +requires-python = ">=3.9" +sdist = {name = "mypy-1.18.2.tar.gz", url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hashes = {sha256 = "06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"}} +wheels = [ + {name = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"}}, + {name = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"}}, + {name = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}}, + {name = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}}, + {name = "mypy-1.18.2-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl",hashes = {sha256 = "749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}}, + {name = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}}, + {name = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}}, + {name = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}}, + {name = "mypy-1.18.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}}, + {name = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"}}, + {name = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"}}, + {name = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"}}, + {name = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"}}, + {name = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"}}, + {name = "mypy-1.18.2-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"}}, + {name = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"}}, + {name = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"}}, + {name = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"}}, + {name = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"}}, + {name = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"}}, + {name = "mypy-1.18.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"}}, + {name = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/03/6f/657961a0743cff32e6c0611b63ff1c1970a0b482ace35b069203bf705187/mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"}}, + {name = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/10/e9/420822d4f661f13ca8900f5fa239b40ee3be8b62b32f3357df9a3045a08b/mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"}}, + {name = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/aa/73/a05b2bbaa7005f4642fcfe40fb73f2b4fb6bb44229bd585b5878e9a87ef8/mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"}}, + {name = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4f/01/f6e4b9f0d031c11ccbd6f17da26564f3a0f3c4155af344006434b0a05a9d/mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"}}, + {name = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/97/19727e7499bfa1ae0773d06afd30ac66a58ed7437d940c70548634b24185/mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"}}, + {name = "mypy-1.18.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/4f/90dc8c15c1441bf31cf0f9918bb077e452618708199e530f4cbd5cede6ff/mypy-1.18.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"}}, + {name = "mypy-1.18.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl",hashes = {sha256 = "22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}}, +] +marker = "\"lint\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "typing-extensions>=4.6.0", + "mypy-extensions>=1.0.0", + "pathspec>=0.9.0", + "tomli>=1.1.0; python_version < \"3.11\"", +] + +[[packages]] +name = "pre-commit-hooks" +version = "6.0.0" +requires-python = ">=3.9" +sdist = {name = "pre_commit_hooks-6.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/36/4d/93e63e48f8fd16d6c1e4cef5dabadcade4d1325c7fd6f29f075a4d2284f3/pre_commit_hooks-6.0.0.tar.gz", hashes = {sha256 = "76d8370c006f5026cdd638a397a678d26dda735a3c88137e05885a020f824034"}} +wheels = [ + {name = "pre_commit_hooks-6.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/12/46/eba9be9daa403fa94854ce16a458c29df9a01c6c047931c3d8be6016cd9a/pre_commit_hooks-6.0.0-py2.py3-none-any.whl",hashes = {sha256 = "76161b76d321d2f8ee2a8e0b84c30ee8443e01376121fd1c90851e33e3bd7ee2"}}, +] +marker = "\"lint\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "ruamel-yaml>=0.15", + "tomli>=1.1.0; python_version < \"3.11\"", +] + +[[packages]] +name = "ruff" +version = "0.13.1" +requires-python = ">=3.7" +sdist = {name = "ruff-0.13.1.tar.gz", url = "https://files.pythonhosted.org/packages/ab/33/c8e89216845615d14d2d42ba2bee404e7206a8db782f33400754f3799f05/ruff-0.13.1.tar.gz", hashes = {sha256 = "88074c3849087f153d4bb22e92243ad4c1b366d7055f98726bc19aa08dc12d51"}} +wheels = [ + {name = "ruff-0.13.1-py3-none-linux_armv6l.whl",url = "https://files.pythonhosted.org/packages/f3/41/ca37e340938f45cfb8557a97a5c347e718ef34702546b174e5300dbb1f28/ruff-0.13.1-py3-none-linux_armv6l.whl",hashes = {sha256 = "b2abff595cc3cbfa55e509d89439b5a09a6ee3c252d92020bd2de240836cf45b"}}, + {name = "ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/84/ba378ef4129415066c3e1c80d84e539a0d52feb250685091f874804f28af/ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl",hashes = {sha256 = "4ee9f4249bf7f8bb3984c41bfaf6a658162cdb1b22e3103eabc7dd1dc5579334"}}, + {name = "ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8d/b6/ec5e4559ae0ad955515c176910d6d7c93edcbc0ed1a3195a41179c58431d/ruff-0.13.1-py3-none-macosx_11_0_arm64.whl",hashes = {sha256 = "5c5da4af5f6418c07d75e6f3224e08147441f5d1eac2e6ce10dcce5e616a3bae"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/d6/cb3e3b4f03b9b0c4d4d8f06126d34b3394f6b4d764912fe80a1300696ef6/ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "80524f84a01355a59a93cef98d804e2137639823bcee2931f5028e71134a954e"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/d2/ea/bf60cb46d7ade706a246cd3fb99e4cfe854efa3dfbe530d049c684da24ff/ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "ff7f5ce8d7988767dd46a148192a14d0f48d1baea733f055d9064875c7d50389"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/2d/3e/05f72f4c3d3a69e65d55a13e1dd1ade76c106d8546e7e54501d31f1dc54a/ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "c55d84715061f8b05469cdc9a446aa6c7294cd4bd55e86a89e572dba14374f8c"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",url = "https://files.pythonhosted.org/packages/81/e7/01b1fc403dd45d6cfe600725270ecc6a8f8a48a55bc6521ad820ed3ceaf8/ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",hashes = {sha256 = "ac57fed932d90fa1624c946dc67a0a3388d65a7edc7d2d8e4ca7bddaa789b3b0"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/fa/92/d9e183d4ed6185a8df2ce9faa3f22e80e95b5f88d9cc3d86a6d94331da3f/ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "c366a71d5b4f41f86a008694f7a0d75fe409ec298685ff72dc882f882d532e36"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/3b/4a/6ddb1b11d60888be224d721e01bdd2d81faaf1720592858ab8bac3600466/ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "f4ea9d1b5ad3e7a83ee8ebb1229c33e5fe771e833d6d3dcfca7b77d95b060d38"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/98/3f1d18a8d9ea33ef2ad508f0417fcb182c99b23258ec5e53d15db8289809/ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "b0f70202996055b555d3d74b626406476cc692f37b13bac8828acff058c9966a"}}, + {name = "ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/8d/86/b6ce62ce9c12765fa6c65078d1938d2490b2b1d9273d0de384952b43c490/ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl",hashes = {sha256 = "f8cff7a105dad631085d9505b491db33848007d6b487c3c1979dd8d9b2963783"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/6e/af7943466a41338d04503fb5a81b2fd07251bd272f546622e5b1599a7976/ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9761e84255443316a258dd7dfbd9bfb59c756e52237ed42494917b2577697c6a"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/3f/97/0249b9a24f0f3ebd12f007e81c87cec6d311de566885e9309fcbac5b24cc/ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl",hashes = {sha256 = "3d376a88c3102ef228b102211ef4a6d13df330cb0f5ca56fdac04ccec2a99700"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/f6/85/0b64693b2c99d62ae65236ef74508ba39c3febd01466ef7f354885e5050c/ruff-0.13.1-py3-none-musllinux_1_2_i686.whl",hashes = {sha256 = "cbefd60082b517a82c6ec8836989775ac05f8991715d228b3c1d86ccc7df7dae"}}, + {name = "ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/96/fc/342e9f28179915d28b3747b7654f932ca472afbf7090fc0c4011e802f494/ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl",hashes = {sha256 = "dd16b9a5a499fe73f3c2ef09a7885cb1d97058614d601809d37c422ed1525317"}}, + {name = "ruff-0.13.1-py3-none-win32.whl",url = "https://files.pythonhosted.org/packages/37/54/6177a0dc10bce6f43e392a2192e6018755473283d0cf43cc7e6afc182aea/ruff-0.13.1-py3-none-win32.whl",hashes = {sha256 = "55e9efa692d7cb18580279f1fbb525146adc401f40735edf0aaeabd93099f9a0"}}, + {name = "ruff-0.13.1-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/51/c6a3a33d9938007b8bdc8ca852ecc8d810a407fb513ab08e34af12dc7c24/ruff-0.13.1-py3-none-win_amd64.whl",hashes = {sha256 = "3a3fb595287ee556de947183489f636b9f76a72f0fa9c028bdcabf5bab2cc5e5"}}, + {name = "ruff-0.13.1-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/04/afc078a12cf68592345b1e2d6ecdff837d286bac023d7a22c54c7a698c5b/ruff-0.13.1-py3-none-win_arm64.whl",hashes = {sha256 = "c0bae9ffd92d54e03c2bf266f466da0a65e145f298ee5b5846ed435f6a00518a"}}, +] +marker = "\"lint\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "coverage" +version = "7.13.4" +requires-python = ">=3.10" +sdist = {name = "coverage-7.13.4.tar.gz", url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hashes = {sha256 = "e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}} +wheels = [ + {name = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}}, + {name = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}}, + {name = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}}, + {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}}, + {name = "coverage-7.13.4-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl",hashes = {sha256 = "8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}}, + {name = "coverage-7.13.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}}, + {name = "coverage-7.13.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}}, + {name = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}}, + {name = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}}, + {name = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}}, + {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}}, + {name = "coverage-7.13.4-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl",hashes = {sha256 = "c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}}, + {name = "coverage-7.13.4-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}}, + {name = "coverage-7.13.4-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}}, + {name = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}}, + {name = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}}, + {name = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}}, + {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}}, + {name = "coverage-7.13.4-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl",hashes = {sha256 = "f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}}, + {name = "coverage-7.13.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}}, + {name = "coverage-7.13.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}}, + {name = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}}, + {name = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}}, + {name = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}}, + {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}}, + {name = "coverage-7.13.4-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl",hashes = {sha256 = "2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}}, + {name = "coverage-7.13.4-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}}, + {name = "coverage-7.13.4-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}}, + {name = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"}}, + {name = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/a0/2ea570925524ef4e00bb6c82649f5682a77fac5ab910a65c9284de422600/coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/ac/45dc2e19a1939098d783c846e130b8f862fbb50d09e0af663988f2f21973/coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/2d/4d/26d236ff35abc3b5e63540d3386e4c3b192168c1d96da5cb2f43c640970f/coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"}}, + {name = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/ec/55/14a966c757d1348b2e19caf699415a2a4c4f7feaa4bbc6326a51f5c7dd1b/coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/33/50116647905837c66d28b2af1321b845d5f5d19be9655cb84d4a0ea806b4/coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c2/b4/8efb11a46e3665d92635a56e4f2d4529de6d33f2cb38afd47d779d15fc99/coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/51/24/8cd73dd399b812cc76bb0ac260e671c4163093441847ffe058ac9fda1e32/coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/03/94/0a4b12f1d0e029ce1ccc1c800944a9984cbe7d678e470bb6d3c6bc38a0da/coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"}}, + {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/44/6002fbf88f6698ca034360ce474c406be6d5a985b3fdb3401128031eef6b/coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"}}, + {name = "coverage-7.13.4-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/de/c6/a0279f7c00e786be75a749a5674e6fa267bcbd8209cd10c9a450c655dfa7/coverage-7.13.4-cp312-cp312-win32.whl",hashes = {sha256 = "01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"}}, + {name = "coverage-7.13.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/77/4e/c0a25a425fcf5557d9abd18419c95b63922e897bc86c1f327f155ef234a9/coverage-7.13.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"}}, + {name = "coverage-7.13.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/47/ac/92da44ad9a6f4e3a7debd178949d6f3769bedca33830ce9b1dcdab589a37/coverage-7.13.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"}}, + {name = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"}}, + {name = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"}}, + {name = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"}}, + {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"}}, + {name = "coverage-7.13.4-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl",hashes = {sha256 = "784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"}}, + {name = "coverage-7.13.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"}}, + {name = "coverage-7.13.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"}}, + {name = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/d4/7827d9ffa34d5d4d752eec907022aa417120936282fc488306f5da08c292/coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"}}, + {name = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/b0/d69df26607c64043292644dbb9dc54b0856fabaa2cbb1eeee3331cc9e280/coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/82/a4/c1523f7c9e47b2271dbf8c2a097e7a1f89ef0d66f5840bb59b7e8814157b/coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/02/aa7ec01d1a5023c4b680ab7257f9bfde9defe8fdddfe40be096ac19e8177/coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/35/98/85aba0aed5126d896162087ef3f0e789a225697245256fc6181b95f47207/coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/96/72/1db59bd67494bc162e3e4cd5fbc7edba2c7026b22f7c8ef1496d58c2b94c/coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"}}, + {name = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/9d/97/72899c59c7066961de6e3daa142d459d47d104956db43e057e034f015c8a/coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/39/1f/f1885573b5970235e908da4389176936c8933e86cb316b9620aab1585fa2/coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a8/cf/e80390c5b7480b722fa3e994f8202807799b85bc562aa4f1dde209fbb7be/coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/bf/f89a8350d85572f95412debb0fb9bb4795b1d5b5232bd652923c759e787b/coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/6e/612a02aece8178c818df273e8d1642190c4875402ca2ba74514394b27aba/coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"}}, + {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/cb/98/b5afc39af67c2fa6786b03c3a7091fc300947387ce8914b096db8a73d67a/coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"}}, + {name = "coverage-7.13.4-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/51/30/2bba8ef0682d5bd210c38fe497e12a06c9f8d663f7025e9f5c2c31ce847d/coverage-7.13.4-cp310-cp310-win32.whl",hashes = {sha256 = "a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"}}, + {name = "coverage-7.13.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/78/13/331f94934cf6c092b8ea59ff868eb587bc8fe0893f02c55bc6c0183a192e/coverage-7.13.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"}}, + {name = "coverage-7.13.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl",hashes = {sha256 = "1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "duckdb" +version = "1.4.4" +requires-python = ">=3.9.0" +sdist = {name = "duckdb-1.4.4.tar.gz", url = "https://files.pythonhosted.org/packages/36/9d/ab66a06e416d71b7bdcb9904cdf8d4db3379ef632bb8e9495646702d9718/duckdb-1.4.4.tar.gz", hashes = {sha256 = "8bba52fd2acb67668a4615ee17ee51814124223de836d9e2fdcbc4c9021b3d3c"}} +wheels = [ + {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/97/a6/f19e2864e651b0bd8e4db2b0c455e7e0d71e0d4cd2cd9cc052f518e43eb3/duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "25874f8b1355e96178079e37312c3ba6d61a2354f51319dae860cf21335c3a20"}}, + {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/0e/93/8a24e932c67414fd2c45bed83218e62b73348996bf859eda020c224774b2/duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "452c5b5d6c349dc5d1154eb2062ee547296fcbd0c20e9df1ed00b5e1809089da"}}, + {name = "duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/62/13/e5378ff5bb1d4397655d840b34b642b1b23cdd82ae19599e62dc4b9461c9/duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8e5c2d8a0452df55e092959c0bfc8ab8897ac3ea0f754cb3b0ab3e165cd79aff"}}, + {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2d/94/24364da564b27aeebe44481f15bd0197a0b535ec93f188a6b1b98c22f082/duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1af6e76fe8bd24875dc56dd8e38300d64dc708cd2e772f67b9fbc635cc3066a3"}}, + {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/0a/6ae31b2914b4dc34243279b2301554bcbc5f1a09ccc82600486c49ab71d1/duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d0440f59e0cd9936a9ebfcf7a13312eda480c79214ffed3878d75947fc3b7d6d"}}, + {name = "duckdb-1.4.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d2/b1/fd5c37c53d45efe979f67e9bd49aaceef640147bb18f0699a19edd1874d6/duckdb-1.4.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "59c8d76016dde854beab844935b1ec31de358d4053e792988108e995b18c08e7"}}, + {name = "duckdb-1.4.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/2d/13e6024e613679d8a489dd922f199ef4b1d08a456a58eadd96dc2f05171f/duckdb-1.4.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "53cd6423136ab44383ec9955aefe7599b3fb3dd1fe006161e6396d8167e0e0d4"}}, + {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/7f/fe/64810fee20030f2bf96ce28b527060564864ce5b934b50888eda2cbf99dd/duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "337f8b24e89bc2e12dadcfe87b4eb1c00fd920f68ab07bc9b70960d6523b8bc3"}}, + {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9c/9b/3c7c5e48456b69365d952ac201666053de2700f5b0144a699a4dc6854507/duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "0509b39ea7af8cff0198a99d206dca753c62844adab54e545984c2e2c1381616"}}, + {name = "duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a6/7b/64e68a7b857ed0340045501535a0da99ea5d9d5ea3708fec0afb8663eb27/duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "fb94de6d023de9d79b7edc1ae07ee1d0b4f5fa8a9dcec799650b5befdf7aafec"}}, + {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/09/5b/3e7aa490841784d223de61beb2ae64e82331501bf5a415dc87a0e27b4663/duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0d636ceda422e7babd5e2f7275f6a0d1a3405e6a01873f00d38b72118d30c10b"}}, + {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/53/32/256df3dbaa198c58539ad94f9a41e98c2c8ff23f126b8f5f52c7dcd0a738/duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "7df7351328ffb812a4a289732f500d621e7de9942a3a2c9b6d4afcf4c0e72526"}}, + {name = "duckdb-1.4.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a4/f0/620323fd87062ea43e527a2d5ed9e55b525e0847c17d3b307094ddab98a2/duckdb-1.4.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "6fb1225a9ea5877421481d59a6c556a9532c32c16c7ae6ca8d127e2b878c9389"}}, + {name = "duckdb-1.4.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/07/a397fdb7c95388ba9c055b9a3d38dfee92093f4427bc6946cf9543b1d216/duckdb-1.4.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "f28a18cc790217e5b347bb91b2cab27aafc557c58d3d8382e04b4fe55d0c3f66"}}, + {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/58/33/beadaa69f8458afe466126f2c5ee48c4759cc9d5d784f8703d44e0b52c3c/duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "ddcfd9c6ff234da603a1edd5fd8ae6107f4d042f74951b65f91bc5e2643856b3"}}, + {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/66/82413f386df10467affc87f65bac095b7c88dbd9c767584164d5f4dc4cb8/duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "6792ca647216bd5c4ff16396e4591cfa9b4a72e5ad7cdd312cec6d67e8431a7c"}}, + {name = "duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/8c/c13d396fd4e9bf970916dc5b4fea410c1b10fe531069aea65f1dcf849a71/duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "1f8d55843cc940e36261689054f7dfb6ce35b1f5b0953b0d355b6adb654b0d52"}}, + {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/77/2446a0b44226bb95217748d911c7ca66a66ca10f6481d5178d9370819631/duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c65d15c440c31e06baaebfd2c06d71ce877e132779d309f1edf0a85d23c07e92"}}, + {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/2e/a3/97715bba30040572fb15d02c26f36be988d48bc00501e7ac02b1d65ef9d0/duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "b297eff642503fd435a9de5a9cb7db4eccb6f61d61a55b30d2636023f149855f"}}, + {name = "duckdb-1.4.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/0a/18b9167adf528cbe3867ef8a84a5f19f37bedccb606a8a9e59cfea1880c8/duckdb-1.4.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d525de5f282b03aa8be6db86b1abffdceae5f1055113a03d5b50cd2fb8cf2ef8"}}, + {name = "duckdb-1.4.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f8/15/37af97f5717818f3d82d57414299c293b321ac83e048c0a90bb8b6a09072/duckdb-1.4.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "50f2eb173c573811b44aba51176da7a4e5c487113982be6a6a1c37337ec5fa57"}}, + {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/04/68/19233412033a2bc5a144a3f531f64e3548d4487251e3f16b56c31411a06f/duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5ba684f498d4e924c7e8f30dd157da8da34c8479746c5011b6c0e037e9c60ad2"}}, + {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b3/3e/cec70e546c298ab76d80b990109e111068d82cca67942c42328eaa7d6fdb/duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "5536eb952a8aa6ae56469362e344d4e6403cc945a80bc8c5c2ebdd85d85eb64b"}}, + {name = "duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/f0/cf4241a040ec4f571859a738007ec773b642fbc27df4cbcf34b0c32ea559/duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "47dd4162da6a2be59a0aef640eb08d6360df1cf83c317dcc127836daaf3b7f7c"}}, + {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/11/64/de2bb4ec1e35ec9ebf6090a95b930fc56934a0ad6f34a24c5972a14a77ef/duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6cb357cfa3403910e79e2eb46c8e445bb1ee2fd62e9e9588c6b999df4256abc1"}}, + {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/a2/ac0f5ee16df890d141304bcd48733516b7202c0de34cd3555634d6eb4551/duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4c25d5b0febda02b7944e94fdae95aecf952797afc8cb920f677b46a7c251955"}}, + {name = "duckdb-1.4.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/37/a2/9a3402edeedaecf72de05fe9ff7f0303d701b8dfc136aea4a4be1a5f7eee/duckdb-1.4.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6703dd1bb650025b3771552333d305d62ddd7ff182de121483d4e042ea6e2e00"}}, + {name = "duckdb-1.4.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f6/e6/052ea6dcdf35b259fd182eff3efd8d75a071de4010c9807556098df137b9/duckdb-1.4.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bf138201f56e5d6fc276a25138341b3523e2f84733613fc43f02c54465619a95"}}, + {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/a2/9f/67a75f1e88f84946909826fa7aadd0c4b0dc067f24956142751fd9d59fe6/duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "e870a441cb1c41d556205deb665749f26347ed13b3a247b53714f5d589596977"}}, + {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/6b/7a/e9277d0567884c21f345ad43cc01aeaa2abe566d5fdf22e35c3861dd44fa/duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "49123b579e4a6323e65139210cd72dddc593a72d840211556b60f9703bda8526"}}, + {name = "duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/96/3a7630d2779d2bae6f3cdf540a088ed45166adefd3c429971e5b85ce8f84/duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "5e1933fac5293fea5926b0ee75a55b8cfe7f516d867310a5b251831ab61fe62b"}}, + {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/ad/f62a3a65d200e8afc1f75cf0dd3f0aa84ef0dd07c484414a11f2abed810e/duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "707530f6637e91dc4b8125260595299ec9dd157c09f5d16c4186c5988bfbd09a"}}, + {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/5f/23bd586ecb21273b41b5aa4b16fd88b7fecb53ed48d897273651c0c3d66f/duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "453b115f4777467f35103d8081770ac2f223fb5799178db5b06186e3ab51d1f2"}}, + {name = "duckdb-1.4.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/d0/4ce78bf341c930d4a22a56cb686bfc2c975eaf25f653a7ac25e3929d98bb/duckdb-1.4.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "a3c8542db7ffb128aceb7f3b35502ebaddcd4f73f1227569306cc34bad06680c"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "httpx-folio" +version = "0.3.0" +requires-python = ">=3.9" +sdist = {name = "httpx_folio-0.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/87/23/dd3f9ade71ace5a4b0343388792aa1bf8892f95ddf7217d82c0182f14c59/httpx_folio-0.3.0.tar.gz", hashes = {sha256 = "436778fb1bffb3327393bd5b809e7f38a2fd9fdfc8fea71a0a47fe2e0dbae2f2"}} +wheels = [ + {name = "httpx_folio-0.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5a/91/2ab3ee8588e5eab7808be5c3b1ea8fb3515f07686cddf49cbcde40885b3d/httpx_folio-0.3.0-py3-none-any.whl",hashes = {sha256 = "5396438eb07257db7c080382f65711b01b93eab3b2adc420a5855be3007c37ae"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "httpx>=0.20.0", + "httpx-retries>=0.4.1", +] + +[[packages]] +name = "orjson" +version = "3.11.7" +requires-python = ">=3.10" +sdist = {name = "orjson-3.11.7.tar.gz", url = "https://files.pythonhosted.org/packages/53/45/b268004f745ede84e5798b48ee12b05129d19235d0e15267aa57dcdb400b/orjson-3.11.7.tar.gz", hashes = {sha256 = "9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49"}} +wheels = [ + {name = "orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/e9/1e/745565dca749813db9a093c5ebc4bac1a9475c64d54b95654336ac3ed961/orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0"}}, + {name = "orjson-3.11.7-cp314-cp314-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/46/19/e40f6225da4d3aa0c8dc6e5219c5e87c2063a560fe0d72a88deb59776794/orjson-3.11.7-cp314-cp314-macosx_15_0_arm64.whl",hashes = {sha256 = "c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/9d/7e/c4de2babef2c0817fd1f048fd176aa48c37bec8aef53d2fa932983032cce/orjson-3.11.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/eb/74/233d360632bafd2197f217eee7fb9c9d0229eac0c18128aee5b35b0014fe/orjson-3.11.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/79/51/af79504981dd31efe20a9e360eb49c15f06df2b40e7f25a0a52d9ae888e8/orjson-3.11.7-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/67/e2/da898eb68b72304f8de05ca6715870d09d603ee98d30a27e8a9629abc64b/orjson-3.11.7-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/c5/89/15364d92acb3d903b029e28d834edb8780c2b97404cbf7929aa6b9abdb24/orjson-3.11.7-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e"}}, + {name = "orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c2/8b/ecdad52d0b38d4b8f514be603e69ccd5eacf4e7241f972e37e79792212ec/orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b9/0e/45e1dcf10e17d0924b7c9162f87ec7b4ca79e28a0548acf6a71788d3e108/orjson-3.11.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/63/d7/4d2e8b03561257af0450f2845b91fbd111d7e526ccdf737267108075e0ba/orjson-3.11.7-cp314-cp314-musllinux_1_2_armv7l.whl",hashes = {sha256 = "23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/78/cf/d45343518282108b29c12a65892445fc51f9319dc3c552ceb51bb5905ed2/orjson-3.11.7-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141"}}, + {name = "orjson-3.11.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a9/3a/d6001f51a7275aacd342e77b735c71fa04125a3f93c36fee4526bc8c654e/orjson-3.11.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2"}}, + {name = "orjson-3.11.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/1d/d3/f19b47ce16820cc2c480f7f1723e17f6d411b3a295c60c8ad3aa9ff1c96a/orjson-3.11.7-cp314-cp314-win32.whl",hashes = {sha256 = "89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576"}}, + {name = "orjson-3.11.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/12/df/172771902943af54bf661a8d102bdf2e7f932127968080632bda6054b62c/orjson-3.11.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1"}}, + {name = "orjson-3.11.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/6f/1c/f2a8d8a1b17514660a614ce5f7aac74b934e69f5abc2700cc7ced882a009/orjson-3.11.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d"}}, + {name = "orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/89/25/6e0e52cac5aab51d7b6dcd257e855e1dec1c2060f6b28566c509b4665f62/orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733"}}, + {name = "orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/29/a77f48d2fc8a05bbc529e5ff481fb43d914f9e383ea2469d4f3d51df3d00/orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/25/0a16e0729a0e6a1504f9d1a13cdd365f030068aab64cec6958396b9969d7/orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/66/da/a2e505469d60666a05ab373f1a6322eb671cb2ba3a0ccfc7d4bc97196787/orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/23/bf/ed73f88396ea35c71b38961734ea4a4746f7ca0768bf28fd551d37e48dd0/orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/73/3c/b05d80716f0225fc9008fbf8ab22841dcc268a626aa550561743714ce3bf/orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/61/e8/0be9b0addd9bf86abfc938e97441dcd0375d494594b1c8ad10fe57479617/orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705"}}, + {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c9/ec/c68e3b9021a31d9ec15a94931db1410136af862955854ed5dd7e7e4f5bff/orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d2/45/f3466739aaafa570cc8e77c6dbb853c48bf56e3b43738020e2661e08b0ac/orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/e1/84/9f7f02288da1ffb31405c1be07657afd1eecbcb4b64ee2817b6fe0f785fa/orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",hashes = {sha256 = "ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/18/07/9dd2f0c0104f1a0295ffbe912bc8d63307a539b900dd9e2c48ef7810d971/orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3"}}, + {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/66/857a8e4a3292e1f7b1b202883bcdeb43a91566cf59a93f97c53b44bd6801/orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223"}}, + {name = "orjson-3.11.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/0a/5b/6ebcf3defc1aab3a338ca777214966851e92efb1f30dc7fc8285216e6d1b/orjson-3.11.7-cp313-cp313-win32.whl",hashes = {sha256 = "7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3"}}, + {name = "orjson-3.11.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/00/04/c6f72daca5092e3117840a1b1e88dfc809cc1470cf0734890d0366b684a1/orjson-3.11.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757"}}, + {name = "orjson-3.11.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/03/ba/077a0f6f1085d6b806937246860fafbd5b17f3919c70ee3f3d8d9c713f38/orjson-3.11.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539"}}, + {name = "orjson-3.11.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/80/bf/76f4f1665f6983385938f0e2a5d7efa12a58171b8456c252f3bae8a4cf75/orjson-3.11.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f"}}, + {name = "orjson-3.11.7-cp312-cp312-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/79/53/6c72c002cb13b5a978a068add59b25a8bdf2800ac1c9c8ecdb26d6d97064/orjson-3.11.7-cp312-cp312-macosx_15_0_arm64.whl",hashes = {sha256 = "89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/83/10e48852865e5dd151bdfe652c06f7da484578ed02c5fca938e3632cb0b8/orjson-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/6e/52/a66e22a2b9abaa374b4a081d410edab6d1e30024707b87eab7c734afe28d/orjson-3.11.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/de/38/605d371417021359f4910c496f764c48ceb8997605f8c25bf1dfe58c0ebe/orjson-3.11.7-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/98/af32e842b0ffd2335c89714d48ca4e3917b42f5d6ee5537832e069a4b3ac/orjson-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/96/0b/fc793858dfa54be6feee940c1463370ece34b3c39c1ca0aa3845f5ba9892/orjson-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f"}}, + {name = "orjson-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/dc/91/98a52415059db3f374757d0b7f0f16e3b5cd5976c90d1c2b56acaea039e6/orjson-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/dc/b6/cb540117bda61791f46381f8c26c8f93e802892830a6055748d3bb1925ab/orjson-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/63/1a/50a3201c334a7f17c231eee5f841342190723794e3b06293f26e7cf87d31/orjson-3.11.7-cp312-cp312-musllinux_1_2_armv7l.whl",hashes = {sha256 = "b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/87/cd/8de1c67d0be44fdc22701e5989c0d015a2adf391498ad42c4dc589cd3013/orjson-3.11.7-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab"}}, + {name = "orjson-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/fe/d605d700c35dd55f51710d159fc54516a280923cd1b7e47508982fbb387d/orjson-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2"}}, + {name = "orjson-3.11.7-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/e4/e4/15ecc67edb3ddb3e2f46ae04475f2d294e8b60c1825fbe28a428b93b3fbd/orjson-3.11.7-cp312-cp312-win32.whl",hashes = {sha256 = "f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f"}}, + {name = "orjson-3.11.7-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/34/70/2e0855361f76198a3965273048c8e50a9695d88cd75811a5b46444895845/orjson-3.11.7-cp312-cp312-win_amd64.whl",hashes = {sha256 = "bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74"}}, + {name = "orjson-3.11.7-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/68/40/c2051bd19fc467610fed469dc29e43ac65891571138f476834ca192bc290/orjson-3.11.7-cp312-cp312-win_arm64.whl",hashes = {sha256 = "26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5"}}, + {name = "orjson-3.11.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/37/02/da6cb01fc6087048d7f61522c327edf4250f1683a58a839fdcc435746dd5/orjson-3.11.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c"}}, + {name = "orjson-3.11.7-cp311-cp311-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c1/c2/5885e7a5881dba9a9af51bc564e8967225a642b3e03d089289a35054e749/orjson-3.11.7-cp311-cp311-macosx_15_0_arm64.whl",hashes = {sha256 = "79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/1d/4e7688de0a92d1caf600dfd5fb70b4c5bfff51dfa61ac555072ef2d0d32a/orjson-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/2f/b2/ec04b74ae03a125db7bd69cffd014b227b7f341e3261bf75b5eb88a1aa92/orjson-3.11.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/4c/69/f95bdf960605f08f827f6e3291fe243d8aa9c5c9ff017a8d7232209184c3/orjson-3.11.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a4/1b/de59c57bae1d148ef298852abd31909ac3089cff370dfd4cd84cc99cbc42/orjson-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/ee/9e/9decc59f4499f695f65c650f6cfa6cd4c37a3fbe8fa235a0a3614cb54386/orjson-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b"}}, + {name = "orjson-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/28/e6/59f932bcabd1eac44e334fe8e3281a92eacfcb450586e1f4bde0423728d8/orjson-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f1/36/b0f05c0eaa7ca30bc965e37e6a2956b0d67adb87a9872942d3568da846ae/orjson-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/b8/03/58ec7d302b8d86944c60c7b4b82975d5161fcce4c9bc8c6cb1d6741b6115/orjson-3.11.7-cp311-cp311-musllinux_1_2_armv7l.whl",hashes = {sha256 = "7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/06/3a/868d65ef9a8b99be723bd510de491349618abd9f62c826cf206d962db295/orjson-3.11.7-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e"}}, + {name = "orjson-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5b/c7/1e18e1c83afe3349f4f6dc9e14910f0ae5f82eac756d1412ea4018938535/orjson-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561"}}, + {name = "orjson-3.11.7-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/d4/0b/ccb7ee1a65b37e8eeb8b267dc953561d72370e85185e459616d4345bab34/orjson-3.11.7-cp311-cp311-win32.whl",hashes = {sha256 = "c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d"}}, + {name = "orjson-3.11.7-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/af/9e/55c776dffda3f381e0f07d010a4f5f3902bf48eaba1bb7684d301acd4924/orjson-3.11.7-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471"}}, + {name = "orjson-3.11.7-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/aa/8e/424a620fa7d263b880162505fb107ef5e0afaa765b5b06a88312ac291560/orjson-3.11.7-cp311-cp311-win_arm64.whl",hashes = {sha256 = "1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d"}}, + {name = "orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/52/a2/fa129e749d500f9b183e8a3446a193818a25f60261e9ce143ad61e975208/orjson-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/08/93/1e82011cd1e0bd051ef9d35bed1aa7fb4ea1f0a055dc2c841b46b43a9ebd/orjson-3.11.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/fe/d8/a26b431ef962c7d55736674dddade876822f3e33223c1f47a36879350d04/orjson-3.11.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a7/19/f47819b84a580f490da260c3ee9ade214cf4cf78ac9ce8c1c758f80fdfc9/orjson-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/5b/cd/37ece39a0777ba077fdcdbe4cccae3be8ed00290c14bf8afdc548befc260/orjson-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222"}}, + {name = "orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/8f/ed/f2b5d66aa9b6b5c02ff5f120efc7b38c7c4962b21e6be0f00fd99a5c348e/orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c4/6e/baa83e68d1aa09fa8c3e5b2c087d01d0a0bd45256de719ed7bc22c07052d/orjson-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/0c/47/7f8ef4963b772cd56999b535e553f7eb5cd27e9dd6c049baee6f18bfa05d/orjson-3.11.7-cp310-cp310-musllinux_1_2_armv7l.whl",hashes = {sha256 = "3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/38/eb/2df104dd2244b3618f25325a656f85cc3277f74bbd91224752410a78f3c7/orjson-3.11.7-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c"}}, + {name = "orjson-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/2a/ee41de0aa3a6686598661eae2b4ebdff1340c65bfb17fcff8b87138aab21/orjson-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f"}}, + {name = "orjson-3.11.7-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/4c/fa/92fc5d3d402b87a8b28277a9ed35386218a6a5287c7fe5ee9b9f02c53fb2/orjson-3.11.7-cp310-cp310-win32.whl",hashes = {sha256 = "ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de"}}, + {name = "orjson-3.11.7-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/07/29/a576bf36d73d60df06904d3844a9df08e25d59eba64363aaf8ec2f9bff41/orjson-3.11.7-cp310-cp310-win_amd64.whl",hashes = {sha256 = "d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "psycopg" +version = "3.3.3" +requires-python = ">=3.10" +sdist = {name = "psycopg-3.3.3.tar.gz", url = "https://files.pythonhosted.org/packages/d3/b6/379d0a960f8f435ec78720462fd94c4863e7a31237cf81bf76d0af5883bf/psycopg-3.3.3.tar.gz", hashes = {sha256 = "5e9a47458b3c1583326513b2556a2a9473a1001a56c9efe9e587245b43148dd9"}} +wheels = [ + {name = "psycopg-3.3.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c8/5b/181e2e3becb7672b502f0ed7f16ed7352aca7c109cfb94cf3878a9186db9/psycopg-3.3.3-py3-none-any.whl",hashes = {sha256 = "f96525a72bcfade6584ab17e89de415ff360748c766f0106959144dcbb38c698"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "typing-extensions>=4.6; python_version < \"3.13\"", + "tzdata; sys_platform == \"win32\"", +] + +[[packages]] +name = "pytest" +version = "9.0.2" +requires-python = ">=3.10" +sdist = {name = "pytest-9.0.2.tar.gz", url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hashes = {sha256 = "75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"}} +wheels = [ + {name = "pytest-9.0.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl",hashes = {sha256 = "711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "colorama>=0.4; sys_platform == \"win32\"", + "exceptiongroup>=1; python_version < \"3.11\"", + "iniconfig>=1.0.1", + "packaging>=22", + "pluggy<2,>=1.5", + "pygments>=2.7.2", + "tomli>=1; python_version < \"3.11\"", +] + +[[packages]] +name = "pytest-cases" +version = "3.9.1" +sdist = {name = "pytest_cases-3.9.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/69/8b41e074e9e1a9fa85c3765971f213e1b8d4a2f648b457af32dea792bdb8/pytest_cases-3.9.1.tar.gz", hashes = {sha256 = "c4e181f1b525c931a318d4812fa8de656c2c8fb77fccf1571ecf0cc5fe8e7f8f"}} +wheels = [ + {name = "pytest_cases-3.9.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/92/82/db006f1d06e5d31805ac47f9ce979937e3d026292f2759543b744f8040be/pytest_cases-3.9.1-py2.py3-none-any.whl",hashes = {sha256 = "60507716650c5ed1ce4a36a3c137f1c3ec58f4fef1ee8678404be074612fcd21"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "decopatch", + "makefun>=1.15.1", + "packaging", + "pytest", +] + +[[packages]] +name = "tqdm" +version = "4.67.3" +requires-python = ">=3.7" +sdist = {name = "tqdm-4.67.3.tar.gz", url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hashes = {sha256 = "7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb"}} +wheels = [ + {name = "tqdm-4.67.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl",hashes = {sha256 = "ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "colorama; platform_system == \"Windows\"", + "importlib-metadata; python_version < \"3.8\"", +] + +[[packages]] +name = "types-tqdm" +version = "4.67.3.20260205" +requires-python = ">=3.9" +sdist = {name = "types_tqdm-4.67.3.20260205.tar.gz", url = "https://files.pythonhosted.org/packages/53/46/790b9872523a48163bdda87d47849b4466017640e5259d06eed539340afd/types_tqdm-4.67.3.20260205.tar.gz", hashes = {sha256 = "f3023682d4aa3bbbf908c8c6bb35f35692d319460d9bbd3e646e8852f3dd9f85"}} +wheels = [ + {name = "types_tqdm-4.67.3.20260205-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl",hashes = {sha256 = "85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173"}}, +] +marker = "\"types\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "types-requests", +] + +[[packages]] +name = "tomli" +version = "2.4.0" +requires-python = ">=3.8" +sdist = {name = "tomli-2.4.0.tar.gz", url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hashes = {sha256 = "aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}} +wheels = [ + {name = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}}, + {name = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}}, + {name = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}}, + {name = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}}, + {name = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}}, + {name = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}}, + {name = "tomli-2.4.0-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl",hashes = {sha256 = "31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}}, + {name = "tomli-2.4.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}}, + {name = "tomli-2.4.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}}, + {name = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}}, + {name = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}}, + {name = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}}, + {name = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}}, + {name = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}}, + {name = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}}, + {name = "tomli-2.4.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl",hashes = {sha256 = "d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}}, + {name = "tomli-2.4.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}}, + {name = "tomli-2.4.0-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}}, + {name = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}}, + {name = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}}, + {name = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}}, + {name = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}}, + {name = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}}, + {name = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}}, + {name = "tomli-2.4.0-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl",hashes = {sha256 = "7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}}, + {name = "tomli-2.4.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}}, + {name = "tomli-2.4.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}}, + {name = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}}, + {name = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}}, + {name = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}}, + {name = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}}, + {name = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}}, + {name = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}}, + {name = "tomli-2.4.0-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl",hashes = {sha256 = "0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}}, + {name = "tomli-2.4.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}}, + {name = "tomli-2.4.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}}, + {name = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}}, + {name = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}}, + {name = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}}, + {name = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}}, + {name = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}}, + {name = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}}, + {name = "tomli-2.4.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl",hashes = {sha256 = "b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}}, + {name = "tomli-2.4.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}}, + {name = "tomli-2.4.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}}, + {name = "tomli-2.4.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl",hashes = {sha256 = "1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}}, +] +marker = "\"lint\" in dependency_groups and python_version < \"3.11\" or \"test\" in dependency_groups and python_version < \"3.11\"" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "pluggy" +version = "1.6.0" +requires-python = ">=3.9" +sdist = {name = "pluggy-1.6.0.tar.gz", url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hashes = {sha256 = "7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}} +wheels = [ + {name = "pluggy-1.6.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl",hashes = {sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "typing-extensions" +version = "4.15.0" +requires-python = ">=3.9" +sdist = {name = "typing_extensions-4.15.0.tar.gz", url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hashes = {sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}} +wheels = [ + {name = "typing_extensions-4.15.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl",hashes = {sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}}, +] +marker = "\"default\" in dependency_groups or \"lint\" in dependency_groups or \"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "colorama" +version = "0.4.6" +requires-python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +sdist = {name = "colorama-0.4.6.tar.gz", url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hashes = {sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}} +wheels = [ + {name = "colorama-0.4.6-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl",hashes = {sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}}, +] +marker = "sys_platform == \"win32\" and \"default\" in dependency_groups or sys_platform == \"win32\" and \"test\" in dependency_groups or platform_system == \"Windows\" and \"default\" in dependency_groups or platform_system == \"Windows\" and \"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "exceptiongroup" +version = "1.3.1" +requires-python = ">=3.7" +sdist = {name = "exceptiongroup-1.3.1.tar.gz", url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hashes = {sha256 = "8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}} +wheels = [ + {name = "exceptiongroup-1.3.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl",hashes = {sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}}, +] +marker = "\"default\" in dependency_groups and python_version < \"3.11\" or \"test\" in dependency_groups and python_version < \"3.11\"" + +[packages.tool.pdm] +dependencies = [ + "typing-extensions>=4.6.0; python_version < \"3.13\"", +] + +[[packages]] +name = "httpx" +version = "0.28.1" +requires-python = ">=3.8" +sdist = {name = "httpx-0.28.1.tar.gz", url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hashes = {sha256 = "75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}} +wheels = [ + {name = "httpx-0.28.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl",hashes = {sha256 = "d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "anyio", + "certifi", + "httpcore==1.*", + "idna", +] + +[[packages]] +name = "httpcore" +version = "1.0.9" +requires-python = ">=3.8" +sdist = {name = "httpcore-1.0.9.tar.gz", url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hashes = {sha256 = "6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}} +wheels = [ + {name = "httpcore-1.0.9-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl",hashes = {sha256 = "2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "certifi", + "h11>=0.16", +] + +[[packages]] +name = "h11" +version = "0.16.0" +requires-python = ">=3.8" +sdist = {name = "h11-0.16.0.tar.gz", url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hashes = {sha256 = "4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}} +wheels = [ + {name = "h11-0.16.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl",hashes = {sha256 = "63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "httpx-retries" +version = "0.4.6" +requires-python = ">=3.9" +sdist = {name = "httpx_retries-0.4.6.tar.gz", url = "https://files.pythonhosted.org/packages/a4/13/5eac2df576c02280f79e4639a6d4c93a25cfe94458275f5aa55f5e6c8ea0/httpx_retries-0.4.6.tar.gz", hashes = {sha256 = "a076d8a5ede5d5794e9c241da17b15b393b482129ddd2fdf1fa56a3fa1f28a7f"}} +wheels = [ + {name = "httpx_retries-0.4.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f2/97/63f56da4400034adde22adfe7524635dba068f17d6858f92ecd96f55b53e/httpx_retries-0.4.6-py3-none-any.whl",hashes = {sha256 = "d66d912173b844e065ffb109345a453b922f4c2cd9c9e11139304cb33e7a1ee1"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "httpx>=0.20.0", +] + +[[packages]] +name = "iniconfig" +version = "2.3.0" +requires-python = ">=3.10" +sdist = {name = "iniconfig-2.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hashes = {sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}} +wheels = [ + {name = "iniconfig-2.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl",hashes = {sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "makefun" +version = "1.16.0" +sdist = {name = "makefun-1.16.0.tar.gz", url = "https://files.pythonhosted.org/packages/7b/cf/6780ab8bc3b84a1cce3e4400aed3d64b6db7d5e227a2f75b6ded5674701a/makefun-1.16.0.tar.gz", hashes = {sha256 = "e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947"}} +wheels = [ + {name = "makefun-1.16.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/c0/4bc973defd1270b89ccaae04cef0d5fa3ea85b59b108ad2c08aeea9afb76/makefun-1.16.0-py2.py3-none-any.whl",hashes = {sha256 = "43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "funcsigs; python_version < \"3.3\"", +] + +[[packages]] +name = "mypy-extensions" +version = "1.1.0" +requires-python = ">=3.8" +sdist = {name = "mypy_extensions-1.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hashes = {sha256 = "52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}} +wheels = [ + {name = "mypy_extensions-1.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl",hashes = {sha256 = "1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}}, +] +marker = "\"lint\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "packaging" +version = "26.0" +requires-python = ">=3.8" +sdist = {name = "packaging-26.0.tar.gz", url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hashes = {sha256 = "00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}} +wheels = [ + {name = "packaging-26.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl",hashes = {sha256 = "b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "pathspec" +version = "1.0.4" +requires-python = ">=3.9" +sdist = {name = "pathspec-1.0.4.tar.gz", url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hashes = {sha256 = "0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645"}} +wheels = [ + {name = "pathspec-1.0.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl",hashes = {sha256 = "fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}}, +] +marker = "\"lint\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "pygments" +version = "2.19.2" +requires-python = ">=3.8" +sdist = {name = "pygments-2.19.2.tar.gz", url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hashes = {sha256 = "636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}} +wheels = [ + {name = "pygments-2.19.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl",hashes = {sha256 = "86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "ruamel-yaml" +version = "0.19.1" +requires-python = ">=3.9" +sdist = {name = "ruamel_yaml-0.19.1.tar.gz", url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hashes = {sha256 = "53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993"}} +wheels = [ + {name = "ruamel_yaml-0.19.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl",hashes = {sha256 = "27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93"}}, +] +marker = "\"lint\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "anyio" +version = "4.12.1" +requires-python = ">=3.9" +sdist = {name = "anyio-4.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hashes = {sha256 = "41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703"}} +wheels = [ + {name = "anyio-4.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl",hashes = {sha256 = "d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "exceptiongroup>=1.0.2; python_version < \"3.11\"", + "idna>=2.8", + "typing-extensions>=4.5; python_version < \"3.13\"", +] + +[[packages]] +name = "idna" +version = "3.11" +requires-python = ">=3.8" +sdist = {name = "idna-3.11.tar.gz", url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hashes = {sha256 = "795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}} +wheels = [ + {name = "idna-3.11-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl",hashes = {sha256 = "771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "certifi" +version = "2026.2.25" +requires-python = ">=3.7" +sdist = {name = "certifi-2026.2.25.tar.gz", url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hashes = {sha256 = "e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"}} +wheels = [ + {name = "certifi-2026.2.25-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl",hashes = {sha256 = "027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "decopatch" +version = "1.4.10" +sdist = {name = "decopatch-1.4.10.tar.gz", url = "https://files.pythonhosted.org/packages/90/4c/8ca1f193428cbc4d63d0f07db9b8bd96be2db8ee5deefa93e7e8a28f2812/decopatch-1.4.10.tar.gz", hashes = {sha256 = "957f49c93f4150182c23f8fb51d13bb3213e0f17a79e09c8cca7057598b55720"}} +wheels = [ + {name = "decopatch-1.4.10-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/7b/fa/8e4a51e1afda8d4bd73d784bfe4a60cfdeeced9bea419eff5c271180377e/decopatch-1.4.10-py2.py3-none-any.whl",hashes = {sha256 = "e151f7f93de2b1b3fd3f3272dcc7cefd1a69f68ec1c2d8e288ecd9deb36dc5f7"}}, +] +marker = "\"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "makefun>=1.5.0", + "funcsigs; python_version < \"3.3\"", + "enum34; python_version < \"3.4\"", +] + +[[packages]] +name = "types-requests" +version = "2.32.4.20260107" +requires-python = ">=3.9" +sdist = {name = "types_requests-2.32.4.20260107.tar.gz", url = "https://files.pythonhosted.org/packages/0f/f3/a0663907082280664d745929205a89d41dffb29e89a50f753af7d57d0a96/types_requests-2.32.4.20260107.tar.gz", hashes = {sha256 = "018a11ac158f801bfa84857ddec1650750e393df8a004a8a9ae2a9bec6fcb24f"}} +wheels = [ + {name = "types_requests-2.32.4.20260107-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1c/12/709ea261f2bf91ef0a26a9eed20f2623227a8ed85610c1e54c5805692ecb/types_requests-2.32.4.20260107-py3-none-any.whl",hashes = {sha256 = "b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d"}}, +] +marker = "\"types\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [ + "urllib3>=2", +] + +[[packages]] +name = "urllib3" +version = "2.6.3" +requires-python = ">=3.9" +sdist = {name = "urllib3-2.6.3.tar.gz", url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hashes = {sha256 = "1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}} +wheels = [ + {name = "urllib3-2.6.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl",hashes = {sha256 = "bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}}, +] +marker = "\"types\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "tzdata" +version = "2025.3" +requires-python = ">=2" +sdist = {name = "tzdata-2025.3.tar.gz", url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hashes = {sha256 = "de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7"}} +wheels = [ + {name = "tzdata-2025.3-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl",hashes = {sha256 = "06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}}, +] +marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[tool.pdm] +hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} +strategy = ["inherit_metadata", "static_urls"] + +[[tool.pdm.targets]] +requires_python = ">=3.10" diff --git a/pylock.maximal.toml b/pylock.maximal.toml index bacb212..70c5380 100644 --- a/pylock.maximal.toml +++ b/pylock.maximal.toml @@ -3,7 +3,7 @@ lock-version = "1.0" requires-python = ">=3.10" environments = [ - "python_version >= \"3.13\"", + "python_version >= \"3.14\"", ] extras = [] dependency-groups = ["default", "lint", "test", "types"] @@ -22,15 +22,9 @@ wheels = [ {name = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}}, {name = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}}, {name = "mypy-1.18.2-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl",hashes = {sha256 = "749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}}, - {name = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}}, - {name = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}}, - {name = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}}, - {name = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}}, - {name = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}}, - {name = "mypy-1.18.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}}, {name = "mypy-1.18.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl",hashes = {sha256 = "22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}}, ] -marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -48,7 +42,7 @@ sdist = {name = "pre_commit_hooks-6.0.0.tar.gz", url = "https://files.pythonhost wheels = [ {name = "pre_commit_hooks-6.0.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/12/46/eba9be9daa403fa94854ce16a458c29df9a01c6c047931c3d8be6016cd9a/pre_commit_hooks-6.0.0-py2.py3-none-any.whl",hashes = {sha256 = "76161b76d321d2f8ee2a8e0b84c30ee8443e01376121fd1c90851e33e3bd7ee2"}}, ] -marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -81,26 +75,7 @@ wheels = [ {name = "ruff-0.13.1-py3-none-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/51/c6a3a33d9938007b8bdc8ca852ecc8d810a407fb513ab08e34af12dc7c24/ruff-0.13.1-py3-none-win_amd64.whl",hashes = {sha256 = "3a3fb595287ee556de947183489f636b9f76a72f0fa9c028bdcabf5bab2cc5e5"}}, {name = "ruff-0.13.1-py3-none-win_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/04/afc078a12cf68592345b1e2d6ecdff837d286bac023d7a22c54c7a698c5b/ruff-0.13.1-py3-none-win_arm64.whl",hashes = {sha256 = "c0bae9ffd92d54e03c2bf266f466da0a65e145f298ee5b5846ed435f6a00518a"}}, ] -marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "duckdb" -version = "1.3.2" -requires-python = ">=3.7.0" -sdist = {name = "duckdb-1.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/47/24/a2e7fb78fba577641c286fe33185789ab1e1569ccdf4d142e005995991d2/duckdb-1.3.2.tar.gz", hashes = {sha256 = "c658df8a1bc78704f702ad0d954d82a1edd4518d7a04f00027ec53e40f591ff5"}} -wheels = [ - {name = "duckdb-1.3.2-cp313-cp313-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/f0/8cac9713735864899e8abc4065bbdb3d1617f2130006d508a80e1b1a6c53/duckdb-1.3.2-cp313-cp313-macosx_12_0_arm64.whl",hashes = {sha256 = "a3418c973b06ac4e97f178f803e032c30c9a9f56a3e3b43a866f33223dfbf60b"}}, - {name = "duckdb-1.3.2-cp313-cp313-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/c5/26/6698bbb30b7bce8b8b17697599f1517611c61e4bd68b37eaeaf4f5ddd915/duckdb-1.3.2-cp313-cp313-macosx_12_0_universal2.whl",hashes = {sha256 = "2a741eae2cf110fd2223eeebe4151e22c0c02803e1cfac6880dbe8a39fecab6a"}}, - {name = "duckdb-1.3.2-cp313-cp313-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/10/75/8ab4da3099a2fac7335ecebce4246706d19bdd5dad167aa436b5b27c43c4/duckdb-1.3.2-cp313-cp313-macosx_12_0_x86_64.whl",hashes = {sha256 = "51e62541341ea1a9e31f0f1ade2496a39b742caf513bebd52396f42ddd6525a0"}}, - {name = "duckdb-1.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/d1/46/af81b10d4a66a0f27c248df296d1b41ff2a305a235ed8488f93240f6f8b5/duckdb-1.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b3e519de5640e5671f1731b3ae6b496e0ed7e4de4a1c25c7a2f34c991ab64d71"}}, - {name = "duckdb-1.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/68/fc/259a54fc22111a847981927aa58528d766e8b228c6d41deb0ad8a1959f9f/duckdb-1.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4732fb8cc60566b60e7e53b8c19972cb5ed12d285147a3063b16cc64a79f6d9f"}}, - {name = "duckdb-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ab/dc/5d5140383e40661173dacdceaddee2a97c3f6721a5e8d76e08258110595e/duckdb-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "97f7a22dcaa1cca889d12c3dc43a999468375cdb6f6fe56edf840e062d4a8293"}}, - {name = "duckdb-1.3.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/c9/2fcd86ab7530a5b6caff42dbe516ce7a86277e12c499d1c1f5acd266ffb2/duckdb-1.3.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "cd3d717bf9c49ef4b1016c2216517572258fa645c2923e91c5234053defa3fb5"}}, -] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -141,39 +116,28 @@ wheels = [ {name = "coverage-7.13.4-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl",hashes = {sha256 = "c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}}, {name = "coverage-7.13.4-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}}, {name = "coverage-7.13.4-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}}, - {name = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}}, - {name = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}}, - {name = "coverage-7.13.4-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl",hashes = {sha256 = "f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}}, - {name = "coverage-7.13.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}}, - {name = "coverage-7.13.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}}, - {name = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}}, - {name = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}}, - {name = "coverage-7.13.4-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl",hashes = {sha256 = "2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}}, - {name = "coverage-7.13.4-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}}, - {name = "coverage-7.13.4-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}}, {name = "coverage-7.13.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl",hashes = {sha256 = "1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + +[[packages]] +name = "duckdb" +version = "1.4.4" +requires-python = ">=3.9.0" +sdist = {name = "duckdb-1.4.4.tar.gz", url = "https://files.pythonhosted.org/packages/36/9d/ab66a06e416d71b7bdcb9904cdf8d4db3379ef632bb8e9495646702d9718/duckdb-1.4.4.tar.gz", hashes = {sha256 = "8bba52fd2acb67668a4615ee17ee51814124223de836d9e2fdcbc4c9021b3d3c"}} +wheels = [ + {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/97/a6/f19e2864e651b0bd8e4db2b0c455e7e0d71e0d4cd2cd9cc052f518e43eb3/duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "25874f8b1355e96178079e37312c3ba6d61a2354f51319dae860cf21335c3a20"}}, + {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/0e/93/8a24e932c67414fd2c45bed83218e62b73348996bf859eda020c224774b2/duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "452c5b5d6c349dc5d1154eb2062ee547296fcbd0c20e9df1ed00b5e1809089da"}}, + {name = "duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/62/13/e5378ff5bb1d4397655d840b34b642b1b23cdd82ae19599e62dc4b9461c9/duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8e5c2d8a0452df55e092959c0bfc8ab8897ac3ea0f754cb3b0ab3e165cd79aff"}}, + {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2d/94/24364da564b27aeebe44481f15bd0197a0b535ec93f188a6b1b98c22f082/duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1af6e76fe8bd24875dc56dd8e38300d64dc708cd2e772f67b9fbc635cc3066a3"}}, + {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/0a/6ae31b2914b4dc34243279b2301554bcbc5f1a09ccc82600486c49ab71d1/duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d0440f59e0cd9936a9ebfcf7a13312eda480c79214ffed3878d75947fc3b7d6d"}}, + {name = "duckdb-1.4.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d2/b1/fd5c37c53d45efe979f67e9bd49aaceef640147bb18f0699a19edd1874d6/duckdb-1.4.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "59c8d76016dde854beab844935b1ec31de358d4053e792988108e995b18c08e7"}}, + {name = "duckdb-1.4.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/2d/13e6024e613679d8a489dd922f199ef4b1d08a456a58eadd96dc2f05171f/duckdb-1.4.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "53cd6423136ab44383ec9955aefe7599b3fb3dd1fe006161e6396d8167e0e0d4"}}, +] +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -186,7 +150,7 @@ sdist = {name = "httpx_folio-0.3.0.tar.gz", url = "https://files.pythonhosted.or wheels = [ {name = "httpx_folio-0.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5a/91/2ab3ee8588e5eab7808be5c3b1ea8fb3515f07686cddf49cbcde40885b3d/httpx_folio-0.3.0-py3-none-any.whl",hashes = {sha256 = "5396438eb07257db7c080382f65711b01b93eab3b2adc420a5855be3007c37ae"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -215,36 +179,21 @@ wheels = [ {name = "orjson-3.11.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/1d/d3/f19b47ce16820cc2c480f7f1723e17f6d411b3a295c60c8ad3aa9ff1c96a/orjson-3.11.7-cp314-cp314-win32.whl",hashes = {sha256 = "89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576"}}, {name = "orjson-3.11.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/12/df/172771902943af54bf661a8d102bdf2e7f932127968080632bda6054b62c/orjson-3.11.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1"}}, {name = "orjson-3.11.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/6f/1c/f2a8d8a1b17514660a614ce5f7aac74b934e69f5abc2700cc7ced882a009/orjson-3.11.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d"}}, - {name = "orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/89/25/6e0e52cac5aab51d7b6dcd257e855e1dec1c2060f6b28566c509b4665f62/orjson-3.11.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl",hashes = {sha256 = "1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733"}}, - {name = "orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/29/a77f48d2fc8a05bbc529e5ff481fb43d914f9e383ea2469d4f3d51df3d00/orjson-3.11.7-cp313-cp313-macosx_15_0_arm64.whl",hashes = {sha256 = "d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4"}}, - {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/25/0a16e0729a0e6a1504f9d1a13cdd365f030068aab64cec6958396b9969d7/orjson-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785"}}, - {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/66/da/a2e505469d60666a05ab373f1a6322eb671cb2ba3a0ccfc7d4bc97196787/orjson-3.11.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539"}}, - {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/23/bf/ed73f88396ea35c71b38961734ea4a4746f7ca0768bf28fd551d37e48dd0/orjson-3.11.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1"}}, - {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/73/3c/b05d80716f0225fc9008fbf8ab22841dcc268a626aa550561743714ce3bf/orjson-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1"}}, - {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/61/e8/0be9b0addd9bf86abfc938e97441dcd0375d494594b1c8ad10fe57479617/orjson-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705"}}, - {name = "orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c9/ec/c68e3b9021a31d9ec15a94931db1410136af862955854ed5dd7e7e4f5bff/orjson-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace"}}, - {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d2/45/f3466739aaafa570cc8e77c6dbb853c48bf56e3b43738020e2661e08b0ac/orjson-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b"}}, - {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/e1/84/9f7f02288da1ffb31405c1be07657afd1eecbcb4b64ee2817b6fe0f785fa/orjson-3.11.7-cp313-cp313-musllinux_1_2_armv7l.whl",hashes = {sha256 = "ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157"}}, - {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/18/07/9dd2f0c0104f1a0295ffbe912bc8d63307a539b900dd9e2c48ef7810d971/orjson-3.11.7-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3"}}, - {name = "orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/66/857a8e4a3292e1f7b1b202883bcdeb43a91566cf59a93f97c53b44bd6801/orjson-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223"}}, - {name = "orjson-3.11.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/0a/5b/6ebcf3defc1aab3a338ca777214966851e92efb1f30dc7fc8285216e6d1b/orjson-3.11.7-cp313-cp313-win32.whl",hashes = {sha256 = "7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3"}}, - {name = "orjson-3.11.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/00/04/c6f72daca5092e3117840a1b1e88dfc809cc1470cf0734890d0366b684a1/orjson-3.11.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757"}}, - {name = "orjson-3.11.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/03/ba/077a0f6f1085d6b806937246860fafbd5b17f3919c70ee3f3d8d9c713f38/orjson-3.11.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539"}}, -] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +] +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [] [[packages]] name = "psycopg" -version = "3.3.2" +version = "3.3.3" requires-python = ">=3.10" -sdist = {name = "psycopg-3.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/e0/1a/7d9ef4fdc13ef7f15b934c393edc97a35c281bb7d3c3329fbfcbe915a7c2/psycopg-3.3.2.tar.gz", hashes = {sha256 = "707a67975ee214d200511177a6a80e56e654754c9afca06a7194ea6bbfde9ca7"}} +sdist = {name = "psycopg-3.3.3.tar.gz", url = "https://files.pythonhosted.org/packages/d3/b6/379d0a960f8f435ec78720462fd94c4863e7a31237cf81bf76d0af5883bf/psycopg-3.3.3.tar.gz", hashes = {sha256 = "5e9a47458b3c1583326513b2556a2a9473a1001a56c9efe9e587245b43148dd9"}} wheels = [ - {name = "psycopg-3.3.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8c/51/2779ccdf9305981a06b21a6b27e8547c948d85c41c76ff434192784a4c93/psycopg-3.3.2-py3-none-any.whl",hashes = {sha256 = "3e94bc5f4690247d734599af56e51bae8e0db8e4311ea413f801fef82b14a99b"}}, + {name = "psycopg-3.3.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c8/5b/181e2e3becb7672b502f0ed7f16ed7352aca7c109cfb94cf3878a9186db9/psycopg-3.3.3-py3-none-any.whl",hashes = {sha256 = "f96525a72bcfade6584ab17e89de415ff360748c766f0106959144dcbb38c698"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -260,7 +209,7 @@ sdist = {name = "pytest-9.0.2.tar.gz", url = "https://files.pythonhosted.org/pac wheels = [ {name = "pytest-9.0.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl",hashes = {sha256 = "711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -280,7 +229,7 @@ sdist = {name = "pytest_cases-3.9.1.tar.gz", url = "https://files.pythonhosted.o wheels = [ {name = "pytest_cases-3.9.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/92/82/db006f1d06e5d31805ac47f9ce979937e3d026292f2759543b744f8040be/pytest_cases-3.9.1-py2.py3-none-any.whl",hashes = {sha256 = "60507716650c5ed1ce4a36a3c137f1c3ec58f4fef1ee8678404be074612fcd21"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -298,7 +247,7 @@ sdist = {name = "tqdm-4.67.3.tar.gz", url = "https://files.pythonhosted.org/pack wheels = [ {name = "tqdm-4.67.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl",hashes = {sha256 = "ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -314,7 +263,7 @@ sdist = {name = "types_tqdm-4.67.3.20260205.tar.gz", url = "https://files.python wheels = [ {name = "types_tqdm-4.67.3.20260205-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl",hashes = {sha256 = "85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173"}}, ] -marker = "python_version >= \"3.13\" and \"types\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"types\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -329,7 +278,7 @@ sdist = {name = "pluggy-1.6.0.tar.gz", url = "https://files.pythonhosted.org/pac wheels = [ {name = "pluggy-1.6.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl",hashes = {sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -342,7 +291,7 @@ sdist = {name = "colorama-0.4.6.tar.gz", url = "https://files.pythonhosted.org/p wheels = [ {name = "colorama-0.4.6-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl",hashes = {sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}}, ] -marker = "sys_platform == \"win32\" and python_version >= \"3.13\" and \"default\" in dependency_groups or sys_platform == \"win32\" and python_version >= \"3.13\" and \"test\" in dependency_groups or platform_system == \"Windows\" and python_version >= \"3.13\" and \"default\" in dependency_groups or platform_system == \"Windows\" and python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "sys_platform == \"win32\" and python_version >= \"3.14\" and \"default\" in dependency_groups or sys_platform == \"win32\" and python_version >= \"3.14\" and \"test\" in dependency_groups or platform_system == \"Windows\" and python_version >= \"3.14\" and \"default\" in dependency_groups or platform_system == \"Windows\" and python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -355,7 +304,7 @@ sdist = {name = "httpx-0.28.1.tar.gz", url = "https://files.pythonhosted.org/pac wheels = [ {name = "httpx-0.28.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl",hashes = {sha256 = "d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -373,7 +322,7 @@ sdist = {name = "httpcore-1.0.9.tar.gz", url = "https://files.pythonhosted.org/p wheels = [ {name = "httpcore-1.0.9-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl",hashes = {sha256 = "2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -389,20 +338,20 @@ sdist = {name = "h11-0.16.0.tar.gz", url = "https://files.pythonhosted.org/packa wheels = [ {name = "h11-0.16.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl",hashes = {sha256 = "63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [] [[packages]] name = "httpx-retries" -version = "0.4.5" +version = "0.4.6" requires-python = ">=3.9" -sdist = {name = "httpx_retries-0.4.5.tar.gz", url = "https://files.pythonhosted.org/packages/22/40/b9b5e4c16fb86d2999840bb795b28670a61856c7f48f030530b412bf4133/httpx_retries-0.4.5.tar.gz", hashes = {sha256 = "acee306d7384eefad71ac12fefe8b13d7b41c19595c538e68d9bd7e40e59539d"}} +sdist = {name = "httpx_retries-0.4.6.tar.gz", url = "https://files.pythonhosted.org/packages/a4/13/5eac2df576c02280f79e4639a6d4c93a25cfe94458275f5aa55f5e6c8ea0/httpx_retries-0.4.6.tar.gz", hashes = {sha256 = "a076d8a5ede5d5794e9c241da17b15b393b482129ddd2fdf1fa56a3fa1f28a7f"}} wheels = [ - {name = "httpx_retries-0.4.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/0a/2626b5a2678f8072ba3174d3e40f81429fdc41d1cb993280dbc7ba3c4e3f/httpx_retries-0.4.5-py3-none-any.whl",hashes = {sha256 = "ae22d6ef197a2da49242246a01d721474cbd6516b1fef155f6da694ee410bb37"}}, + {name = "httpx_retries-0.4.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f2/97/63f56da4400034adde22adfe7524635dba068f17d6858f92ecd96f55b53e/httpx_retries-0.4.6-py3-none-any.whl",hashes = {sha256 = "d66d912173b844e065ffb109345a453b922f4c2cd9c9e11139304cb33e7a1ee1"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -417,7 +366,7 @@ sdist = {name = "iniconfig-2.3.0.tar.gz", url = "https://files.pythonhosted.org/ wheels = [ {name = "iniconfig-2.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl",hashes = {sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -429,7 +378,7 @@ sdist = {name = "makefun-1.16.0.tar.gz", url = "https://files.pythonhosted.org/p wheels = [ {name = "makefun-1.16.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/c0/4bc973defd1270b89ccaae04cef0d5fa3ea85b59b108ad2c08aeea9afb76/makefun-1.16.0-py2.py3-none-any.whl",hashes = {sha256 = "43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -444,7 +393,7 @@ sdist = {name = "mypy_extensions-1.1.0.tar.gz", url = "https://files.pythonhoste wheels = [ {name = "mypy_extensions-1.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl",hashes = {sha256 = "1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}}, ] -marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -457,7 +406,7 @@ sdist = {name = "packaging-26.0.tar.gz", url = "https://files.pythonhosted.org/p wheels = [ {name = "packaging-26.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl",hashes = {sha256 = "b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -470,7 +419,7 @@ sdist = {name = "pathspec-1.0.4.tar.gz", url = "https://files.pythonhosted.org/p wheels = [ {name = "pathspec-1.0.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl",hashes = {sha256 = "fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}}, ] -marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -483,7 +432,7 @@ sdist = {name = "pygments-2.19.2.tar.gz", url = "https://files.pythonhosted.org/ wheels = [ {name = "pygments-2.19.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl",hashes = {sha256 = "86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -496,7 +445,7 @@ sdist = {name = "ruamel_yaml-0.19.1.tar.gz", url = "https://files.pythonhosted.o wheels = [ {name = "ruamel_yaml-0.19.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl",hashes = {sha256 = "27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93"}}, ] -marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -509,7 +458,7 @@ sdist = {name = "typing_extensions-4.15.0.tar.gz", url = "https://files.pythonho wheels = [ {name = "typing_extensions-4.15.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl",hashes = {sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}}, ] -marker = "python_version >= \"3.13\" and \"lint\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -522,7 +471,7 @@ sdist = {name = "anyio-4.12.1.tar.gz", url = "https://files.pythonhosted.org/pac wheels = [ {name = "anyio-4.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl",hashes = {sha256 = "d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -539,20 +488,20 @@ sdist = {name = "idna-3.11.tar.gz", url = "https://files.pythonhosted.org/packag wheels = [ {name = "idna-3.11-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl",hashes = {sha256 = "771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [] [[packages]] name = "certifi" -version = "2026.1.4" +version = "2026.2.25" requires-python = ">=3.7" -sdist = {name = "certifi-2026.1.4.tar.gz", url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hashes = {sha256 = "ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}} +sdist = {name = "certifi-2026.2.25.tar.gz", url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hashes = {sha256 = "e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"}} wheels = [ - {name = "certifi-2026.1.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl",hashes = {sha256 = "9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}}, + {name = "certifi-2026.2.25-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl",hashes = {sha256 = "027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"}}, ] -marker = "python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -564,7 +513,7 @@ sdist = {name = "decopatch-1.4.10.tar.gz", url = "https://files.pythonhosted.org wheels = [ {name = "decopatch-1.4.10-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/7b/fa/8e4a51e1afda8d4bd73d784bfe4a60cfdeeced9bea419eff5c271180377e/decopatch-1.4.10-py2.py3-none-any.whl",hashes = {sha256 = "e151f7f93de2b1b3fd3f3272dcc7cefd1a69f68ec1c2d8e288ecd9deb36dc5f7"}}, ] -marker = "python_version >= \"3.13\" and \"test\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -581,7 +530,7 @@ sdist = {name = "types_requests-2.32.4.20260107.tar.gz", url = "https://files.py wheels = [ {name = "types_requests-2.32.4.20260107-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1c/12/709ea261f2bf91ef0a26a9eed20f2623227a8ed85610c1e54c5805692ecb/types_requests-2.32.4.20260107-py3-none-any.whl",hashes = {sha256 = "b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d"}}, ] -marker = "python_version >= \"3.13\" and \"types\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"types\" in dependency_groups" [packages.tool.pdm] dependencies = [ @@ -596,7 +545,7 @@ sdist = {name = "urllib3-2.6.3.tar.gz", url = "https://files.pythonhosted.org/pa wheels = [ {name = "urllib3-2.6.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl",hashes = {sha256 = "bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}}, ] -marker = "python_version >= \"3.13\" and \"types\" in dependency_groups" +marker = "python_version >= \"3.14\" and \"types\" in dependency_groups" [packages.tool.pdm] dependencies = [] @@ -609,14 +558,14 @@ sdist = {name = "tzdata-2025.3.tar.gz", url = "https://files.pythonhosted.org/pa wheels = [ {name = "tzdata-2025.3-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl",hashes = {sha256 = "06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}}, ] -marker = "sys_platform == \"win32\" and python_version >= \"3.13\" and \"default\" in dependency_groups" +marker = "sys_platform == \"win32\" and python_version >= \"3.14\" and \"default\" in dependency_groups" [packages.tool.pdm] dependencies = [] [tool.pdm] -hashes = {sha256 = "0c0e9208d38f65d8253d8fa6094d6d32dd41f91a12e3ab69ff765e694312f812"} +hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] -requires_python = ">=3.13" +requires_python = ">=3.14" diff --git a/pylock.minimal.toml b/pylock.minimal.toml index 6dd6a47..5c62add 100644 --- a/pylock.minimal.toml +++ b/pylock.minimal.toml @@ -104,34 +104,6 @@ marker = "\"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] -[[packages]] -name = "duckdb" -version = "0.9.2" -requires-python = ">=3.7.0" -sdist = {name = "duckdb-0.9.2.tar.gz", url = "https://files.pythonhosted.org/packages/5d/ca/cabff918b84235618710cafb2f45d7ee84b4224c131b16db4c69f2cd1ef9/duckdb-0.9.2.tar.gz", hashes = {sha256 = "3843afeab7c3fc4a4c0b53686a4cc1d9cdbdadcbb468d60fef910355ecafd447"}} -wheels = [ - {name = "duckdb-0.9.2-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/2f/92/8b2b73603efd6eec2db9b6d0a087a2005c357798963ed16595b38aa2e03d/duckdb-0.9.2-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "061a9ea809811d6e3025c5de31bc40e0302cfb08c08feefa574a6491e882e7e8"}}, - {name = "duckdb-0.9.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/32/2d/63769dcd6a35e639a7a3e0a8e9f14a14c180cc31605d62b9d283098ab2d8/duckdb-0.9.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "a43f93be768af39f604b7b9b48891f9177c9282a408051209101ff80f7450d8f"}}, - {name = "duckdb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d7/de/134a8310d18166f1ceb915038259bc0a0bb538d5f4d5a43bfc9632282486/duckdb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "ac29c8c8f56fff5a681f7bf61711ccb9325c5329e64f23cb7ff31781d7b50773"}}, - {name = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/21/92/07e21a3ec8ca88ab0e0ceaa87818a3e2dc9f2f93c1da9d34131828fc325f/duckdb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "b14d98d26bab139114f62ade81350a5342f60a168d94b27ed2c706838f949eda"}}, - {name = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/f9/71/cc6be43546540a7b480734be2e1822f31d51d7d3112ead13ffe0f8cf364d/duckdb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "796a995299878913e765b28cc2b14c8e44fae2f54ab41a9ee668c18449f5f833"}}, - {name = "duckdb-0.9.2-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/6e/f8088f2fd623e6a48846c3dd9adde67f520cee7ff4393d22a05be9c93d87/duckdb-0.9.2-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "6cb64ccfb72c11ec9c41b3cb6181b6fd33deccceda530e94e1c362af5f810ba1"}}, - {name = "duckdb-0.9.2-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/c7/79/12c98e0caf0b9231ec498f568afafddca67af8a6851f4583415ebd0febfd/duckdb-0.9.2-cp311-cp311-win32.whl",hashes = {sha256 = "930740cb7b2cd9e79946e1d3a8f66e15dc5849d4eaeff75c8788d0983b9256a5"}}, - {name = "duckdb-0.9.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a6/7a/e15904563fa63d7d3cc542a697377486ddea8ba4914810391812ffefc9b1/duckdb-0.9.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "c28f13c45006fd525001b2011cdf91fa216530e9751779651e66edc0e446be50"}}, - {name = "duckdb-0.9.2-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/c1/a2/82dfe2b377bbed986a20611775dae98cc31f5d9a47f378df039c3c66ae1f/duckdb-0.9.2-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "aadcea5160c586704c03a8a796c06a8afffbefefb1986601104a60cb0bfdb5ab"}}, - {name = "duckdb-0.9.2-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/7e/61/1708bbd29d04164b295ddedf2e30ecd82be4edac9babd0b45dfa268380e3/duckdb-0.9.2-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "08215f17147ed83cbec972175d9882387366de2ed36c21cbe4add04b39a5bcb4"}}, - {name = "duckdb-0.9.2-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/53/d7/ee3abe18d69db7beca6d47b95ede600a64a529a9e1a237bb4fcce37d74ea/duckdb-0.9.2-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "ee6c2a8aba6850abef5e1be9dbc04b8e72a5b2c2b67f77892317a21fae868fe7"}}, - {name = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/ec/ac/67f340d936a2754c64aa20d3b0bcee01a6ce195820b2794c9acbe2601a44/duckdb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "1ff49f3da9399900fd58b5acd0bb8bfad22c5147584ad2427a78d937e11ec9d0"}}, - {name = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/7c/d5/7688cdc1b57c9ada17b6f6143a923606294b462e4b15e3ac249c04649bde/duckdb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "dd5ac5baf8597efd2bfa75f984654afcabcd698342d59b0e265a0bc6f267b3f0"}}, - {name = "duckdb-0.9.2-cp310-cp310-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/ea/8e/a22bad5f552468190f1aafa2618a38e4a2f2d595a09660bc257613a97458/duckdb-0.9.2-cp310-cp310-musllinux_1_1_x86_64.whl",hashes = {sha256 = "81c6df905589a1023a27e9712edb5b724566587ef280a0c66a7ec07c8083623b"}}, - {name = "duckdb-0.9.2-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/40/39/6cb9719ff3ccd2fab7eb5f1524377d428c2af5128c13d594ca54aaddc3fa/duckdb-0.9.2-cp310-cp310-win32.whl",hashes = {sha256 = "a298cd1d821c81d0dec8a60878c4b38c1adea04a9675fb6306c8f9083bbf314d"}}, - {name = "duckdb-0.9.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1c/95/b0abc7155dda6fe7ac60a4493fe7b62228e6c54ff8c5ef8ffe9bb14bb499/duckdb-0.9.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "492a69cd60b6cb4f671b51893884cdc5efc4c3b2eb76057a007d2a2295427173"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "coverage" version = "7.10.7" @@ -235,6 +207,46 @@ marker = "\"test\" in dependency_groups" [packages.tool.pdm] dependencies = [] +[[packages]] +name = "duckdb" +version = "1.3.0" +requires-python = ">=3.7.0" +sdist = {name = "duckdb-1.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/3e/82/680b108da1870e48d98464ddcf03820f983421b5bbd8dd8beff98d583db7/duckdb-1.3.0.tar.gz", hashes = {sha256 = "09aaa4b1dca24f4d1f231e7ae66b6413e317b7e04e2753541d42df6c8113fac7"}} +wheels = [ + {name = "duckdb-1.3.0-cp313-cp313-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/32/d5/d2666a682cda7152d0f391067e0307eec3e913b3462d2b5b944a3aab4d1d/duckdb-1.3.0-cp313-cp313-macosx_12_0_arm64.whl",hashes = {sha256 = "176b9818d940c52ac7f31c64a98cf172d7c19d2a006017c9c4e9c06c246e36bf"}}, + {name = "duckdb-1.3.0-cp313-cp313-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/91/60/feb19a432c0b327b3d03171042acbafa688edb9a02f3034f7ae963d0f62d/duckdb-1.3.0-cp313-cp313-macosx_12_0_universal2.whl",hashes = {sha256 = "03981f7e8793f07a4a9a2ba387640e71d0a99ebcaf8693ab09f96d59e628b713"}}, + {name = "duckdb-1.3.0-cp313-cp313-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/f8/393beb10a24115347c8a4b75d59e6e1d49f7391722717a614bb71430673a/duckdb-1.3.0-cp313-cp313-macosx_12_0_x86_64.whl",hashes = {sha256 = "a177d55a38a62fdf79b59a0eaa32531a1dbb443265f6d67f64992cc1e82b755c"}}, + {name = "duckdb-1.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/71/45/da77973a7da7747385e16aa88c65a7b0e634585b5f7f92a6bb423838077c/duckdb-1.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b1c30e3749823147d5578bc3f01f35d1a0433a1c768908d946056ec8d6e1757e"}}, + {name = "duckdb-1.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/51/adc86c800e7ecfe828e94cccc28ac727b54a886124da08e3808cf77bf1b9/duckdb-1.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5855f3a564baf22eeeab70c120b51f5a11914f1f1634f03382daeb6b1dea4c62"}}, + {name = "duckdb-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/9d/ac3a6ddcaaf9bbd5584bb471794f017498326d11f754ee28b3c0a5c7aee8/duckdb-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9b1fac15a48056f7c2739cf8800873063ba2f691e91a9b2fc167658a401ca76a"}}, + {name = "duckdb-1.3.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ab/e9/f83285b0cb3729f24321a038f272490dfb76ca531b7cef832037b7bd077c/duckdb-1.3.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "fbdfc1c0b83b90f780ae74038187ee696bb56ab727a289752372d7ec42dda65b"}}, + {name = "duckdb-1.3.0-cp312-cp312-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e4/b8/0931871f55a10aacd1af024c8d1e5de68337032379438aba05e26e9a1132/duckdb-1.3.0-cp312-cp312-macosx_12_0_arm64.whl",hashes = {sha256 = "f24038fe9b83dcbaeafb1ed76ec3b3f38943c1c8d27ab464ad384db8a6658b61"}}, + {name = "duckdb-1.3.0-cp312-cp312-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/af/d5/a08f76900391ff248b18fc1d5742db4b7bcf910c4be00314ce7b3069223f/duckdb-1.3.0-cp312-cp312-macosx_12_0_universal2.whl",hashes = {sha256 = "956c85842841bef68f4a5388c6b225b933151a7c06d568390fc895fc44607913"}}, + {name = "duckdb-1.3.0-cp312-cp312-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/05/f1/9dfa45484422bd6c598e76fb2d005de48373aea66b037471b4568c1e938a/duckdb-1.3.0-cp312-cp312-macosx_12_0_x86_64.whl",hashes = {sha256 = "efe883d822ed56fcfbb6a7b397c13f6a0d2eaeb3bc4ef4510f84fadb3dfe416d"}}, + {name = "duckdb-1.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/4e/093944cbca2e4b3fe5da99c46df9f4ae293c6768f15f14a959aaa2064a50/duckdb-1.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3872a3a1b80ffba5264ea236a3754d0c41d3c7b01bdf8cdcb1c180fc1b8dc8e2"}}, + {name = "duckdb-1.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b0/9e/b1a7c086db03f3cc85c513e70034bd515e68e25013875e5f0b40c4bf5d0a/duckdb-1.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "30bf45ad78a5a997f378863e036e917b481d18d685e5c977cd0a3faf2e31fbaf"}}, + {name = "duckdb-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5e/b4/5baef852efec9480dcfb44bed5adc56f6fcee09919037cf54fbbe87ac427/duckdb-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "85cbd8e1d65df8a0780023baf5045d3033fabd154799bc9ea6d9ab5728f41eb3"}}, + {name = "duckdb-1.3.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/36/4f/f7ab120ecd827fdff59f14e1de9771335aa7656a29c3259fa7949de1f276/duckdb-1.3.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "8754c40dac0f26d9fb0363bbb5df02f7a61ce6a6728d5efc02c3bc925d7c89c3"}}, + {name = "duckdb-1.3.0-cp311-cp311-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/48/a5/0a7dd8f256aa75e254717732905fb96858a9e54e881a5da0966b5760393a/duckdb-1.3.0-cp311-cp311-macosx_12_0_arm64.whl",hashes = {sha256 = "60a58b85929754abb21db1e739d2f53eaef63e6015e62ba58eae3425030e7935"}}, + {name = "duckdb-1.3.0-cp311-cp311-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/10/b9/5a2275f765f3ca6375797066bc3870bdc8dc3f4c91b84f4230709e012c50/duckdb-1.3.0-cp311-cp311-macosx_12_0_universal2.whl",hashes = {sha256 = "1d46b5a20f078b1b2284243e02a1fde7e12cbb8d205fce62e4700bcfe6a09881"}}, + {name = "duckdb-1.3.0-cp311-cp311-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/a4/f6/20da96bc7e3886cf424461a45de3f76247b7731a5f7552615bd31e73f1ac/duckdb-1.3.0-cp311-cp311-macosx_12_0_x86_64.whl",hashes = {sha256 = "0044e5ffb2d46308099640a92f99980a44e12bb68642aa9e6b08acbf300d64a1"}}, + {name = "duckdb-1.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/43/21/ffe5aeb9d32a49d2de6d368b3fe3e53c2246eccec916375d65c45dc58339/duckdb-1.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5cb813de2ca2f5e7c77392a67bdcaa174bfd69ebbfdfc983024af270c77a0447"}}, + {name = "duckdb-1.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/0c/111dc4a3dcdd7007ca610e41a85634fbfa258ab960a6445e02872b67ab02/duckdb-1.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "7a0c993eb6df2b30b189ad747f3aea1b0b87b78ab7f80c6e7c57117b6e8dbfb0"}}, + {name = "duckdb-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/00/71c174b65f167af4d77aafa6a01445f08238e84dd679638836472f1141af/duckdb-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "6728e209570d36ece66dd7249e5d6055326321137cd807f26300733283930cd4"}}, + {name = "duckdb-1.3.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/2c/cb/c84a617f79bedb2220ea0b0a9826b2fb1a534568c5742789ca2c0812d465/duckdb-1.3.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "7e652b7c8dbdb91a94fd7d543d3e115d24a25aa0791a373a852e20cb7bb21154"}}, + {name = "duckdb-1.3.0-cp310-cp310-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8d/8f/ac97536d4ba130c9ec097c99b88ce4fa2ceb2c90471d4f0312066c1c694d/duckdb-1.3.0-cp310-cp310-macosx_12_0_arm64.whl",hashes = {sha256 = "fc65c1e97aa010359c43c0342ea423e6efa3cb8c8e3f133b0765451ce674e3db"}}, + {name = "duckdb-1.3.0-cp310-cp310-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/db/30/d8a740b91021056b00f6d5c6ce8136f15fbc4a738ff8a9ce0b4a3d29604d/duckdb-1.3.0-cp310-cp310-macosx_12_0_universal2.whl",hashes = {sha256 = "8fc91b629646679e33806342510335ccbbeaf2b823186f0ae829fd48e7a63c66"}}, + {name = "duckdb-1.3.0-cp310-cp310-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/5a/d0/75cdba51cc7f35494d8621267cd6ac8de9a649f12fa64c9a2e2b2892f55b/duckdb-1.3.0-cp310-cp310-macosx_12_0_x86_64.whl",hashes = {sha256 = "1a69b970553fd015c557238d427ef00be3c8ed58c3bc3641aef987e33f8bf614"}}, + {name = "duckdb-1.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/fe/3e/164119d03fabf2851ef36b4cccd1763d7950aadea2466cbf0e568e7de9fe/duckdb-1.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1003e84c07b84680cee6d06e4795b6e861892474704f7972058594a52c7473cf"}}, + {name = "duckdb-1.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/27/a5a21c73eea6dbc207a426f13c23358712e444ba4ce9f4fa7e8cb3f73a09/duckdb-1.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "992239b54ca6f015ad0ed0d80f3492c065313c4641df0a226183b8860cb7f5b0"}}, + {name = "duckdb-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f7/e4/5ac11e11fec8cef4780b3867c0bda258650444a46793827a0ab473765853/duckdb-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0ba1c5af59e8147216149b814b1970b8f7e3c240494a9688171390db3c504b29"}}, + {name = "duckdb-1.3.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/68/89/57c0812d9d9c899b0986a1ec1c80a91ea9056bc9a718777caae42ae3a0a2/duckdb-1.3.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "57b794ca28e22b23bd170506cb1d4704a3608e67f0fe33273db9777b69bdf26a"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + [[packages]] name = "httpx-folio" version = "0.3.0" @@ -525,11 +537,11 @@ dependencies = [] [[packages]] name = "httpx-retries" -version = "0.4.5" +version = "0.4.6" requires-python = ">=3.9" -sdist = {name = "httpx_retries-0.4.5.tar.gz", url = "https://files.pythonhosted.org/packages/22/40/b9b5e4c16fb86d2999840bb795b28670a61856c7f48f030530b412bf4133/httpx_retries-0.4.5.tar.gz", hashes = {sha256 = "acee306d7384eefad71ac12fefe8b13d7b41c19595c538e68d9bd7e40e59539d"}} +sdist = {name = "httpx_retries-0.4.6.tar.gz", url = "https://files.pythonhosted.org/packages/a4/13/5eac2df576c02280f79e4639a6d4c93a25cfe94458275f5aa55f5e6c8ea0/httpx_retries-0.4.6.tar.gz", hashes = {sha256 = "a076d8a5ede5d5794e9c241da17b15b393b482129ddd2fdf1fa56a3fa1f28a7f"}} wheels = [ - {name = "httpx_retries-0.4.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/0a/2626b5a2678f8072ba3174d3e40f81429fdc41d1cb993280dbc7ba3c4e3f/httpx_retries-0.4.5-py3-none-any.whl",hashes = {sha256 = "ae22d6ef197a2da49242246a01d721474cbd6516b1fef155f6da694ee410bb37"}}, + {name = "httpx_retries-0.4.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f2/97/63f56da4400034adde22adfe7524635dba068f17d6858f92ecd96f55b53e/httpx_retries-0.4.6-py3-none-any.whl",hashes = {sha256 = "d66d912173b844e065ffb109345a453b922f4c2cd9c9e11139304cb33e7a1ee1"}}, ] marker = "\"default\" in dependency_groups" @@ -662,11 +674,11 @@ dependencies = [] [[packages]] name = "certifi" -version = "2026.1.4" +version = "2026.2.25" requires-python = ">=3.7" -sdist = {name = "certifi-2026.1.4.tar.gz", url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hashes = {sha256 = "ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}} +sdist = {name = "certifi-2026.2.25.tar.gz", url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hashes = {sha256 = "e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"}} wheels = [ - {name = "certifi-2026.1.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl",hashes = {sha256 = "9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}}, + {name = "certifi-2026.2.25-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl",hashes = {sha256 = "027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"}}, ] marker = "\"default\" in dependency_groups" @@ -703,7 +715,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "0c0e9208d38f65d8253d8fa6094d6d32dd41f91a12e3ab69ff765e694312f812"} +hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} strategy = ["direct_minimal_versions", "inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.toml b/pylock.toml index 56be3e9..fb6f477 100644 --- a/pylock.toml +++ b/pylock.toml @@ -104,46 +104,6 @@ marker = "\"lint\" in dependency_groups" [packages.tool.pdm] dependencies = [] -[[packages]] -name = "duckdb" -version = "1.3.2" -requires-python = ">=3.7.0" -sdist = {name = "duckdb-1.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/47/24/a2e7fb78fba577641c286fe33185789ab1e1569ccdf4d142e005995991d2/duckdb-1.3.2.tar.gz", hashes = {sha256 = "c658df8a1bc78704f702ad0d954d82a1edd4518d7a04f00027ec53e40f591ff5"}} -wheels = [ - {name = "duckdb-1.3.2-cp313-cp313-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/f0/8cac9713735864899e8abc4065bbdb3d1617f2130006d508a80e1b1a6c53/duckdb-1.3.2-cp313-cp313-macosx_12_0_arm64.whl",hashes = {sha256 = "a3418c973b06ac4e97f178f803e032c30c9a9f56a3e3b43a866f33223dfbf60b"}}, - {name = "duckdb-1.3.2-cp313-cp313-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/c5/26/6698bbb30b7bce8b8b17697599f1517611c61e4bd68b37eaeaf4f5ddd915/duckdb-1.3.2-cp313-cp313-macosx_12_0_universal2.whl",hashes = {sha256 = "2a741eae2cf110fd2223eeebe4151e22c0c02803e1cfac6880dbe8a39fecab6a"}}, - {name = "duckdb-1.3.2-cp313-cp313-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/10/75/8ab4da3099a2fac7335ecebce4246706d19bdd5dad167aa436b5b27c43c4/duckdb-1.3.2-cp313-cp313-macosx_12_0_x86_64.whl",hashes = {sha256 = "51e62541341ea1a9e31f0f1ade2496a39b742caf513bebd52396f42ddd6525a0"}}, - {name = "duckdb-1.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/d1/46/af81b10d4a66a0f27c248df296d1b41ff2a305a235ed8488f93240f6f8b5/duckdb-1.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b3e519de5640e5671f1731b3ae6b496e0ed7e4de4a1c25c7a2f34c991ab64d71"}}, - {name = "duckdb-1.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/68/fc/259a54fc22111a847981927aa58528d766e8b228c6d41deb0ad8a1959f9f/duckdb-1.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4732fb8cc60566b60e7e53b8c19972cb5ed12d285147a3063b16cc64a79f6d9f"}}, - {name = "duckdb-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ab/dc/5d5140383e40661173dacdceaddee2a97c3f6721a5e8d76e08258110595e/duckdb-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "97f7a22dcaa1cca889d12c3dc43a999468375cdb6f6fe56edf840e062d4a8293"}}, - {name = "duckdb-1.3.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/51/c9/2fcd86ab7530a5b6caff42dbe516ce7a86277e12c499d1c1f5acd266ffb2/duckdb-1.3.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "cd3d717bf9c49ef4b1016c2216517572258fa645c2923e91c5234053defa3fb5"}}, - {name = "duckdb-1.3.2-cp312-cp312-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6c/5d/77f15528857c2b186ebec07778dc199ccc04aafb69fb7b15227af4f19ac9/duckdb-1.3.2-cp312-cp312-macosx_12_0_arm64.whl",hashes = {sha256 = "2455b1ffef4e3d3c7ef8b806977c0e3973c10ec85aa28f08c993ab7f2598e8dd"}}, - {name = "duckdb-1.3.2-cp312-cp312-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/78/67/7e4964f688b846676c813a4acc527cd3454be8a9cafa10f3a9aa78d0d165/duckdb-1.3.2-cp312-cp312-macosx_12_0_universal2.whl",hashes = {sha256 = "9d0ae509713da3461c000af27496d5413f839d26111d2a609242d9d17b37d464"}}, - {name = "duckdb-1.3.2-cp312-cp312-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/95/3d/2d7f8078194130dbf30b5ae154ce454bfc208c91aa5f3e802531a3e09bca/duckdb-1.3.2-cp312-cp312-macosx_12_0_x86_64.whl",hashes = {sha256 = "72ca6143d23c0bf6426396400f01fcbe4785ad9ceec771bd9a4acc5b5ef9a075"}}, - {name = "duckdb-1.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/cd/05/36ff9000b9c6d2a68c1b248f133ee316fcac10c0ff817112cbf5214dbe91/duckdb-1.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b49a11afba36b98436db83770df10faa03ebded06514cb9b180b513d8be7f392"}}, - {name = "duckdb-1.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/ac/73/f85acbb3ac319a86abbf6b46103d58594d73529123377219980f11b388e9/duckdb-1.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "36abdfe0d1704fe09b08d233165f312dad7d7d0ecaaca5fb3bb869f4838a2d0b"}}, - {name = "duckdb-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/32/40/9aa3267f3631ae06b30fb1045a48628f4dba7beb2efb485c0282b4a73367/duckdb-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3380aae1c4f2af3f37b0bf223fabd62077dd0493c84ef441e69b45167188e7b6"}}, - {name = "duckdb-1.3.2-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8c/8d/47bf95f6999b327cf4da677e150cfce802abf9057b61a93a1f91e89d748c/duckdb-1.3.2-cp312-cp312-win_amd64.whl",hashes = {sha256 = "11af73963ae174aafd90ea45fb0317f1b2e28a7f1d9902819d47c67cc957d49c"}}, - {name = "duckdb-1.3.2-cp311-cp311-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/38/16/4cde40c37dd1f48d2f9ffa63027e8b668391c5cc32cbb59f7ca8b1cec6e2/duckdb-1.3.2-cp311-cp311-macosx_12_0_arm64.whl",hashes = {sha256 = "e1872cf63aae28c3f1dc2e19b5e23940339fc39fb3425a06196c5d00a8d01040"}}, - {name = "duckdb-1.3.2-cp311-cp311-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/22/ca/9ca65db51868604007114a27cc7d44864d89328ad6a934668626618147ff/duckdb-1.3.2-cp311-cp311-macosx_12_0_universal2.whl",hashes = {sha256 = "db256c206056468ae6a9e931776bdf7debaffc58e19a0ff4fa9e7e1e82d38b3b"}}, - {name = "duckdb-1.3.2-cp311-cp311-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/9e/ca/7f7cf01dd7731d358632fb516521f2962070a627558fb6fc3137e594bbaa/duckdb-1.3.2-cp311-cp311-macosx_12_0_x86_64.whl",hashes = {sha256 = "1d57df2149d6e4e0bd5198689316c5e2ceec7f6ac0a9ec11bc2b216502a57b34"}}, - {name = "duckdb-1.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/4c/7f/38e518b8f51299410dcad9f1e99f1c99f3592516581467a2da344d3b5951/duckdb-1.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "54f76c8b1e2a19dfe194027894209ce9ddb073fd9db69af729a524d2860e4680"}}, - {name = "duckdb-1.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/90/a3/41f3d42fddd9629846aac328eb295170e76782d8dfc5e58b3584b96fa296/duckdb-1.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "45bea70b3e93c6bf766ce2f80fc3876efa94c4ee4de72036417a7bd1e32142fe"}}, - {name = "duckdb-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/11/8e/c5444b6890ae7f00836fd0cd17799abbcc3066bbab32e90b04aa8a8a5087/duckdb-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "003f7d36f0d8a430cb0e00521f18b7d5ee49ec98aaa541914c6d0e008c306f1a"}}, - {name = "duckdb-1.3.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/87/a1/e240bd07671542ddf2084962e68a7d5c9b068d8da3f938e935af69441355/duckdb-1.3.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "0eb210cedf08b067fa90c666339688f1c874844a54708562282bc54b0189aac6"}}, - {name = "duckdb-1.3.2-cp310-cp310-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6a/a0/13f45e67565800826ce0af12a0ab68fe9502dcac0e39bc03bf8a8cba61da/duckdb-1.3.2-cp310-cp310-macosx_12_0_arm64.whl",hashes = {sha256 = "14676651b86f827ea10bf965eec698b18e3519fdc6266d4ca849f5af7a8c315e"}}, - {name = "duckdb-1.3.2-cp310-cp310-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/ec/28/daf9c01b5cb4058fc80070c74284c52f11581c888db2b0e73ca48f9bae23/duckdb-1.3.2-cp310-cp310-macosx_12_0_universal2.whl",hashes = {sha256 = "e584f25892450757919639b148c2410402b17105bd404017a57fa9eec9c98919"}}, - {name = "duckdb-1.3.2-cp310-cp310-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/77/e0/5b50014d92eb6c879608183f6184186ab2cf324dd33e432174af93d19a44/duckdb-1.3.2-cp310-cp310-macosx_12_0_x86_64.whl",hashes = {sha256 = "84a19f185ee0c5bc66d95908c6be19103e184b743e594e005dee6f84118dc22c"}}, - {name = "duckdb-1.3.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a2/ff/291d74f8b4c988b2a7ee5f65d3073fe0cf4c6a4505aa1a6f28721bb2ebe2/duckdb-1.3.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "186fc3f98943e97f88a1e501d5720b11214695571f2c74745d6e300b18bef80e"}}, - {name = "duckdb-1.3.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/65/50/9a1289619447d93a8c63b08f6ab22e1e6ce73a681e0dceb0cd0ea7558613/duckdb-1.3.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6b7e6bb613b73745f03bff4bb412f362d4a1e158bdcb3946f61fd18e9e1a8ddf"}}, - {name = "duckdb-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e0/d1/8dc959e3ca16c4c32ab34e28ceea189edc9bf32523aaa976080fd2101835/duckdb-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1c90646b52a0eccda1f76b10ac98b502deb9017569e84073da00a2ab97763578"}}, - {name = "duckdb-1.3.2-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7b/e8/126767fe5acbe01230f7431d999a2c2ef028ffdaebda8fe32ddb57628815/duckdb-1.3.2-cp310-cp310-win_amd64.whl",hashes = {sha256 = "4cdffb1e60defbfa75407b7f2ccc322f535fd462976940731dfd1644146f90c6"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - [[packages]] name = "coverage" version = "7.13.4" @@ -261,6 +221,52 @@ marker = "\"test\" in dependency_groups" [packages.tool.pdm] dependencies = [] +[[packages]] +name = "duckdb" +version = "1.4.4" +requires-python = ">=3.9.0" +sdist = {name = "duckdb-1.4.4.tar.gz", url = "https://files.pythonhosted.org/packages/36/9d/ab66a06e416d71b7bdcb9904cdf8d4db3379ef632bb8e9495646702d9718/duckdb-1.4.4.tar.gz", hashes = {sha256 = "8bba52fd2acb67668a4615ee17ee51814124223de836d9e2fdcbc4c9021b3d3c"}} +wheels = [ + {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/97/a6/f19e2864e651b0bd8e4db2b0c455e7e0d71e0d4cd2cd9cc052f518e43eb3/duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "25874f8b1355e96178079e37312c3ba6d61a2354f51319dae860cf21335c3a20"}}, + {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/0e/93/8a24e932c67414fd2c45bed83218e62b73348996bf859eda020c224774b2/duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "452c5b5d6c349dc5d1154eb2062ee547296fcbd0c20e9df1ed00b5e1809089da"}}, + {name = "duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/62/13/e5378ff5bb1d4397655d840b34b642b1b23cdd82ae19599e62dc4b9461c9/duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8e5c2d8a0452df55e092959c0bfc8ab8897ac3ea0f754cb3b0ab3e165cd79aff"}}, + {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2d/94/24364da564b27aeebe44481f15bd0197a0b535ec93f188a6b1b98c22f082/duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1af6e76fe8bd24875dc56dd8e38300d64dc708cd2e772f67b9fbc635cc3066a3"}}, + {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/0a/6ae31b2914b4dc34243279b2301554bcbc5f1a09ccc82600486c49ab71d1/duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d0440f59e0cd9936a9ebfcf7a13312eda480c79214ffed3878d75947fc3b7d6d"}}, + {name = "duckdb-1.4.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d2/b1/fd5c37c53d45efe979f67e9bd49aaceef640147bb18f0699a19edd1874d6/duckdb-1.4.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "59c8d76016dde854beab844935b1ec31de358d4053e792988108e995b18c08e7"}}, + {name = "duckdb-1.4.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/2d/13e6024e613679d8a489dd922f199ef4b1d08a456a58eadd96dc2f05171f/duckdb-1.4.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "53cd6423136ab44383ec9955aefe7599b3fb3dd1fe006161e6396d8167e0e0d4"}}, + {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/7f/fe/64810fee20030f2bf96ce28b527060564864ce5b934b50888eda2cbf99dd/duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "337f8b24e89bc2e12dadcfe87b4eb1c00fd920f68ab07bc9b70960d6523b8bc3"}}, + {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9c/9b/3c7c5e48456b69365d952ac201666053de2700f5b0144a699a4dc6854507/duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "0509b39ea7af8cff0198a99d206dca753c62844adab54e545984c2e2c1381616"}}, + {name = "duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a6/7b/64e68a7b857ed0340045501535a0da99ea5d9d5ea3708fec0afb8663eb27/duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "fb94de6d023de9d79b7edc1ae07ee1d0b4f5fa8a9dcec799650b5befdf7aafec"}}, + {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/09/5b/3e7aa490841784d223de61beb2ae64e82331501bf5a415dc87a0e27b4663/duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0d636ceda422e7babd5e2f7275f6a0d1a3405e6a01873f00d38b72118d30c10b"}}, + {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/53/32/256df3dbaa198c58539ad94f9a41e98c2c8ff23f126b8f5f52c7dcd0a738/duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "7df7351328ffb812a4a289732f500d621e7de9942a3a2c9b6d4afcf4c0e72526"}}, + {name = "duckdb-1.4.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a4/f0/620323fd87062ea43e527a2d5ed9e55b525e0847c17d3b307094ddab98a2/duckdb-1.4.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "6fb1225a9ea5877421481d59a6c556a9532c32c16c7ae6ca8d127e2b878c9389"}}, + {name = "duckdb-1.4.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/07/a397fdb7c95388ba9c055b9a3d38dfee92093f4427bc6946cf9543b1d216/duckdb-1.4.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "f28a18cc790217e5b347bb91b2cab27aafc557c58d3d8382e04b4fe55d0c3f66"}}, + {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/58/33/beadaa69f8458afe466126f2c5ee48c4759cc9d5d784f8703d44e0b52c3c/duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "ddcfd9c6ff234da603a1edd5fd8ae6107f4d042f74951b65f91bc5e2643856b3"}}, + {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/66/82413f386df10467affc87f65bac095b7c88dbd9c767584164d5f4dc4cb8/duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "6792ca647216bd5c4ff16396e4591cfa9b4a72e5ad7cdd312cec6d67e8431a7c"}}, + {name = "duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/8c/c13d396fd4e9bf970916dc5b4fea410c1b10fe531069aea65f1dcf849a71/duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "1f8d55843cc940e36261689054f7dfb6ce35b1f5b0953b0d355b6adb654b0d52"}}, + {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/77/2446a0b44226bb95217748d911c7ca66a66ca10f6481d5178d9370819631/duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c65d15c440c31e06baaebfd2c06d71ce877e132779d309f1edf0a85d23c07e92"}}, + {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/2e/a3/97715bba30040572fb15d02c26f36be988d48bc00501e7ac02b1d65ef9d0/duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "b297eff642503fd435a9de5a9cb7db4eccb6f61d61a55b30d2636023f149855f"}}, + {name = "duckdb-1.4.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/0a/18b9167adf528cbe3867ef8a84a5f19f37bedccb606a8a9e59cfea1880c8/duckdb-1.4.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d525de5f282b03aa8be6db86b1abffdceae5f1055113a03d5b50cd2fb8cf2ef8"}}, + {name = "duckdb-1.4.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f8/15/37af97f5717818f3d82d57414299c293b321ac83e048c0a90bb8b6a09072/duckdb-1.4.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "50f2eb173c573811b44aba51176da7a4e5c487113982be6a6a1c37337ec5fa57"}}, + {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/04/68/19233412033a2bc5a144a3f531f64e3548d4487251e3f16b56c31411a06f/duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5ba684f498d4e924c7e8f30dd157da8da34c8479746c5011b6c0e037e9c60ad2"}}, + {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b3/3e/cec70e546c298ab76d80b990109e111068d82cca67942c42328eaa7d6fdb/duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "5536eb952a8aa6ae56469362e344d4e6403cc945a80bc8c5c2ebdd85d85eb64b"}}, + {name = "duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/f0/cf4241a040ec4f571859a738007ec773b642fbc27df4cbcf34b0c32ea559/duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "47dd4162da6a2be59a0aef640eb08d6360df1cf83c317dcc127836daaf3b7f7c"}}, + {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/11/64/de2bb4ec1e35ec9ebf6090a95b930fc56934a0ad6f34a24c5972a14a77ef/duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6cb357cfa3403910e79e2eb46c8e445bb1ee2fd62e9e9588c6b999df4256abc1"}}, + {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/a2/ac0f5ee16df890d141304bcd48733516b7202c0de34cd3555634d6eb4551/duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4c25d5b0febda02b7944e94fdae95aecf952797afc8cb920f677b46a7c251955"}}, + {name = "duckdb-1.4.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/37/a2/9a3402edeedaecf72de05fe9ff7f0303d701b8dfc136aea4a4be1a5f7eee/duckdb-1.4.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6703dd1bb650025b3771552333d305d62ddd7ff182de121483d4e042ea6e2e00"}}, + {name = "duckdb-1.4.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f6/e6/052ea6dcdf35b259fd182eff3efd8d75a071de4010c9807556098df137b9/duckdb-1.4.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bf138201f56e5d6fc276a25138341b3523e2f84733613fc43f02c54465619a95"}}, + {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/a2/9f/67a75f1e88f84946909826fa7aadd0c4b0dc067f24956142751fd9d59fe6/duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "e870a441cb1c41d556205deb665749f26347ed13b3a247b53714f5d589596977"}}, + {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/6b/7a/e9277d0567884c21f345ad43cc01aeaa2abe566d5fdf22e35c3861dd44fa/duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "49123b579e4a6323e65139210cd72dddc593a72d840211556b60f9703bda8526"}}, + {name = "duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/96/3a7630d2779d2bae6f3cdf540a088ed45166adefd3c429971e5b85ce8f84/duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "5e1933fac5293fea5926b0ee75a55b8cfe7f516d867310a5b251831ab61fe62b"}}, + {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/ad/f62a3a65d200e8afc1f75cf0dd3f0aa84ef0dd07c484414a11f2abed810e/duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "707530f6637e91dc4b8125260595299ec9dd157c09f5d16c4186c5988bfbd09a"}}, + {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/5f/23bd586ecb21273b41b5aa4b16fd88b7fecb53ed48d897273651c0c3d66f/duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "453b115f4777467f35103d8081770ac2f223fb5799178db5b06186e3ab51d1f2"}}, + {name = "duckdb-1.4.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/d0/4ce78bf341c930d4a22a56cb686bfc2c975eaf25f653a7ac25e3929d98bb/duckdb-1.4.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "a3c8542db7ffb128aceb7f3b35502ebaddcd4f73f1227569306cc34bad06680c"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + [[packages]] name = "httpx-folio" version = "0.3.0" @@ -364,11 +370,11 @@ dependencies = [] [[packages]] name = "psycopg" -version = "3.3.2" +version = "3.3.3" requires-python = ">=3.10" -sdist = {name = "psycopg-3.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/e0/1a/7d9ef4fdc13ef7f15b934c393edc97a35c281bb7d3c3329fbfcbe915a7c2/psycopg-3.3.2.tar.gz", hashes = {sha256 = "707a67975ee214d200511177a6a80e56e654754c9afca06a7194ea6bbfde9ca7"}} +sdist = {name = "psycopg-3.3.3.tar.gz", url = "https://files.pythonhosted.org/packages/d3/b6/379d0a960f8f435ec78720462fd94c4863e7a31237cf81bf76d0af5883bf/psycopg-3.3.3.tar.gz", hashes = {sha256 = "5e9a47458b3c1583326513b2556a2a9473a1001a56c9efe9e587245b43148dd9"}} wheels = [ - {name = "psycopg-3.3.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8c/51/2779ccdf9305981a06b21a6b27e8547c948d85c41c76ff434192784a4c93/psycopg-3.3.2-py3-none-any.whl",hashes = {sha256 = "3e94bc5f4690247d734599af56e51bae8e0db8e4311ea413f801fef82b14a99b"}}, + {name = "psycopg-3.3.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c8/5b/181e2e3becb7672b502f0ed7f16ed7352aca7c109cfb94cf3878a9186db9/psycopg-3.3.3-py3-none-any.whl",hashes = {sha256 = "f96525a72bcfade6584ab17e89de415ff360748c766f0106959144dcbb38c698"}}, ] marker = "\"default\" in dependency_groups" @@ -608,11 +614,11 @@ dependencies = [] [[packages]] name = "httpx-retries" -version = "0.4.5" +version = "0.4.6" requires-python = ">=3.9" -sdist = {name = "httpx_retries-0.4.5.tar.gz", url = "https://files.pythonhosted.org/packages/22/40/b9b5e4c16fb86d2999840bb795b28670a61856c7f48f030530b412bf4133/httpx_retries-0.4.5.tar.gz", hashes = {sha256 = "acee306d7384eefad71ac12fefe8b13d7b41c19595c538e68d9bd7e40e59539d"}} +sdist = {name = "httpx_retries-0.4.6.tar.gz", url = "https://files.pythonhosted.org/packages/a4/13/5eac2df576c02280f79e4639a6d4c93a25cfe94458275f5aa55f5e6c8ea0/httpx_retries-0.4.6.tar.gz", hashes = {sha256 = "a076d8a5ede5d5794e9c241da17b15b393b482129ddd2fdf1fa56a3fa1f28a7f"}} wheels = [ - {name = "httpx_retries-0.4.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/0a/2626b5a2678f8072ba3174d3e40f81429fdc41d1cb993280dbc7ba3c4e3f/httpx_retries-0.4.5-py3-none-any.whl",hashes = {sha256 = "ae22d6ef197a2da49242246a01d721474cbd6516b1fef155f6da694ee410bb37"}}, + {name = "httpx_retries-0.4.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f2/97/63f56da4400034adde22adfe7524635dba068f17d6858f92ecd96f55b53e/httpx_retries-0.4.6-py3-none-any.whl",hashes = {sha256 = "d66d912173b844e065ffb109345a453b922f4c2cd9c9e11139304cb33e7a1ee1"}}, ] marker = "\"default\" in dependency_groups" @@ -745,11 +751,11 @@ dependencies = [] [[packages]] name = "certifi" -version = "2026.1.4" +version = "2026.2.25" requires-python = ">=3.7" -sdist = {name = "certifi-2026.1.4.tar.gz", url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hashes = {sha256 = "ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}} +sdist = {name = "certifi-2026.2.25.tar.gz", url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hashes = {sha256 = "e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"}} wheels = [ - {name = "certifi-2026.1.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl",hashes = {sha256 = "9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}}, + {name = "certifi-2026.2.25-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl",hashes = {sha256 = "027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"}}, ] marker = "\"default\" in dependency_groups" @@ -814,7 +820,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "0c0e9208d38f65d8253d8fa6094d6d32dd41f91a12e3ab69ff765e694312f812"} +hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pyproject.toml b/pyproject.toml index 91ddeb8..e5a780e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,9 +11,8 @@ authors = [ { name = "Nassib Nassar", email = "nassib@indexdata.com" }, ] dependencies = [ - # Versions lower than 0.9 have issues binding the custom functions - # 1.4 has a number of regressions so I'm letting it shake out until some fixes - "duckdb>=0.9.2,<1.4", + # 1.3 introduces json each + "duckdb>=1.3", # 4.64 is the first release with type stubs "tqdm>=4.64.0", # 0.3 allows checking the path for id based paging @@ -67,6 +66,9 @@ include = ["src/**"] distribution = true package-dir = "src" +[tool.pdm.resolution] +allow-prereleases = false + [tool.pdm.scripts] test.composite = [ "rm -f .coverage", @@ -76,7 +78,8 @@ test.composite = [ lock.composite = [ "rm -f pylock.toml pylock.maximal.toml pylock.minimal.toml", "pdm lock --python=3.10", - "pdm lock --lockfile pylock.maximal.toml --python=3.13", + "cp pylock.toml pylock.lint.toml", + "pdm lock --lockfile pylock.maximal.toml --python=3.14", "pdm lock --strategy direct_minimal_versions --lockfile pylock.minimal.toml --python=3.10", ] test-install.composite = [ diff --git a/src/ldlite/_csv.py b/src/ldlite/_csv.py index 4afec9d..dbe8eca 100644 --- a/src/ldlite/_csv.py +++ b/src/ldlite/_csv.py @@ -64,6 +64,7 @@ def to_csv( s += "," if attrs[i][1] in [ "NUMBER", + "DECIMAL(18,3)", "bigint", "numeric", 20, diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index a11045e..c0a913a 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -24,13 +24,6 @@ def __init__(self, db: duckdb.DuckDBPyConnection) -> None: @staticmethod def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: - with conn.cursor() as cur: - cur.execute("SELECT string_split(ltrim(version(),'v'), '.') AS has_lambda;") - if ver := cur.fetchone(): - (ma, mi, _) = ver[0] - if int(ma) > 1 and int(mi) >= 3: - cur.execute("SET lambda_syntax = 'ENABLE_SINGLE_ARROW';") - with conn.cursor() as cur: cur.execute( r""" @@ -63,8 +56,8 @@ def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: END WHEN 'array' THEN CASE - WHEN length(list_filter((main.json_extract(j, p))::JSON[], x -> x != 'null'::JSON)) = 0 THEN 'null'::JSON - ELSE list_filter((main.json_extract(j, p))::JSON[], x -> x != 'null'::JSON) + WHEN length(list_filter((main.json_extract(j, p))::JSON[], lambda x : x != 'null'::JSON)) = 0 THEN 'null'::JSON + ELSE list_filter((main.json_extract(j, p))::JSON[], lambda x : x != 'null'::JSON) END ELSE coalesce(main.json_extract(j, p), 'null'::JSON) END diff --git a/tests/test_expansion.py b/tests/test_expansion.py index 33421ae..bcb62b7 100644 --- a/tests/test_expansion.py +++ b/tests/test_expansion.py @@ -218,17 +218,32 @@ def case_basic_array() -> ExpansionTC: Assertion("""SELECT COUNT(*) FROM tests.prefix__t__list2""", expect=2), Assertion( """ -SELECT id, list1_o, list1 +SELECT id, list1 +FROM tests.prefix__t__list1 +ORDER BY id, list1 + """, + expect=[ + ("id1", "a1"), + ("id1", "b1"), + ("id1", "c1"), + ("id2", "a2"), + ("id2", "b2"), + ("id2", "c2"), + ], + ), + Assertion( + """ +SELECT id, list1_o FROM tests.prefix__t__list1 ORDER BY id, list1_o """, expect=[ - ("id1", 1, "a1"), - ("id1", 2, "b1"), - ("id1", 3, "c1"), - ("id2", 1, "a2"), - ("id2", 2, "b2"), - ("id2", 3, "c2"), + ("id1", 1), + ("id1", 2), + ("id1", 3), + ("id2", 1), + ("id2", 2), + ("id2", 3), ], ), *[ @@ -281,15 +296,28 @@ def case_nested_arrays() -> ExpansionTC: Assertion("""SELECT COUNT(*) FROM tests.prefix__t__sub""", expect=4), Assertion( """ -SELECT id, sub_o, sub__id +SELECT id, sub__id +FROM tests.prefix__t__sub +ORDER BY id, sub__id + """, + expect=[ + ("id1", "sub1id1"), + ("id1", "sub2id1"), + ("id2", "sub1id2"), + ("id2", "sub2id2"), + ], + ), + Assertion( + """ +SELECT id, sub_o FROM tests.prefix__t__sub ORDER BY id, sub_o """, expect=[ - ("id1", 1, "sub1id1"), - ("id1", 2, "sub2id1"), - ("id2", 1, "sub1id2"), - ("id2", 2, "sub2id2"), + ("id1", 1), + ("id1", 2), + ("id2", 1), + ("id2", 2), ], ), Assertion( diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index 995964c..29aaf3d 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -7,7 +7,7 @@ import duckdb import psycopg import pytest -from pytest_cases import parametrize, parametrize_with_cases +from pytest_cases import get_case_id, parametrize, parametrize_with_cases if TYPE_CHECKING: from _typeshed import dbapi @@ -38,9 +38,6 @@ class JsonTC: ("obj_some", '{"k1":"v1","k2":null}'), ("obj_empty", "null"), ("arr_zero", "null"), - ("arr_str", '["s1","s2","s3"]'), - ("arr_str_some", '["s1","s2"]'), - ("arr_obj_some", '[{"k1":"v1"}]'), ("na", "null"), ("na_str1", "null"), ("na_str2", "null"), @@ -55,6 +52,43 @@ def case_jextract(p: tuple[Any, ...]) -> JsonTC: ) +# Duckdb through 1.3 and 1.4 have different json comparison behavior here +# Whitespace matters in 1.4 and not 1.3 +# This makes the arrays text and compares the values as a workaround +@parametrize( + p=[ + ("arr_str", '["s1", "s2", "s3"]'), + ("arr_str_some", '["s1", "s2"]'), + ("arr_obj_some", '[{"k1":"v1"}]'), + ], +) +def case_jextract_duckdb(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """SELECT ldlite_system.jextract(jc, $1){assertion} FROM j;""", + p[:1], + """::text[] = $2::JSON::text[]""", + p[1:], + ) + + +# The differences betweeen postgres/duckdb here only matters for tests +# This can all be rectified when duckdb 1.4 is the minimum version +@parametrize( + p=[ + ("arr_str", '["s1", "s2", "s3"]'), + ("arr_str_some", '["s1", "s2"]'), + ("arr_obj_some", '[{"k1":"v1"}]'), + ], +) +def case_jextract_postgres(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """SELECT ldlite_system.jextract(jc, $1){assertion} FROM j;""", + p[:1], + """ = $2::JSONB""", + p[1:], + ) + + @parametrize( p=[ ("str", "str_val"), @@ -293,7 +327,11 @@ def duckdb_jop_dsn() -> Iterator[str]: yield dsn -@parametrize_with_cases("tc", cases=".") +@parametrize_with_cases( + "tc", + cases=".", + filter=lambda cf: "postgres" not in get_case_id(cf), +) def test_duckdb(duckdb_jop_dsn: str, tc: JsonTC) -> None: from ldlite import LDLite @@ -316,7 +354,11 @@ def pg_jop_dsn(pg_dsn: None | Callable[[str], str]) -> str: return dsn -@parametrize_with_cases("tc", cases=".") +@parametrize_with_cases( + "tc", + cases=".", + filter=lambda cf: "duckdb" not in get_case_id(cf), +) def test_postgres(pg_jop_dsn: str, tc: JsonTC) -> None: from ldlite import LDLite From 493b5fcf0da587ed74f85fd9aada2db5a6ed42fe Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Wed, 4 Mar 2026 14:30:06 -0500 Subject: [PATCH 15/25] Switch LDLite to using the new server side transform (#66) This switches LDLite to using the new transform. The legacy transform is still available by using a parameter passed to the query method. After making the switch and testing with both the unit tests and against Five Colleges production instance a number of regressions were found and fixed. While testing against the production instance the load_history table proved to be a thorn in my side and the v1 was added in lieu of actually using a migration framework for it. * The catalog table was never implemented * The array index column was misnamed * Booleans weren't created as boolean columns * The column named "value" used during expansion conflicted with underlying column names * The columns in the output tables were ordered in a random way * Fields that started with caps would get an underscore at the front of their column name Indexing for the new transformation will be implemented in the next PR. In testing, this implementation runs out of memory for large tables with large objects. I've experimented with fixes and there will be a follow up performance PR to address this issue. --- src/ldlite/__init__.py | 152 +++++++++++---------- src/ldlite/database/__init__.py | 2 +- src/ldlite/database/_duckdb.py | 4 +- src/ldlite/database/_expansion/__init__.py | 29 ++-- src/ldlite/database/_expansion/metadata.py | 8 +- src/ldlite/database/_expansion/nodes.py | 38 +++--- src/ldlite/database/_postgres.py | 4 +- src/ldlite/database/_prefix.py | 37 +++-- src/ldlite/database/_typed_database.py | 60 +++++--- tests/test___init__.py | 14 ++ tests/test_drop_tables.py | 16 +-- tests/test_expansion.py | 67 +++++++-- tests/test_json_operators.py | 4 +- tests/test_load_history.py | 5 +- tests/test_query.py | 35 +++-- 15 files changed, 299 insertions(+), 176 deletions(-) diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 42d3cf0..1cf80ac 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -250,6 +250,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 limit: int | None = None, transform: bool | None = None, keep_raw: bool = True, + use_legacy_transform: bool = False, ) -> list[str]: """Submits a query to a FOLIO module, and transforms and stores the result. @@ -279,6 +280,9 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 If *keep_raw* is set to False, then the raw table of __id, json will be dropped saving an estimated 20% disk space. + *use_legacy_transform* will use the pre 4.0 transformation logic. + This parameter is deprecated and will not function in a future release. + The *transform* parameter is no longer supported and will be removed in the future. Instead, specify *json_depth* as 0 to disable JSON transformation. @@ -307,70 +311,88 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 start = datetime.now(timezone.utc) if not self._quiet: print("ldlite: querying: " + path, file=sys.stderr) - try: - (total_records, records) = self._folio.iterate_records( - path, - self._okapi_timeout, - self._okapi_max_retries, - self.page_size, - query=cast("QueryType", query), - ) - if limit is not None: - total_records = min(total_records, limit) - records = (x for _, x in zip(range(limit), records, strict=False)) - if self._verbose: - print( - "ldlite: estimated row count: " + str(total_records), - file=sys.stderr, - ) - download_started = datetime.now(timezone.utc) - processed = self._database.ingest_records( - table, - cast( - "Iterator[bytes]", - tqdm( - records, - desc="downloading", - total=total_records, - leave=False, - mininterval=5, - disable=self._quiet, - unit=table.split(".")[-1], - unit_scale=True, - delay=5, - ), - ), + (total_records, records) = self._folio.iterate_records( + path, + self._okapi_timeout, + self._okapi_max_retries, + self.page_size, + query=cast("QueryType", query), + ) + if limit is not None: + total_records = min(total_records, limit) + records = (x for _, x in zip(range(limit), records, strict=False)) + if self._verbose: + print( + "ldlite: estimated row count: " + str(total_records), + file=sys.stderr, ) - download = datetime.now(timezone.utc) - download_elapsed = datetime.now(timezone.utc) - download_started - - transform_started = datetime.now(timezone.utc) - self._database.drop_extracted_tables(table) - newtables = [table] - newattrs = {} - if json_depth > 0: - autocommit(self.db, self.dbtype, False) - (jsontables, jsonattrs) = transform_json( - self.db, - self.dbtype, - table, - processed, - self._quiet, - json_depth, - ) - newtables += jsontables - newattrs = jsonattrs - for t in newattrs: - newattrs[t]["__id"] = Attr("__id", "bigint") - newattrs[table] = {"__id": Attr("__id", "bigint")} - - if not keep_raw: - self._database.drop_raw_table(table) - transform_elapsed = datetime.now(timezone.utc) - transform_started - finally: - autocommit(self.db, self.dbtype, True) + download_started = datetime.now(timezone.utc) + processed = self._database.ingest_records( + table, + cast( + "Iterator[bytes]", + tqdm( + records, + desc="downloading", + total=total_records, + leave=False, + mininterval=5, + disable=self._quiet, + unit=table.split(".")[-1], + unit_scale=True, + delay=5, + ), + ), + ) + download = datetime.now(timezone.utc) + download_elapsed = datetime.now(timezone.utc) - download_started + + transform_started = datetime.now(timezone.utc) + if not use_legacy_transform: + newtables = self._database.expand_prefix(table, json_depth, keep_raw) + if keep_raw: + newtables = [table, *newtables] + indexable_attrs = [] + + else: + try: + self._database.drop_extracted_tables(table) + newtables = [table] + newattrs = {} + if json_depth > 0: + autocommit(self.db, self.dbtype, False) + (jsontables, jsonattrs) = transform_json( + self.db, + self.dbtype, + table, + processed, + self._quiet, + json_depth, + ) + newtables += jsontables + newattrs = jsonattrs + for t in newattrs: + newattrs[t]["__id"] = Attr("__id", "bigint") + newattrs[table] = {"__id": Attr("__id", "bigint")} + + if not keep_raw: + self._database.drop_raw_table(table) + + indexable_attrs = [ + (t, a) + for t, attrs in newattrs.items() + for n, a in attrs.items() + if n in ["__id", "id"] + or n.endswith(("_id", "__o")) + or a.datatype == "uuid" + ] + + finally: + autocommit(self.db, self.dbtype, True) + + transform_elapsed = datetime.now(timezone.utc) - transform_started # Create indexes on id columns (for postgres) index_started = datetime.now(timezone.utc) if self.dbtype == DBType.POSTGRES: @@ -381,14 +403,6 @@ def close(self) -> None: ... pbar: tqdm | PbarNoop = PbarNoop() # type:ignore[type-arg] - indexable_attrs = [ - (t, a) - for t, attrs in newattrs.items() - for n, a in attrs.items() - if n in ["__id", "id"] - or n.endswith(("_id", "__o")) - or a.datatype == "uuid" - ] index_total = len(indexable_attrs) if not self._quiet: pbar = tqdm( diff --git a/src/ldlite/database/__init__.py b/src/ldlite/database/__init__.py index 1e67fb7..719656c 100644 --- a/src/ldlite/database/__init__.py +++ b/src/ldlite/database/__init__.py @@ -47,7 +47,7 @@ def ingest_records(self, prefix: str, records: Iterator[bytes]) -> int: """Ingests a stream of records dowloaded from FOLIO to the raw table.""" @abstractmethod - def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> None: + def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[str]: """Unnests and explodes the raw data at the given prefix.""" @abstractmethod diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index c0a913a..98ac5bb 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -94,7 +94,7 @@ def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: ; CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j) AS TABLE ( - SELECT value FROM main.json_each(j) + SELECT value as ld_value FROM main.json_each(j) ); """, # noqa: E501 @@ -120,7 +120,7 @@ def ingest_records( insert_sql = ( sql.SQL("INSERT INTO {table} VALUES(?, ?);") - .format(table=pfx.schemafy(pfx.raw_table)) + .format(table=pfx.raw_table.id) .as_string() ) # duckdb has better performance bulk inserting in a transaction diff --git a/src/ldlite/database/_expansion/__init__.py b/src/ldlite/database/_expansion/__init__.py index 0afc37e..d6f8bd5 100644 --- a/src/ldlite/database/_expansion/__init__.py +++ b/src/ldlite/database/_expansion/__init__.py @@ -21,7 +21,7 @@ class ExpandContext: source_table: sql.Identifier json_depth: int get_transform_table: Callable[[int], sql.Identifier] - get_output_table: Callable[[str], sql.Identifier] + get_output_table: Callable[[str], tuple[str, sql.Identifier]] # This is necessary for Analyzing the table in pg before querying it # I don't love how this is implemented preprocess: Callable[ @@ -55,19 +55,20 @@ def expand_nonmarc( root_name: str, root_values: list[str], ctx: ExpandContext, -) -> None: - _expand_nonmarc( +) -> list[str]: + (_, created_tables) = _expand_nonmarc( ObjectNode(root_name, "", None, root_values), 0, ctx, ) + return created_tables def _expand_nonmarc( root: ObjectNode, count: int, ctx: ExpandContext, -) -> int: +) -> tuple[int, list[str]]: initial_count = count ctx.preprocess(ctx.conn, ctx.source_table, [root.identifier]) root.unnest( @@ -95,6 +96,8 @@ def _expand_nonmarc( expand_children_of.append(c) count += 1 + created_tables = [] + new_source_table = ctx.get_transform_table(count) arrays = root.descendents_oftype(ArrayNode) ctx.preprocess(ctx.conn, new_source_table, [a.identifier for a in arrays]) @@ -110,7 +113,7 @@ def _expand_nonmarc( count += 1 if an.meta.is_object: - count += _expand_nonmarc( + (sub_index, array_tables) = _expand_nonmarc( ObjectNode( an.name, an.name, @@ -123,8 +126,12 @@ def _expand_nonmarc( ctx.json_depth - len(an.parents), ), ) + count += sub_index + created_tables.extend(array_tables) else: with ctx.conn.cursor() as cur: + (tname, tid) = ctx.get_output_table(an.name) + created_tables.append(tname) cur.execute( sql.SQL( """ @@ -136,7 +143,7 @@ def _expand_nonmarc( """, ) .format( - dest_table=ctx.get_output_table(an.name), + dest_table=tid, source_table=ctx.get_transform_table(count), cols=sql.SQL("\n ,").join( [sql.Identifier(v) for v in [*values, an.name]], @@ -146,12 +153,12 @@ def _expand_nonmarc( ) stamped_values = [ - sql.Identifier(v) - for n in set(root.descendents).difference(arrays) - for v in n.values + sql.Identifier(v) for n in root.descendents if n not in arrays for v in n.values ] with ctx.conn.cursor() as cur: + (tname, tid) = ctx.get_output_table(root.path) + created_tables.append(tname) cur.execute( sql.SQL( """ @@ -163,11 +170,11 @@ def _expand_nonmarc( """, ) .format( - dest_table=ctx.get_output_table(root.path), + dest_table=tid, source_table=new_source_table, cols=sql.SQL("\n ,").join(stamped_values), ) .as_string(), ) - return count + 1 - initial_count + return (count + 1 - initial_count, created_tables) diff --git a/src/ldlite/database/_expansion/metadata.py b/src/ldlite/database/_expansion/metadata.py index 755cd78..15f75f7 100644 --- a/src/ldlite/database/_expansion/metadata.py +++ b/src/ldlite/database/_expansion/metadata.py @@ -31,7 +31,9 @@ def is_object(self) -> bool: @property def snake(self) -> str: - return "".join("_" + c.lower() if c.isupper() else c for c in self.prop) + return "".join("_" + c.lower() if c.isupper() else c for c in self.prop).lstrip( + "_", + ) def select_column( self, @@ -47,6 +49,10 @@ def select_column( "(ldlite_system.jextract_string({json_col}, {prop}))" "::numeric AS {alias}", ) + elif self.json_type == "boolean": + stmt = sql.SQL( + "(ldlite_system.jextract_string({json_col}, {prop}))::bool AS {alias}", + ) elif self.json_type == "string" and self.is_uuid: stmt = sql.SQL( "(ldlite_system.jextract_string({json_col}, {prop}))::uuid AS {alias}", diff --git a/src/ldlite/database/_expansion/nodes.py b/src/ldlite/database/_expansion/nodes.py index 4b5ab5a..7883f51 100644 --- a/src/ldlite/database/_expansion/nodes.py +++ b/src/ldlite/database/_expansion/nodes.py @@ -142,30 +142,30 @@ def unnest( values AS ( SELECT prop - ,ldlite_system.jextract({json_col}, prop) as value + ,ldlite_system.jextract({json_col}, prop) as ld_value FROM {table}, props ), value_and_types AS ( SELECT prop - ,ldlite_system.jtype_of(value) AS json_type - ,value + ,ldlite_system.jtype_of(ld_value) AS json_type + ,ld_value FROM values - WHERE NOT ldlite_system.jis_null(value) + WHERE NOT ldlite_system.jis_null(ld_value) ), array_values AS ( SELECT v.prop - ,ldlite_system.jtype_of(a.value) AS json_type - ,v.value - FROM value_and_types v, ldlite_system.jexplode(v.value) a + ,ldlite_system.jtype_of(a.ld_value) AS json_type + ,v.ld_value + FROM value_and_types v, ldlite_system.jexplode(v.ld_value) a WHERE v.json_type = 'array' ), all_values AS ( SELECT prop ,json_type - ,value + ,ld_value ,FALSE AS is_array FROM value_and_types WHERE json_type <> 'array' @@ -173,18 +173,18 @@ def unnest( SELECT prop ,json_type - ,value + ,ld_value ,TRUE AS is_array FROM array_values - WHERE NOT ldlite_system.jis_null(value) + WHERE NOT ldlite_system.jis_null(ld_value) ) SELECT prop ,STRING_AGG(DISTINCT json_type, '|') AS json_type ,bool_and(is_array) AS is_array - ,bool_and(ldlite_system.jis_uuid(value)) AS is_uuid - ,bool_and(ldlite_system.jis_datetime(value)) AS is_datetime - ,bool_and(ldlite_system.jis_float(value)) AS is_float + ,bool_and(ldlite_system.jis_uuid(ld_value)) AS is_uuid + ,bool_and(ldlite_system.jis_datetime(ld_value)) AS is_datetime + ,bool_and(ldlite_system.jis_float(ld_value)) AS is_float FROM all_values GROUP BY prop """, @@ -261,15 +261,19 @@ def explode( source_cte: str, ) -> list[str]: with conn.cursor() as cur: - o_col = self.name + "_o" + o_col = self.name + "__o" create_columns: list[sql.Composable] = [ - sql.SQL("ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS __id"), + sql.SQL( + "(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)))::integer AS __id" + ), *[sql.Identifier(v) for v in self.carryover], - sql.SQL("ROW_NUMBER() OVER (PARTITION BY s.__id) AS {id_alias}").format( + sql.SQL( + "(ROW_NUMBER() OVER (PARTITION BY s.__id))::smallint AS {id_alias}", + ).format( id_alias=sql.Identifier(o_col), ), self.meta.select_column( - sql.Identifier("a", "value"), + sql.Identifier("a", "ld_value"), self.name, ), ] diff --git a/src/ldlite/database/_postgres.py b/src/ldlite/database/_postgres.py index 987810c..a9b4b81 100644 --- a/src/ldlite/database/_postgres.py +++ b/src/ldlite/database/_postgres.py @@ -140,7 +140,7 @@ def _setup_jfuncs(conn: psycopg.Connection) -> None: IMMUTABLE PARALLEL SAFE; -CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j JSONB) RETURNS TABLE (value JSONB) AS $$ +CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j JSONB) RETURNS TABLE (ld_value JSONB) AS $$ SELECT * FROM jsonb_array_elements(j); $$ LANGUAGE sql @@ -174,7 +174,7 @@ def ingest_records( cur.copy( sql.SQL( "COPY {table} (__id, jsonb) FROM STDIN (FORMAT BINARY)", - ).format(table=pfx.schemafy(pfx.raw_table)), + ).format(table=pfx.raw_table.id), ) as copy, ): # postgres jsonb is always version 1 diff --git a/src/ldlite/database/_prefix.py b/src/ldlite/database/_prefix.py index d4ef74d..a93dd81 100644 --- a/src/ldlite/database/_prefix.py +++ b/src/ldlite/database/_prefix.py @@ -1,6 +1,13 @@ +from typing import NamedTuple + from psycopg import sql +class PrefixedTable(NamedTuple): + name: str + id: sql.Identifier + + class Prefix: def __init__(self, prefix: str): self.schema: str | None = None @@ -14,32 +21,34 @@ def __init__(self, prefix: str): else: (self.schema, self._prefix) = sandt - def schemafy(self, table: str) -> sql.Identifier: + def _prefixed_table(self, name: str) -> PrefixedTable: if self.schema is None: - return sql.Identifier(table) - return sql.Identifier(self.schema, table) + return PrefixedTable(name, sql.Identifier(name)) + return PrefixedTable(name, sql.Identifier(self.schema, name)) @property - def raw_table(self) -> str: - return self._prefix + def raw_table(self) -> PrefixedTable: + return self._prefixed_table(self._prefix) @property def _output_table(self) -> str: return self._prefix + "__t" - def output_table(self, prefix: str) -> sql.Identifier: - if len(prefix) == 0: - return self.schemafy(self._output_table) - - return self.schemafy(self._output_table + "__" + prefix) + def output_table(self, prefix: str) -> PrefixedTable: + return self._prefixed_table( + self._output_table + ("" if len(prefix) == 0 else "__" + prefix), + ) @property - def catalog_table(self) -> str: - return f"{self._prefix}__tcatalog" + def catalog_table(self) -> PrefixedTable: + return self._prefixed_table(self._prefix + "__tcatalog") + + def catalog_table_row(self, created_table: str) -> str: + return ((self.schema + ".") if self.schema is not None else "") + created_table @property - def legacy_jtable(self) -> str: - return f"{self._prefix}_jtable" + def legacy_jtable(self) -> PrefixedTable: + return self._prefixed_table(self._prefix + "_jtable") @property def load_history_key(self) -> str: diff --git a/src/ldlite/database/_typed_database.py b/src/ldlite/database/_typed_database.py index 6ef07c7..b67d367 100644 --- a/src/ldlite/database/_typed_database.py +++ b/src/ldlite/database/_typed_database.py @@ -26,7 +26,7 @@ def __init__(self, conn_factory: Callable[[], DB]): with conn.cursor() as cur: cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') cur.execute(""" -CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history" ( +CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history_v1" ( "table_name" TEXT UNIQUE ,"path" TEXT ,"query" TEXT @@ -58,7 +58,7 @@ def drop_prefix( self._drop_extracted_tables(conn, pfx) self._drop_raw_table(conn, pfx) conn.execute( - 'DELETE FROM "ldlite_system"."load_history" WHERE "table_name" = $1', + 'DELETE FROM "ldlite_system"."load_history_v1" WHERE "table_name" = $1', (pfx.load_history_key,), ) conn.commit() @@ -79,7 +79,7 @@ def _drop_raw_table( with closing(conn.cursor()) as cur: cur.execute( sql.SQL("DROP TABLE IF EXISTS {table};") - .format(table=prefix.schemafy(prefix.raw_table)) + .format(table=prefix.raw_table.id) .as_string(), ) @@ -104,23 +104,23 @@ def _drop_extracted_tables( WHERE table_schema = $1 and table_name IN ($2, $3);""", ( prefix.schema or self._default_schema, - prefix.catalog_table, - prefix.legacy_jtable, + prefix.catalog_table.name, + prefix.legacy_jtable.name, ), ) for (tname,) in cur.fetchall(): - if tname == prefix.catalog_table: + if tname == prefix.catalog_table.name: cur.execute( sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.schemafy(prefix.catalog_table)) + .format(catalog=prefix.catalog_table.id) .as_string(), ) tables.extend(cur.fetchall()) - if tname == prefix.legacy_jtable: + if tname == prefix.legacy_jtable.name: cur.execute( sql.SQL("SELECT table_name FROM {catalog};") - .format(catalog=prefix.schemafy(prefix.legacy_jtable)) + .format(catalog=prefix.legacy_jtable.id) .as_string(), ) tables.extend(cur.fetchall()) @@ -134,12 +134,12 @@ def _drop_extracted_tables( ) cur.execute( sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.schemafy(prefix.catalog_table)) + .format(catalog=prefix.catalog_table.id) .as_string(), ) cur.execute( sql.SQL("DROP TABLE IF EXISTS {catalog};") - .format(catalog=prefix.schemafy(prefix.legacy_jtable)) + .format(catalog=prefix.legacy_jtable.id) .as_string(), ) @@ -162,7 +162,7 @@ def _prepare_raw_table( with closing(conn.cursor()) as cur: cur.execute( self._create_raw_table_sql.format( - table=prefix.schemafy(prefix.raw_table), + table=prefix.raw_table.id, ).as_string(), ) @@ -179,9 +179,14 @@ def preprocess_source_table( @abstractmethod def source_table_cte_stmt(self, keep_source: bool) -> str: ... - def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> None: + def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[str]: pfx = Prefix(prefix) with closing(self._conn_factory()) as conn: + self._drop_extracted_tables(conn, pfx) + if json_depth < 1: + conn.commit() + return [] + with conn.cursor() as cur: cur.execute( sql.SQL( @@ -195,7 +200,7 @@ def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> None: ) .format( dest_table=pfx.origin_table, - source_table=pfx.schemafy(pfx.raw_table), + source_table=pfx.raw_table.id, ) .as_string(), ) @@ -203,7 +208,7 @@ def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> None: if not keep_raw: self._drop_raw_table(conn, pfx) - expand_nonmarc( + created_tables = expand_nonmarc( "jsonb", ["__id"], ExpandContext( @@ -217,13 +222,36 @@ def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> None: ), ) + with conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +CREATE TABLE {catalog_table} ( + table_name text +) +""", + ) + .format(catalog_table=pfx.catalog_table.id) + .as_string(), + ) + cur.executemany( + sql.SQL("INSERT INTO {catalog_table} VALUES ($1)") + .format( + catalog_table=pfx.catalog_table.id, + ) + .as_string(), + [(pfx.catalog_table_row(t),) for t in created_tables], + ) + conn.commit() + return created_tables + def record_history(self, history: LoadHistory) -> None: with closing(self._conn_factory()) as conn, conn.cursor() as cur: cur.execute( """ -INSERT INTO "ldlite_system"."load_history" VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9) +INSERT INTO "ldlite_system"."load_history_v1" VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9) ON CONFLICT ("table_name") DO UPDATE SET "path" = EXCLUDED."path" ,"query" = EXCLUDED."query" diff --git a/tests/test___init__.py b/tests/test___init__.py index e363ed4..e19eb19 100644 --- a/tests/test___init__.py +++ b/tests/test___init__.py @@ -54,6 +54,20 @@ def test_ok_legacy(self, folio_params: tuple[bool, FolioParams]) -> None: ld.query(table="g", path="/groups", query="cql.allRecords=1 sortby id") ld.select(table="g__t") + def test_ok_legacy_transform(self, folio_params: tuple[bool, FolioParams]) -> None: + from ldlite import LDLite as uut + + ld = uut() + ld.connect_folio(*astuple(folio_params[1])) + ld.connect_db() + ld.query( + table="g", + path="/groups", + query="cql.allRecords=1 sortby id", + use_legacy_transform=True, + ) + ld.select(table="g__t") + def test_ok_limit(self, folio_params: tuple[bool, FolioParams]) -> None: from ldlite import LDLite as uut diff --git a/tests/test_drop_tables.py b/tests/test_drop_tables.py index a0d1d42..1050cd3 100644 --- a/tests/test_drop_tables.py +++ b/tests/test_drop_tables.py @@ -28,11 +28,11 @@ class DropTablesTC(MockedResponseTestCase): def case_one_table(keep_raw: bool) -> DropTablesTC: return DropTablesTC( Call( - "prefix", + "sch.prefix", returns={"purchaseOrders": [{"id": "1"}]}, keep_raw=keep_raw, ), - drop="prefix", + drop="sch.prefix", expected_tables=[], ) @@ -41,7 +41,7 @@ def case_one_table(keep_raw: bool) -> DropTablesTC: def case_two_tables(keep_raw: bool) -> DropTablesTC: return DropTablesTC( Call( - "prefix", + "sch.prefix", returns={ "purchaseOrders": [ { @@ -52,7 +52,7 @@ def case_two_tables(keep_raw: bool) -> DropTablesTC: }, keep_raw=keep_raw, ), - drop="prefix", + drop="sch.prefix", expected_tables=[], ) @@ -69,7 +69,7 @@ def case_separate_table(keep_raw: bool) -> DropTablesTC: return DropTablesTC( [ Call( - "prefix", + "sch.prefix", returns={"purchaseOrders": [{"id": "1"}]}, keep_raw=keep_raw, ), @@ -79,7 +79,7 @@ def case_separate_table(keep_raw: bool) -> DropTablesTC: keep_raw=keep_raw, ), ], - drop="prefix", + drop="sch.prefix", expected_tables=expected_tables, ) @@ -120,11 +120,11 @@ def _assert( ) assert sorted([r[0] for r in cur.fetchall()]) == sorted(tc.expected_tables) - cur.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + cur.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history_v1"') assert (ud := cur.fetchone()) is not None assert ud[0] == len(tc.calls_list) - 1 cur.execute( - 'SELECT COUNT(*) FROM "ldlite_system"."load_history" ' + 'SELECT COUNT(*) FROM "ldlite_system"."load_history_v1" ' 'WHERE "table_name" = $1', (tc.drop,), ) diff --git a/tests/test_expansion.py b/tests/test_expansion.py index bcb62b7..8967736 100644 --- a/tests/test_expansion.py +++ b/tests/test_expansion.py @@ -51,6 +51,7 @@ def case_typed_columns() -> ExpansionTC: "id": "id1", "numeric": 1, "text": "value", + "boolean": false, "uuid": "88888888-8888-1888-8888-888888888888" } """, @@ -59,6 +60,7 @@ def case_typed_columns() -> ExpansionTC: "id": "id2", "numeric": 2, "text": "00000000-0000-1000-A000-000000000000", + "boolean": false, "uuid": "11111111-1111-1111-8111-111111111111" } """, @@ -77,6 +79,7 @@ def case_typed_columns() -> ExpansionTC: ("numeric", "DECIMAL(18,3)"), ("text", "VARCHAR"), ("uuid", "UUID"), + ("boolean", "BOOLEAN"), ] ], ) @@ -88,6 +91,7 @@ def case_typed_columns() -> ExpansionTC: ("all_null", None, None), ("nullable_numeric", "numeric", "DECIMAL(18,3)"), ("nullable_uuid", "uuid", "UUID"), + ("nullable_bool", "boolean", "BOOLEAN"), ("nullable_object__id", "numeric", "DECIMAL(18,3)"), ("nullable_array", "numeric", "DECIMAL(18,3)"), ("sortof_nullable_array__id", "numeric", "DECIMAL(18,3)"), @@ -101,6 +105,7 @@ def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: { "all_null": null, "nullable_numeric": null, + "nullable_bool": null, "nullable_uuid": null, "nullable_object": null, "nullable_array": [], @@ -112,6 +117,7 @@ def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: "all_null": null, "nullable_numeric": 5, "nullable_uuid": null, + "nullable_bool": false, "nullable_object": { "id": 5 }, "nullable_array": null, "sortof_nullable_array": [{}, {}] @@ -121,6 +127,7 @@ def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: { "all_null": null, "nullable_numeric": null, + "nullable_bool": true, "nullable_uuid": "0b03c888-102b-18e9-afb7-85e22229ca4d", "nullable_object": { "id": null}, "nullable_array": [null, 5, null], @@ -216,6 +223,14 @@ def case_basic_array() -> ExpansionTC: assertions=[ Assertion("""SELECT COUNT(*) FROM tests.prefix__t__list1""", expect=6), Assertion("""SELECT COUNT(*) FROM tests.prefix__t__list2""", expect=2), + Assertion( + """SELECT * FROM tests.prefix__tcatalog ORDER BY table_name""", + expect=[ + ("tests.prefix__t",), + ("tests.prefix__t__list1",), + ("tests.prefix__t__list2",), + ], + ), Assertion( """ SELECT id, list1 @@ -233,9 +248,9 @@ def case_basic_array() -> ExpansionTC: ), Assertion( """ -SELECT id, list1_o +SELECT id, list1__o FROM tests.prefix__t__list1 -ORDER BY id, list1_o +ORDER BY id, list1__o """, expect=[ ("id1", 1), @@ -255,15 +270,15 @@ def case_basic_array() -> ExpansionTC: ORDER BY ORDINAL_POSITION """, exp_duck=[ - ("__id", "BIGINT"), + ("__id", "INTEGER"), ("id", "VARCHAR"), - (f"{a[0]}_o", "BIGINT"), + (f"{a[0]}__o", "SMALLINT"), (f"{a[0]}", a[1]), ], exp_pg=[ - ("__id", "bigint"), + ("__id", "integer"), ("id", "text"), - (f"{a[0]}_o", "bigint"), + (f"{a[0]}__o", "smallint"), (f"{a[0]}", a[2]), ], ) @@ -294,6 +309,13 @@ def case_nested_arrays() -> ExpansionTC: ], assertions=[ Assertion("""SELECT COUNT(*) FROM tests.prefix__t__sub""", expect=4), + Assertion( + """SELECT * FROM tests.prefix__tcatalog ORDER BY table_name""", + expect=[ + ("tests.prefix__t",), + ("tests.prefix__t__sub",), + ], + ), Assertion( """ SELECT id, sub__id @@ -309,9 +331,9 @@ def case_nested_arrays() -> ExpansionTC: ), Assertion( """ -SELECT id, sub_o +SELECT id, sub__o FROM tests.prefix__t__sub -ORDER BY id, sub_o +ORDER BY id, sub__o """, expect=[ ("id1", 1), @@ -328,15 +350,15 @@ def case_nested_arrays() -> ExpansionTC: ORDER BY ORDINAL_POSITION """, exp_duck=[ - ("__id", "BIGINT"), + ("__id", "INTEGER"), ("id", "VARCHAR"), - ("sub_o", "BIGINT"), + ("sub__o", "SMALLINT"), ("sub__id", "VARCHAR"), ], exp_pg=[ - ("__id", "bigint"), + ("__id", "integer"), ("id", "text"), - ("sub_o", "bigint"), + ("sub__o", "smallint"), ("sub__id", "text"), ], ), @@ -352,6 +374,12 @@ def case_basic_object() -> ExpansionTC: ], assertions=[ Assertion("SELECT COUNT(*) FROM tests.prefix__t;", 2), + Assertion( + """SELECT * FROM tests.prefix__tcatalog ORDER BY table_name""", + expect=[ + ("tests.prefix__t",), + ], + ), Assertion("SELECT id FROM tests.prefix__t WHERE __id = 1", "id1"), Assertion( "SELECT camel_value FROM tests.prefix__t WHERE __id = 1", @@ -410,6 +438,12 @@ def case_nested_objects() -> ExpansionTC: ], assertions=[ Assertion("SELECT COUNT(*) FROM tests.prefix__t;", 2), + Assertion( + """SELECT * FROM tests.prefix__tcatalog ORDER BY table_name""", + expect=[ + ("tests.prefix__t",), + ], + ), Assertion("SELECT id FROM tests.prefix__t WHERE __id = 1", "id1"), Assertion("SELECT sub__id FROM tests.prefix__t WHERE __id = 1", "sub_id1"), Assertion( @@ -483,6 +517,15 @@ def case_json_depth() -> ExpansionTC: ], assertions=[ Assertion("""SELECT "depth2_obj4__id" FROM tests.prefix__t""", "id2"), + Assertion( + """SELECT * FROM tests.prefix__tcatalog ORDER BY table_name""", + expect=[ + ("tests.prefix__t",), + ("tests.prefix__t__depth2_arr",), + ("tests.prefix__t__depth2_arr__depth3_arr",), + ("tests.prefix__t__depth2_obj__depth3_arr",), + ], + ), Assertion( """ SELECT "depth2_obj__depth3_obj__id" diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index 29aaf3d..d89cf44 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -159,11 +159,11 @@ def case_jexplode(p: tuple[Any, ...]) -> JsonTC: """ {assertion} ( - SELECT a.value FROM j, ldlite_system.jexplode(j.jc->$1) a + SELECT a.ld_value FROM j, ldlite_system.jexplode(j.jc->$1) a EXCEPT SELECT value::{jtype} FROM unnest($2::text[]) AS expect(value) UNION ALL SELECT value::{jtype} FROM unnest($2::text[]) AS expect(value) - EXCEPT SELECT a.value FROM j, ldlite_system.jexplode(j.jc->$1) a + EXCEPT SELECT a.ld_value FROM j, ldlite_system.jexplode(j.jc->$1) a ) """, p, diff --git a/tests/test_load_history.py b/tests/test_load_history.py index b6afa24..d26120e 100644 --- a/tests/test_load_history.py +++ b/tests/test_load_history.py @@ -126,13 +126,14 @@ def _assert( tc: LoadHistoryTC, ) -> None: with closing(conn.cursor()) as cur: - cur.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history"') + cur.execute('SELECT COUNT(*) FROM "ldlite_system"."load_history_v1"') assert (ud := cur.fetchone()) is not None assert ud[0] == len(tc.expected_loads) for tn, (q, t) in tc.expected_loads.items(): cur.execute( - 'SELECT * FROM "ldlite_system"."load_history" WHERE "table_name" = $1', + 'SELECT * FROM "ldlite_system"."load_history_v1" ' + 'WHERE "table_name" = $1', (tn,), ) assert (d := cur.fetchone()) is not None diff --git a/tests/test_query.py b/tests/test_query.py index f75a369..96ce1e6 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -1,4 +1,3 @@ -import json from collections.abc import Callable from contextlib import closing from dataclasses import dataclass @@ -419,13 +418,8 @@ def case_nested_object_underexpansion() -> QueryTC: ( "b096504a-3d54-4664-9bf5-1b872466fd66", "value", - json.dumps( - { - "id": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "value": "sub-value", - }, - indent=4, - ), + '{"id":"2b94c631-fca9-4892-a730-03ee529ffe2a",' + '"value":"sub-value"}', ), ], ), @@ -587,29 +581,27 @@ def case_id_generation() -> QueryTC: ], expected_values={ "prefix__t__sub_objects": ( - ["__id", "id", "sub_objects__o", "sub_objects__id"], + ["__id", "id", "sub_objects__o"], [ ( "1", "b096504a-3d54-4664-9bf5-1b872466fd66", "1", - "2b94c631-fca9-4892-a730-03ee529ffe2a", ), ( "2", "b096504a-3d54-4664-9bf5-1b872466fd66", "2", - "b5d8cdc4-9441-487c-90cf-0c7ec97728eb", ), ], ), "prefix__t__sub_objects__sub_sub_objects": ( - ["__id", "sub_objects__o", "sub_objects__sub_sub_objects__o"], + ["sub_objects__o", "sub_objects__sub_sub_objects__o"], [ - ("1", "1", "1"), - ("2", "1", "2"), - ("3", "2", "1"), - ("4", "2", "2"), + ("1", "1"), + ("1", "2"), + ("2", "1"), + ("2", "2"), ], ), }, @@ -783,10 +775,15 @@ def _assert( for table, (cols, values) in tc.expected_values.items(): cur.execute( - sql.SQL("SELECT {cols}::text FROM {table};") + sql.SQL('SELECT {cols} FROM {table} ORDER BY {cols} COLLATE "C";') .format( - cols=sql.SQL("::text, ").join( - [sql.Identifier(c) for c in cols], + cols=sql.SQL(", ").join( + [ + sql.SQL( + "REGEXP_REPLACE({col}::text, '\\s+', '', 'g')", + ).format(col=sql.Identifier(c)) + for c in cols + ], ), table=sql.Identifier(table), ) From f397d3102bf3bc88b4b00fb9afdaf9d305151a9a Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Mon, 9 Mar 2026 16:24:11 -0400 Subject: [PATCH 16/25] Index without legacy scanning information (#67) The previous indexing process relied on information saved during the scanning/transformation process. While I could still do it that way I'd like to make these steps independent so they can be better distributed in the future. While only postgres was indexed there's really no harm to also indexing duckdb. I've also realized that the ldlite system generated columns like __id and __o are almost never used in queries so they do not need to be indexed. At some point in the past the unit tests for indexing were accidentally removed and they're restored in this PR. --- src/ldlite/__init__.py | 79 ++++++++++++++------------ src/ldlite/database/__init__.py | 15 ++++- src/ldlite/database/_typed_database.py | 66 ++++++++++++++++++++- tests/test_query.py | 56 +++++++++--------- 4 files changed, 148 insertions(+), 68 deletions(-) diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 1cf80ac..1c118ae 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -337,7 +337,6 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 records, desc="downloading", total=total_records, - leave=False, mininterval=5, disable=self._quiet, unit=table.split(".")[-1], @@ -354,7 +353,11 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 newtables = self._database.expand_prefix(table, json_depth, keep_raw) if keep_raw: newtables = [table, *newtables] - indexable_attrs = [] + transform_elapsed = datetime.now(timezone.utc) - transform_started + + with tqdm(desc="indexing", disable=self._quiet) as progress: + index_started = datetime.now(timezone.utc) + self._database.index_prefix(table, progress) else: try: @@ -392,40 +395,46 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 finally: autocommit(self.db, self.dbtype, True) - transform_elapsed = datetime.now(timezone.utc) - transform_started - # Create indexes on id columns (for postgres) - index_started = datetime.now(timezone.utc) - if self.dbtype == DBType.POSTGRES: - - class PbarNoop: - def update(self, _: int) -> None: ... - def close(self) -> None: ... - - pbar: tqdm | PbarNoop = PbarNoop() # type:ignore[type-arg] - - index_total = len(indexable_attrs) - if not self._quiet: - pbar = tqdm( - desc="indexing", - total=index_total, - leave=False, - mininterval=3, - smoothing=0, - colour="#A9A9A9", - bar_format="{desc} {bar}{postfix}", - ) - for t, attr in indexable_attrs: - cur = self.db.cursor() - try: - cur.execute( - "CREATE INDEX ON " + sqlid(t) + " (" + sqlid(attr.name) + ")", + transform_elapsed = datetime.now(timezone.utc) - transform_started + + # Create indexes on id columns (for postgres) + index_started = datetime.now(timezone.utc) + if self.dbtype == DBType.POSTGRES: + + class PbarNoop: + def update(self, _: int) -> None: ... + def close(self) -> None: ... + + pbar: tqdm | PbarNoop = PbarNoop() # type:ignore[type-arg] + + index_total = len(indexable_attrs) + if not self._quiet: + pbar = tqdm( + desc="indexing", + total=index_total, + leave=False, + mininterval=3, + smoothing=0, + colour="#A9A9A9", + bar_format="{desc} {bar}{postfix}", ) - except (RuntimeError, psycopg.Error): - pass - finally: - cur.close() - pbar.update(1) - pbar.close() + for t, attr in indexable_attrs: + cur = self.db.cursor() + try: + cur.execute( + "CREATE INDEX ON " + + sqlid(t) + + " (" + + sqlid(attr.name) + + ")", + ) + except (RuntimeError, psycopg.Error): + pass + finally: + cur.close() + pbar.update(1) + pbar.close() + index_elapsed = datetime.now(timezone.utc) - index_started self._database.record_history( LoadHistory( diff --git a/src/ldlite/database/__init__.py b/src/ldlite/database/__init__.py index 719656c..9acd7b8 100644 --- a/src/ldlite/database/__init__.py +++ b/src/ldlite/database/__init__.py @@ -1,9 +1,16 @@ """A module for implementing ldlite database targets.""" -import datetime +from __future__ import annotations + from abc import ABC, abstractmethod -from collections.abc import Iterator from dataclasses import dataclass +from typing import TYPE_CHECKING, NoReturn + +if TYPE_CHECKING: + import datetime + from collections.abc import Iterator + + from tqdm import tqdm @dataclass(frozen=True) @@ -50,6 +57,10 @@ def ingest_records(self, prefix: str, records: Iterator[bytes]) -> int: def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[str]: """Unnests and explodes the raw data at the given prefix.""" + @abstractmethod + def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> None: + """Finds and indexes all tables at the given prefix.""" + @abstractmethod def record_history(self, history: LoadHistory) -> None: """Records the statistics and history of a single ldlite operation.""" diff --git a/src/ldlite/database/_typed_database.py b/src/ldlite/database/_typed_database.py index b67d367..eb4a1f3 100644 --- a/src/ldlite/database/_typed_database.py +++ b/src/ldlite/database/_typed_database.py @@ -1,9 +1,11 @@ # pyright: reportArgumentType=false +from __future__ import annotations + from abc import abstractmethod -from collections.abc import Callable, Sequence from contextlib import closing from datetime import timezone -from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast +from typing import TYPE_CHECKING, Any, Generic, NoReturn, TypeVar, cast +from uuid import uuid4 import psycopg from psycopg import sql @@ -13,7 +15,10 @@ from ._prefix import Prefix if TYPE_CHECKING: + from collections.abc import Callable, Sequence + import duckdb + from tqdm import tqdm DB = TypeVar("DB", bound="duckdb.DuckDBPyConnection | psycopg.Connection") @@ -247,6 +252,63 @@ def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[st return created_tables + def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> None: + pfx = Prefix(prefix) + with closing(self._conn_factory()) as conn: + with closing(conn.cursor()) as cur: + cur.execute( + """ +SELECT table_name FROM information_schema.tables +WHERE table_schema = $1 and table_name = $2;""", + ( + pfx.schema or self._default_schema, + pfx.catalog_table.name, + ), + ) + if len(cur.fetchall()) < 1: + return + + with closing(conn.cursor()) as cur: + cur.execute( + sql.SQL( + r""" +SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS +WHERE + TABLE_SCHEMA = $1 AND + TABLE_NAME IN (SELECT TABLE_NAME FROM {catalog}) AND + ( + DATA_TYPE IN ('UUID', 'uuid') OR + COLUMN_NAME = 'id' OR + (COLUMN_NAME LIKE '%\_id' AND COLUMN_NAME <> '__id') + ); +""", + ) + .format(catalog=pfx.catalog_table.id) + .as_string(), + (pfx.schema or self._default_schema,), + ) + indexes = cur.fetchall() + + if progress is not None: + progress.total = len(indexes) + progress.refresh() + + for index in indexes: + with closing(conn.cursor()) as cur: + cur.execute( + sql.SQL("CREATE INDEX {name} ON {table} ({column});") + .format( + name=sql.Identifier(str(uuid4()).split("-")[0]), + table=sql.Identifier(*index[0].split(".")), + column=sql.Identifier(index[1]), + ) + .as_string(), + ) + if progress is not None: + progress.update(1) + + conn.commit() + def record_history(self, history: LoadHistory) -> None: with closing(self._conn_factory()) as conn, conn.cursor() as cur: cur.execute( diff --git a/tests/test_query.py b/tests/test_query.py index 96ce1e6..41ad44e 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -51,8 +51,6 @@ def case_one_table(json_depth: int) -> QueryTC: "prefix__tcatalog": (["table_name"], [("prefix__t",)]), }, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), ], ) @@ -115,12 +113,8 @@ def case_two_tables(json_depth: int) -> QueryTC: ), }, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), - ("prefix__t__sub_objects", "__id"), ("prefix__t__sub_objects", "id"), - ("prefix__t__sub_objects", "sub_objects__o"), ("prefix__t__sub_objects", "sub_objects__id"), ], ) @@ -267,21 +261,11 @@ def case_three_tables(json_depth: int) -> QueryTC: ), }, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), - ("prefix__t__sub_objects", "__id"), ("prefix__t__sub_objects", "id"), - ("prefix__t__sub_objects", "sub_objects__o"), ("prefix__t__sub_objects", "sub_objects__id"), - ("prefix__t__sub_objects__sub_sub_objects", "__id"), ("prefix__t__sub_objects__sub_sub_objects", "id"), - ("prefix__t__sub_objects__sub_sub_objects", "sub_objects__o"), ("prefix__t__sub_objects__sub_sub_objects", "sub_objects__id"), - ( - "prefix__t__sub_objects__sub_sub_objects", - "sub_objects__sub_sub_objects__o", - ), ( "prefix__t__sub_objects__sub_sub_objects", "sub_objects__sub_sub_objects__id", @@ -327,8 +311,6 @@ def case_nested_object() -> QueryTC: ), }, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), ("prefix__t", "sub_object__id"), ], @@ -383,8 +365,6 @@ def case_doubly_nested_object() -> QueryTC: ), }, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), ("prefix__t", "sub_object__id"), ("prefix__t", "sub_object__sub_sub_object__id"), @@ -632,8 +612,6 @@ def case_indexing_id_like() -> QueryTC: ], expected_values={}, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), ("prefix__t", "other_id"), ("prefix__t", "an_id_but_with_a_different_ending"), @@ -666,7 +644,6 @@ def case_drop_raw(json_depth: int) -> QueryTC: "prefix__tcatalog": (["table_name"], [("prefix__t",)]), }, expected_indexes=[ - ("prefix__t", "__id"), ("prefix__t", "id"), ], ) @@ -692,8 +669,6 @@ def case_null_records() -> QueryTC: expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], expected_values={}, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), ], ) @@ -727,8 +702,6 @@ def case_erm_keys() -> QueryTC: "prefix__tcatalog": (["table_name"], [("prefix__t",)]), }, expected_indexes=[ - ("prefix", "__id"), - ("prefix__t", "__id"), ("prefix__t", "id"), ], ) @@ -790,7 +763,7 @@ def _assert( .as_string(), ) for v in values: - assert cur.fetchone() == v + assert cur.fetchone() == v, str(v) assert cur.fetchone() is None @@ -804,7 +777,32 @@ def _assert( """, exp, ) - assert cur.fetchone() == (0,) + assert cur.fetchone() == (0,), str(exp) + + if tc.expected_indexes is not None: + for exp in tc.expected_indexes: + cur.execute( + """ + SELECT * FROM pg_indexes + WHERE tablename = $1 and indexdef LIKE $2; + """, + (exp[0], "%" + exp[1] + "%"), + ) + assert cur.fetchone() is not None, str(exp) + + indexed_tables = {exp[0] for exp in tc.expected_indexes} + where = ",".join([f"${n}" for n in range(1, len(indexed_tables) + 1)]) + cur.execute( + f""" + SELECT tablename, indexdef FROM pg_indexes + WHERE tablename IN ({where}) + ORDER BY tablename; + """, + list(indexed_tables), + ) + actual_indexes = cur.fetchall() + expected_indexes = tc.expected_indexes + assert len(actual_indexes) == len(expected_indexes) @mock.patch("httpx_folio.auth.httpx.post") From d33f3c4a2b59b76e2fb8bd9ed88a12c1d3aa2a67 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Tue, 10 Mar 2026 12:43:59 -0400 Subject: [PATCH 17/25] Improve performance of new transform for large tables (#68) The biggest draw of refactoring the transformation logic to happen in postgres vs python was a performance speed up. Unfortunately as I had originally implemented it postgres ran out of memory and died on any table with a row x column count approaching a million. This PR is the result of a lot of performance tuning and optimization to get the memory usage down while still being fast. I've verified this on a table with 6 million rows and feel confident about the biggest tables (which testing will happen soon). During testing I realized I forgot the progress bars which was really annoying as I had no idea if transformation was doing anything so I added them back in this PR. I also realized that indexing did not work on tables with schemas and fixed it. Note: Postgres 14 is required for negative indexing on the table name in the tcatalog table. --- environment.yaml | 2 +- src/ldlite/__init__.py | 33 ++++- src/ldlite/database/__init__.py | 9 +- src/ldlite/database/_duckdb.py | 47 ++---- src/ldlite/database/_expansion/__init__.py | 62 +++----- src/ldlite/database/_expansion/context.py | 52 +++++++ src/ldlite/database/_expansion/metadata.py | 30 +++- src/ldlite/database/_expansion/nodes.py | 163 ++++++++++++++------- src/ldlite/database/_postgres.py | 91 +++--------- src/ldlite/database/_typed_database.py | 44 ++++-- tests/test_json_operators.py | 106 +------------- tests/test_query.py | 66 ++++----- 12 files changed, 345 insertions(+), 360 deletions(-) create mode 100644 src/ldlite/database/_expansion/context.py diff --git a/environment.yaml b/environment.yaml index 22c24ca..ea467a4 100644 --- a/environment.yaml +++ b/environment.yaml @@ -7,4 +7,4 @@ dependencies: - python>=3.10,<3.11 - pdm==2.26.6 - precious==0.10.2 - - libpq>=13.0 + - libpq>=14.0 diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 1c118ae..3d9d3ef 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -336,6 +336,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 tqdm( records, desc="downloading", + leave=False, total=total_records, mininterval=5, disable=self._quiet, @@ -350,12 +351,40 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 transform_started = datetime.now(timezone.utc) if not use_legacy_transform: - newtables = self._database.expand_prefix(table, json_depth, keep_raw) + no_iters_format = ( + "{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}]" + ) + with ( + tqdm( + desc="scanning", + leave=False, + disable=self._quiet, + bar_format=no_iters_format, + ) as scan_progress, + tqdm( + desc="transforming", + leave=False, + disable=self._quiet, + bar_format=no_iters_format, + ) as transform_progress, + ): + newtables = self._database.expand_prefix( + table, + json_depth, + keep_raw, + scan_progress, + transform_progress, + ) if keep_raw: newtables = [table, *newtables] transform_elapsed = datetime.now(timezone.utc) - transform_started - with tqdm(desc="indexing", disable=self._quiet) as progress: + with tqdm( + desc="indexing", + leave=False, + disable=self._quiet, + bar_format=no_iters_format, + ) as progress: index_started = datetime.now(timezone.utc) self._database.index_prefix(table, progress) diff --git a/src/ldlite/database/__init__.py b/src/ldlite/database/__init__.py index 9acd7b8..e1df517 100644 --- a/src/ldlite/database/__init__.py +++ b/src/ldlite/database/__init__.py @@ -54,7 +54,14 @@ def ingest_records(self, prefix: str, records: Iterator[bytes]) -> int: """Ingests a stream of records dowloaded from FOLIO to the raw table.""" @abstractmethod - def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[str]: + def expand_prefix( + self, + prefix: str, + json_depth: int, + keep_raw: bool, + scan_progress: tqdm[NoReturn] | None = None, + transform_progress: tqdm[NoReturn] | None = None, + ) -> list[str]: """Unnests and explodes the raw data at the given prefix.""" @abstractmethod diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index 98ac5bb..1ca8508 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -41,62 +41,33 @@ def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: END ; -CREATE OR REPLACE FUNCTION ldlite_system.jextract(j, p) AS - CASE ldlite_system.jtype_of(main.json_extract(j, p)) - WHEN 'string' THEN - CASE - WHEN lower(main.json_extract_string(j, p)) = 'null' THEN 'null'::JSON - WHEN length(main.json_extract_string(j, p)) = 0 THEN 'null'::JSON - ELSE main.json_extract(j, p) - END - WHEN 'object' THEN - CASE - WHEN main.json_extract_string(j, p) = '{}' THEN 'null'::JSON - ELSE main.json_extract(j, p) - END - WHEN 'array' THEN - CASE - WHEN length(list_filter((main.json_extract(j, p))::JSON[], lambda x : x != 'null'::JSON)) = 0 THEN 'null'::JSON - ELSE list_filter((main.json_extract(j, p))::JSON[], lambda x : x != 'null'::JSON) - END - ELSE coalesce(main.json_extract(j, p), 'null'::JSON) - END -; - -CREATE OR REPLACE FUNCTION ldlite_system.jextract_string(j, p) AS - main.json_extract_string(ldlite_system.jextract(j, p), '$') -; - -CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j) AS - unnest(main.json_keys(j)) +CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j) AS TABLE + SELECT je.key as ld_key FROM json_each(j) je ORDER BY je.id ; CREATE OR REPLACE FUNCTION ldlite_system.jis_uuid(j) AS - CASE ldlite_system.jtype_of(j) - WHEN 'string' THEN regexp_full_match(main.json_extract_string(j, '$'), '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$') - ELSE FALSE - END + regexp_full_match(main.json_extract_string(j, '$'), '(?i)^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89abAB][a-f0-9]{3}-[a-f0-9]{12}$') ; CREATE OR REPLACE FUNCTION ldlite_system.jis_datetime(j) AS - CASE ldlite_system.jtype_of(j) - WHEN 'string' THEN regexp_full_match(main.json_extract_string(j, '$'), '^\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?$') - ELSE FALSE - END + regexp_full_match(main.json_extract_string(j, '$'), '^\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?$') ; CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j) AS - coalesce(main.json_type(j), 'NULL') == 'DOUBLE' + main.json_type(j) == 'DOUBLE' ; CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j) AS - j is NULL or j == 'null'::JSON + j IS NULL OR j == 'null'::JSON OR main.json_extract_string(j, '$') IN ('NULL', 'null', '', '{}', '[]') ; CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j) AS TABLE ( SELECT value as ld_value FROM main.json_each(j) ); +CREATE OR REPLACE FUNCTION ldlite_system.jself_string(j) AS + main.json_extract_string(j, '$') +; """, # noqa: E501 ) diff --git a/src/ldlite/database/_expansion/__init__.py b/src/ldlite/database/_expansion/__init__.py index d6f8bd5..ae78c48 100644 --- a/src/ldlite/database/_expansion/__init__.py +++ b/src/ldlite/database/_expansion/__init__.py @@ -1,7 +1,6 @@ from __future__ import annotations from collections import deque -from dataclasses import dataclass from typing import TYPE_CHECKING from psycopg import sql @@ -9,46 +8,7 @@ from .nodes import ArrayNode, ObjectNode if TYPE_CHECKING: - from collections.abc import Callable - - import duckdb - import psycopg - - -@dataclass -class ExpandContext: - conn: duckdb.DuckDBPyConnection | psycopg.Connection - source_table: sql.Identifier - json_depth: int - get_transform_table: Callable[[int], sql.Identifier] - get_output_table: Callable[[str], tuple[str, sql.Identifier]] - # This is necessary for Analyzing the table in pg before querying it - # I don't love how this is implemented - preprocess: Callable[ - [ - duckdb.DuckDBPyConnection | psycopg.Connection, - sql.Identifier, - list[sql.Identifier], - ], - None, - ] - # source_cte will go away when DuckDB implements CTAS RETURNING - source_cte: Callable[[bool], str] - - def array_context( - self, - new_source_table: sql.Identifier, - new_json_depth: int, - ) -> ExpandContext: - return ExpandContext( - self.conn, - new_source_table, - new_json_depth, - self.get_transform_table, - self.get_output_table, - self.preprocess, - self.source_cte, - ) + from .context import ExpandContext def expand_nonmarc( @@ -69,18 +29,28 @@ def _expand_nonmarc( count: int, ctx: ExpandContext, ) -> tuple[int, list[str]]: + ctx.scan_progress.total = (ctx.scan_progress.total or 0) + 1 + ctx.scan_progress.refresh() + ctx.transform_progress.total = (ctx.transform_progress.total or 0) + 1 + ctx.transform_progress.refresh() initial_count = count ctx.preprocess(ctx.conn, ctx.source_table, [root.identifier]) - root.unnest( - ctx.conn, + has_rows = root.unnest( + ctx, ctx.source_table, ctx.get_transform_table(count), ctx.source_cte(False), ) + ctx.transform_progress.update(1) + if not has_rows: + return (0, []) expand_children_of = deque([root]) while expand_children_of: on = expand_children_of.popleft() + if ctx.transform_progress: + ctx.transform_progress.total += len(on.object_children) + ctx.transform_progress.refresh() for c in on.object_children: if len(c.parents) >= ctx.json_depth: if c.parent is not None: @@ -88,18 +58,21 @@ def _expand_nonmarc( continue ctx.preprocess(ctx.conn, ctx.get_transform_table(count), [c.identifier]) c.unnest( - ctx.conn, + ctx, ctx.get_transform_table(count), ctx.get_transform_table(count + 1), ctx.source_cte(False), ) expand_children_of.append(c) count += 1 + ctx.transform_progress.update(1) created_tables = [] new_source_table = ctx.get_transform_table(count) arrays = root.descendents_oftype(ArrayNode) + ctx.transform_progress.total += len(arrays) + ctx.transform_progress.refresh() ctx.preprocess(ctx.conn, new_source_table, [a.identifier for a in arrays]) for an in arrays: if len(an.parents) >= ctx.json_depth: @@ -111,6 +84,7 @@ def _expand_nonmarc( ctx.source_cte(True), ) count += 1 + ctx.transform_progress.update(1) if an.meta.is_object: (sub_index, array_tables) = _expand_nonmarc( diff --git a/src/ldlite/database/_expansion/context.py b/src/ldlite/database/_expansion/context.py new file mode 100644 index 0000000..7b9e29a --- /dev/null +++ b/src/ldlite/database/_expansion/context.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, NoReturn + +if TYPE_CHECKING: + from collections.abc import Callable + + import duckdb + import psycopg + from psycopg import sql + from tqdm import tqdm + + +@dataclass +class ExpandContext: + conn: duckdb.DuckDBPyConnection | psycopg.Connection + source_table: sql.Identifier + json_depth: int + get_transform_table: Callable[[int], sql.Identifier] + get_output_table: Callable[[str], tuple[str, sql.Identifier]] + # This is necessary for Analyzing the table in pg before querying it + # I don't love how this is implemented + preprocess: Callable[ + [ + duckdb.DuckDBPyConnection | psycopg.Connection, + sql.Identifier, + list[sql.Identifier], + ], + None, + ] + # source_cte will go away when DuckDB implements CTAS RETURNING + source_cte: Callable[[bool], str] + scan_progress: tqdm[NoReturn] + transform_progress: tqdm[NoReturn] + + def array_context( + self, + new_source_table: sql.Identifier, + new_json_depth: int, + ) -> ExpandContext: + return ExpandContext( + self.conn, + new_source_table, + new_json_depth, + self.get_transform_table, + self.get_output_table, + self.preprocess, + self.source_cte, + self.scan_progress, + self.transform_progress, + ) diff --git a/src/ldlite/database/_expansion/metadata.py b/src/ldlite/database/_expansion/metadata.py index 15f75f7..e18b854 100644 --- a/src/ldlite/database/_expansion/metadata.py +++ b/src/ldlite/database/_expansion/metadata.py @@ -40,26 +40,44 @@ def select_column( json_col: sql.Identifier, alias: str, ) -> sql.Composed: + # '$' is a special character that means the root of the json + # I couldn't figure out how to make the array expansion work + # without it if self.is_array or self.is_object: stmt = sql.SQL( - "(ldlite_system.jextract({json_col}, {prop})) AS {alias}", + "{json_col}->{prop} AS {alias}" + if self.prop != "$" + else "{json_col} AS {alias}", ) elif self.json_type == "number": stmt = sql.SQL( - "(ldlite_system.jextract_string({json_col}, {prop}))" - "::numeric AS {alias}", + "({json_col}->>{prop})::numeric AS {alias}" + if self.prop != "$" + else "ldlite_system.jself_string({json_col})::numeric AS {alias}", ) elif self.json_type == "boolean": stmt = sql.SQL( - "(ldlite_system.jextract_string({json_col}, {prop}))::bool AS {alias}", + "NULLIF(NULLIF({json_col}->>{prop}, ''), 'null')::bool AS {alias}" + if self.prop != "$" + else "NULLIF(NULLIF(" + "ldlite_system.jself_string({json_col})" + ", ''), 'null')::bool AS {alias}", ) elif self.json_type == "string" and self.is_uuid: stmt = sql.SQL( - "(ldlite_system.jextract_string({json_col}, {prop}))::uuid AS {alias}", + "NULLIF(NULLIF({json_col}->>{prop}, ''), 'null')::uuid AS {alias}" + if self.prop != "$" + else "NULLIF(NULLIF(" + "ldlite_system.jself_string({json_col})" + ", ''), 'null')::uuid AS {alias}", ) else: stmt = sql.SQL( - "(ldlite_system.jextract_string({json_col}, {prop})) AS {alias}", + "NULLIF(NULLIF({json_col}->>{prop}, ''), 'null') AS {alias}" + if self.prop != "$" + else "NULLIF(NULLIF(" + "ldlite_system.jself_string({json_col})" + ", ''), 'null') AS {alias}", ) return stmt.format( diff --git a/src/ldlite/database/_expansion/nodes.py b/src/ldlite/database/_expansion/nodes.py index 7883f51..75ea842 100644 --- a/src/ldlite/database/_expansion/nodes.py +++ b/src/ldlite/database/_expansion/nodes.py @@ -1,7 +1,8 @@ from __future__ import annotations from collections import deque -from typing import TYPE_CHECKING, TypeVar +from math import floor +from typing import TYPE_CHECKING, TypeVar, cast from psycopg import sql @@ -11,6 +12,8 @@ import duckdb import psycopg + from .context import ExpandContext + from .metadata import Metadata TNode = TypeVar("TNode", bound="ExpansionNode") @@ -117,90 +120,148 @@ def object_children(self) -> list[ObjectNode]: def unnest( self, - conn: duckdb.DuckDBPyConnection | psycopg.Connection, + ctx: ExpandContext, source_table: sql.Identifier, dest_table: sql.Identifier, source_cte: str, - ) -> None: + ) -> bool: self.unnested = True create_columns: list[sql.Composable] = [ sql.Identifier(v) for v in self.carryover ] - with conn.cursor() as cur: + with ctx.conn.cursor() as cur: + cur.execute( + sql.SQL("SELECT COUNT(*) FROM {table}") + .format(table=source_table) + .as_string(), + ) + total = cast("tuple[int]", cur.fetchone())[0] + if total == 0: + return False + + with ctx.conn.cursor() as cur: cur.execute( sql.SQL( """ WITH - one_object AS ( - SELECT {json_col} AS json - FROM {table} - WHERE NOT ldlite_system.jis_null({json_col}) - LIMIT 1 + keys AS ( + SELECT + keys.ld_key AS k + ,ROW_NUMBER() OVER (PARTITION BY t.__id) AS idx + FROM {source_table} t, ldlite_system.jobject_keys(t.{json_col}) keys + WHERE {json_col} IS NOT NULL AND ldlite_system.jtype_of(t.{json_col}) = 'object' ), - props AS (SELECT ldlite_system.jobject_keys(json) AS prop FROM one_object), - values AS ( + ordered_keys AS ( SELECT - prop - ,ldlite_system.jextract({json_col}, prop) as ld_value - FROM {table}, props + k + ,MAX(idx) idx + ,COUNT(idx) freq + FROM keys + GROUP BY k + ) +SELECT k +FROM ordered_keys +ORDER BY idx, freq DESC +""", + ) + .format(source_table=source_table, json_col=self.identifier) + .as_string(), + ) + props = [prop[0] for prop in cur.fetchall()] + + prop_count = len(props) + ctx.scan_progress.total += prop_count + ctx.scan_progress.refresh() + ctx.scan_progress.update(1) + + for prop in props: + with ctx.conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +WITH + values AS ( + SELECT {json_col}->$1 as ld_value + FROM {table} ), value_and_types AS ( SELECT - prop - ,ldlite_system.jtype_of(ld_value) AS json_type + ldlite_system.jtype_of(ld_value) AS json_type ,ld_value FROM values WHERE NOT ldlite_system.jis_null(ld_value) ), array_values AS ( SELECT - v.prop - ,ldlite_system.jtype_of(a.ld_value) AS json_type - ,v.ld_value - FROM value_and_types v, ldlite_system.jexplode(v.ld_value) a + ldlite_system.jtype_of(a.ld_value) AS json_type + ,a.ld_value + FROM value_and_types v + CROSS JOIN LATERAL ( + SELECT s.ld_value + FROM ldlite_system.jexplode(v.ld_value) AS s + WHERE NOT ldlite_system.jis_null(s.ld_value) + LIMIT 3 + ) a WHERE v.json_type = 'array' ), all_values AS ( SELECT - prop - ,json_type + json_type ,ld_value ,FALSE AS is_array FROM value_and_types WHERE json_type <> 'array' UNION SELECT - prop - ,json_type + json_type ,ld_value ,TRUE AS is_array FROM array_values WHERE NOT ldlite_system.jis_null(ld_value) ) SELECT - prop - ,STRING_AGG(DISTINCT json_type, '|') AS json_type - ,bool_and(is_array) AS is_array - ,bool_and(ldlite_system.jis_uuid(ld_value)) AS is_uuid - ,bool_and(ldlite_system.jis_datetime(ld_value)) AS is_datetime - ,bool_and(ldlite_system.jis_float(ld_value)) AS is_float -FROM all_values -GROUP BY prop + (SELECT STRING_AGG(DISTINCT json_type, '|') FROM all_values) AS json_type + ,(SELECT BOOL_AND(is_array) FROM all_values) AS is_array + ,NOT EXISTS + ( + SELECT 1 FROM all_values + WHERE json_type = 'string' AND NOT ldlite_system.jis_uuid(ld_value) + ) AS is_uuid + ,NOT EXISTS + ( + SELECT 1 FROM all_values + WHERE json_type = 'string' AND NOT ldlite_system.jis_datetime(ld_value) + ) AS is_datetime + ,NOT EXISTS + ( + SELECT 1 FROM all_values + WHERE json_type = 'number' AND NOT ldlite_system.jis_float(ld_value) + ) AS is_float """, + ) + .format( + table=source_table, + json_col=self.identifier, + sample=sql.Literal(min(100, floor((100000 / total) * 100))), + ) + .as_string(), + (prop,), ) - .format(table=source_table, json_col=self.identifier) - .as_string(), - ) - - create_columns.extend( - [ - row.select_column(self.identifier, self.add(row)) - for row in [Metadata(*r) for r in cur.fetchall()] - ], - ) - - with conn.cursor() as cur: + if (row := cur.fetchone()) is not None and all( + c is not None for c in row + ): + meta = Metadata(prop, *row) + create_columns.append( + meta.select_column(self.identifier, self.add(meta)), + ) + if meta.is_object: + ctx.scan_progress.total += 1 + ctx.scan_progress.refresh() + + ctx.scan_progress.update(1) + + with ctx.conn.cursor() as cur: cur.execute( sql.SQL( """ @@ -210,22 +271,26 @@ def unnest( + """ SELECT {cols} -FROM ld_source; +FROM ld_source +WHERE NOT ldlite_system.jis_null({json_col}) """, ) .format( source_table=source_table, dest_table=dest_table, + json_col=self.identifier, cols=sql.SQL("\n ,").join(create_columns), ) .as_string(), ) + return True + def _carryover(self) -> Iterator[str]: for n in self.root.descendents: - if isinstance(n, ObjectNode) and not n.unnested: + if isinstance(n, ObjectNode) and not n.unnested and n.name != "jsonb": yield n.name - else: + if isinstance(n, ArrayNode): yield n.name yield from n.values @@ -264,7 +329,7 @@ def explode( o_col = self.name + "__o" create_columns: list[sql.Composable] = [ sql.SQL( - "(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)))::integer AS __id" + "(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)))::integer AS __id", ), *[sql.Identifier(v) for v in self.carryover], sql.SQL( @@ -306,7 +371,7 @@ def explode( def _carryover(self) -> Iterator[str]: for n in reversed(self.parents): - yield from [v for v in n.values if v != "__id"] + yield from [v for v in n.values if v not in ("__id", "jsonb")] @property def carryover(self) -> list[str]: diff --git a/src/ldlite/database/_postgres.py b/src/ldlite/database/_postgres.py index a9b4b81..2b51f9c 100644 --- a/src/ldlite/database/_postgres.py +++ b/src/ldlite/database/_postgres.py @@ -41,59 +41,7 @@ def _setup_jfuncs(conn: psycopg.Connection) -> None: IMMUTABLE PARALLEL SAFE; -CREATE OR REPLACE FUNCTION ldlite_system.jextract(j JSONB, p TEXT) RETURNS JSONB AS $$ -WITH jp AS ( - -- This is somewhat of a hack. - -- There isn't a really good way to get the element unchanged - -- which works for duckdb and postgres AND CRUCIALLY - -- has a similar syntax to everything else so that we don't - -- have to have special cases for exploding the array and it - -- can share all the same type checking / statement generation code. - -- We're pretending that postgres supports -> '$' style syntax like duckdb. - SELECT - CASE - WHEN p = '$' THEN j #> '{}' - ELSE j->p - END AS val - ,CASE - WHEN p = '$' THEN j #>> '{}' - ELSE j->>p - END AS str -) -SELECT - CASE - WHEN ldlite_system.jtype_of(jp.val) = 'string' THEN - CASE - WHEN lower(jp.str) = 'null' THEN 'null'::JSONB - WHEN length(jp.str) = 0 THEN 'null'::JSONB - ELSE jp.val - END - WHEN ldlite_system.jtype_of(jp.val) = 'array' THEN - CASE - WHEN jsonb_array_length(jsonb_path_query_array(jp.val, '$[*] ? (@ != null)')) = 0 THEN 'null'::JSONB - ELSE jsonb_path_query_array(jp.val, '$[*] ? (@ != null)') - END - WHEN ldlite_system.jtype_of(jp.val) = 'object' THEN - CASE - WHEN jp.str = '{}' THEN 'null'::JSONB - ELSE jp.val - END - ELSE jp.val - END -FROM jp; -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION ldlite_system.jextract_string(j JSONB, p TEXT) RETURNS TEXT AS $$ -SELECT ldlite_system.jextract(j, p) #>> '{}' -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j JSONB) RETURNS SETOF TEXT AS $$ +CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j JSONB) RETURNS TABLE (ld_key TEXT) AS $$ SELECT jsonb_object_keys(j); $$ LANGUAGE sql @@ -101,40 +49,31 @@ def _setup_jfuncs(conn: psycopg.Connection) -> None: PARALLEL SAFE; CREATE OR REPLACE FUNCTION ldlite_system.jis_uuid(j JSONB) RETURNS BOOLEAN AS $$ -SELECT - CASE - WHEN ldlite_system.jtype_of(j) = 'string' THEN j->>0 ~ '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$' - ELSE FALSE - END; +SELECT j::text ~* '^"[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}"$'; $$ LANGUAGE sql IMMUTABLE -PARALLEL SAFE; +PARALLEL SAFE +STRICT; CREATE OR REPLACE FUNCTION ldlite_system.jis_datetime(j JSONB) RETURNS BOOLEAN AS $$ -SELECT - CASE - WHEN ldlite_system.jtype_of(j) = 'string' THEN j->>0 ~ '^\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?$' - ELSE FALSE - END; +SELECT j::text ~ '^"\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?"$' $$ LANGUAGE sql IMMUTABLE -PARALLEL SAFE; +PARALLEL SAFE +STRICT; CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j JSONB) RETURNS BOOLEAN AS $$ -SELECT - CASE - WHEN ldlite_system.jtype_of(j) = 'number' THEN j->>0 LIKE '%.%' - ELSE FALSE - END; +SELECT SCALE((j)::numeric) > 0 $$ LANGUAGE sql IMMUTABLE -PARALLEL SAFE; +PARALLEL SAFE +STRICT; CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j JSONB) RETURNS BOOLEAN AS $$ -SELECT j IS NULL OR j = 'null'::JSONB; +SELECT j IS NULL OR j = 'null'::jsonb OR j #>> '{}' IN ('NULL', 'null', '', '{}', '[]') $$ LANGUAGE sql IMMUTABLE @@ -146,6 +85,14 @@ def _setup_jfuncs(conn: psycopg.Connection) -> None: LANGUAGE sql IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION ldlite_system.jself_string(j JSONB) RETURNS TEXT AS $$ +SELECT j #>> '{}' +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE; """, # noqa: E501 ) diff --git a/src/ldlite/database/_typed_database.py b/src/ldlite/database/_typed_database.py index eb4a1f3..1303931 100644 --- a/src/ldlite/database/_typed_database.py +++ b/src/ldlite/database/_typed_database.py @@ -9,16 +9,18 @@ import psycopg from psycopg import sql +from tqdm import tqdm from . import Database, LoadHistory -from ._expansion import ExpandContext, expand_nonmarc +from ._expansion import expand_nonmarc +from ._expansion.context import ExpandContext from ._prefix import Prefix if TYPE_CHECKING: from collections.abc import Callable, Sequence + from typing import NoReturn import duckdb - from tqdm import tqdm DB = TypeVar("DB", bound="duckdb.DuckDBPyConnection | psycopg.Connection") @@ -134,7 +136,7 @@ def _drop_extracted_tables( for (et,) in tables: cur.execute( sql.SQL("DROP TABLE IF EXISTS {table};") - .format(table=sql.Identifier(cast("str", et))) + .format(table=sql.Identifier(*cast("str", et).split("."))) .as_string(), ) cur.execute( @@ -184,7 +186,14 @@ def preprocess_source_table( @abstractmethod def source_table_cte_stmt(self, keep_source: bool) -> str: ... - def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[str]: + def expand_prefix( + self, + prefix: str, + json_depth: int, + keep_raw: bool, + scan_progress: tqdm[NoReturn] | None = None, + transform_progress: tqdm[NoReturn] | None = None, + ) -> list[str]: pfx = Prefix(prefix) with closing(self._conn_factory()) as conn: self._drop_extracted_tables(conn, pfx) @@ -224,6 +233,10 @@ def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[st pfx.output_table, self.preprocess_source_table, # type: ignore [arg-type] self.source_table_cte_stmt, + scan_progress if scan_progress is not None else tqdm(disable=True), + transform_progress + if transform_progress is not None + else tqdm(disable=True), ), ) @@ -239,14 +252,15 @@ def expand_prefix(self, prefix: str, json_depth: int, keep_raw: bool) -> list[st .format(catalog_table=pfx.catalog_table.id) .as_string(), ) - cur.executemany( - sql.SQL("INSERT INTO {catalog_table} VALUES ($1)") - .format( - catalog_table=pfx.catalog_table.id, + if len(created_tables) > 0: + cur.executemany( + sql.SQL("INSERT INTO {catalog_table} VALUES ($1)") + .format( + catalog_table=pfx.catalog_table.id, + ) + .as_string(), + [(pfx.catalog_table_row(t),) for t in created_tables], ) - .as_string(), - [(pfx.catalog_table_row(t),) for t in created_tables], - ) conn.commit() @@ -272,10 +286,10 @@ def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> N cur.execute( sql.SQL( r""" -SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS +SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = $1 AND - TABLE_NAME IN (SELECT TABLE_NAME FROM {catalog}) AND + TABLE_NAME IN (SELECT SPLIT_PART(TABLE_NAME, '.', -1) FROM {catalog}) AND ( DATA_TYPE IN ('UUID', 'uuid') OR COLUMN_NAME = 'id' OR @@ -299,8 +313,8 @@ def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> N sql.SQL("CREATE INDEX {name} ON {table} ({column});") .format( name=sql.Identifier(str(uuid4()).split("-")[0]), - table=sql.Identifier(*index[0].split(".")), - column=sql.Identifier(index[1]), + table=sql.Identifier(index[0], index[1]), + column=sql.Identifier(index[2]), ) .as_string(), ) diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index d89cf44..8b1f8c8 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -27,95 +27,16 @@ class JsonTC: assertion_params: tuple[Any, ...] -@parametrize( - p=[ - ("str", '"str_val"'), - ("str_empty", "null"), - ("num", "12"), - ("float", "16.3"), - ("bool", "true"), - ("obj", '{"k1":"v1","k2":"v2"}'), - ("obj_some", '{"k1":"v1","k2":null}'), - ("obj_empty", "null"), - ("arr_zero", "null"), - ("na", "null"), - ("na_str1", "null"), - ("na_str2", "null"), - ], -) -def case_jextract(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """SELECT ldlite_system.jextract(jc, $1){assertion} FROM j;""", - p[:1], - """= $2::{jtype}""", - p[1:], - ) - - -# Duckdb through 1.3 and 1.4 have different json comparison behavior here -# Whitespace matters in 1.4 and not 1.3 -# This makes the arrays text and compares the values as a workaround -@parametrize( - p=[ - ("arr_str", '["s1", "s2", "s3"]'), - ("arr_str_some", '["s1", "s2"]'), - ("arr_obj_some", '[{"k1":"v1"}]'), - ], -) -def case_jextract_duckdb(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """SELECT ldlite_system.jextract(jc, $1){assertion} FROM j;""", - p[:1], - """::text[] = $2::JSON::text[]""", - p[1:], - ) - - -# The differences betweeen postgres/duckdb here only matters for tests -# This can all be rectified when duckdb 1.4 is the minimum version -@parametrize( - p=[ - ("arr_str", '["s1", "s2", "s3"]'), - ("arr_str_some", '["s1", "s2"]'), - ("arr_obj_some", '[{"k1":"v1"}]'), - ], -) -def case_jextract_postgres(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """SELECT ldlite_system.jextract(jc, $1){assertion} FROM j;""", - p[:1], - """ = $2::JSONB""", - p[1:], - ) - - -@parametrize( - p=[ - ("str", "str_val"), - ("num", "12"), - ("float", "16.3"), - ("bool", "true"), - ("na",), - ("na_str1",), - ("na_str2",), - ], -) -def case_jextract_string(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """SELECT ldlite_system.jextract_string(jc, $1){assertion} FROM j;""", - p[:1], - """ = $2""" if len(p) == 2 else """ IS NULL""", - p[1:], - ) - - def case_jobject_keys() -> JsonTC: return JsonTC( """ {assertion} (SELECT e.jkey, a.jkey FROM (SELECT 'k1' jkey UNION SELECT 'k2' jkey) as e -FULL OUTER JOIN (SELECT ldlite_system.jobject_keys(jc->'obj') jkey FROM j) as a +FULL OUTER JOIN ( + SELECT k.ld_key as jkey + FROM j, ldlite_system.jobject_keys(j.jc->'obj') k +) as a USING (jkey) WHERE e.jkey IS NULL or a.jkey IS NULL) as q;""", (), @@ -177,7 +98,6 @@ def case_jexplode(p: tuple[Any, ...]) -> JsonTC: ("str", False), ("str_empty", False), ("num", False), - ("na", False), ("na_str1", False), ("na_str2", False), ("uuid_nof", False), @@ -198,10 +118,10 @@ def case_jis_uuid(p: tuple[Any, ...]) -> JsonTC: @parametrize( p=[ ("na", True), - ("obj_empty", False), - ("arr_zero", False), - ("na_str1", False), - ("na_str2", False), + ("obj_empty", True), + ("arr_zero", True), + ("na_str1", True), + ("na_str2", True), ], ) def case_jis_null(p: tuple[Any, ...]) -> JsonTC: @@ -218,7 +138,6 @@ def case_jis_null(p: tuple[Any, ...]) -> JsonTC: ("str", False), ("str_empty", False), ("num", False), - ("na", False), ("na_str1", False), ("na_str2", False), ("uuid_nof", False), @@ -239,15 +158,6 @@ def case_jis_datetime(p: tuple[Any, ...]) -> JsonTC: @parametrize( p=[ - ("str", False), - ("str_empty", False), - ("num", False), - ("na", False), - ("na_str1", False), - ("na_str2", False), - ("uuid_nof", False), - ("uuid", False), - ("dt", False), ("num", False), ("float", True), ], diff --git a/tests/test_query.py b/tests/test_query.py index 41ad44e..8993e7d 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -31,7 +31,7 @@ class QueryTC(MockedResponseTestCase): def case_one_table(json_depth: int) -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=json_depth, returns={ "purchaseOrders": [ @@ -48,7 +48,7 @@ def case_one_table(json_depth: int) -> QueryTC: ["id", "value"], [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], ), - "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + "prefix__tcatalog": (["table_name"], [("tests.prefix__t",)]), }, expected_indexes=[ ("prefix__t", "id"), @@ -60,7 +60,7 @@ def case_one_table(json_depth: int) -> QueryTC: def case_two_tables(json_depth: int) -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=json_depth, returns={ "purchaseOrders": [ @@ -109,7 +109,7 @@ def case_two_tables(json_depth: int) -> QueryTC: ), "prefix__tcatalog": ( ["table_name"], - [("prefix__t",), ("prefix__t__sub_objects",)], + [("tests.prefix__t",), ("tests.prefix__t__sub_objects",)], ), }, expected_indexes=[ @@ -124,7 +124,7 @@ def case_two_tables(json_depth: int) -> QueryTC: def case_table_no_expansion(json_depth: int) -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=json_depth, returns={ "purchaseOrders": [ @@ -149,7 +149,7 @@ def case_table_no_expansion(json_depth: int) -> QueryTC: def case_table_underexpansion() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=2, returns={ "purchaseOrders": [ @@ -194,7 +194,7 @@ def case_table_underexpansion() -> QueryTC: ), "prefix__tcatalog": ( ["table_name"], - [("prefix__t",), ("prefix__t__sub_objects",)], + [("tests.prefix__t",), ("tests.prefix__t__sub_objects",)], ), }, ) @@ -204,7 +204,7 @@ def case_table_underexpansion() -> QueryTC: def case_three_tables(json_depth: int) -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=json_depth, returns={ "purchaseOrders": [ @@ -254,9 +254,9 @@ def case_three_tables(json_depth: int) -> QueryTC: "prefix__tcatalog": ( ["table_name"], [ - ("prefix__t",), - ("prefix__t__sub_objects",), - ("prefix__t__sub_objects__sub_sub_objects",), + ("tests.prefix__t",), + ("tests.prefix__t__sub_objects",), + ("tests.prefix__t__sub_objects__sub_sub_objects",), ], ), }, @@ -277,7 +277,7 @@ def case_three_tables(json_depth: int) -> QueryTC: def case_nested_object() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=2, returns={ "purchaseOrders": [ @@ -307,7 +307,7 @@ def case_nested_object() -> QueryTC: ), "prefix__tcatalog": ( ["table_name"], - [("prefix__t",)], + [("tests.prefix__t",)], ), }, expected_indexes=[ @@ -320,7 +320,7 @@ def case_nested_object() -> QueryTC: def case_doubly_nested_object() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=3, returns={ "purchaseOrders": [ @@ -361,7 +361,7 @@ def case_doubly_nested_object() -> QueryTC: ), "prefix__tcatalog": ( ["table_name"], - [("prefix__t",)], + [("tests.prefix__t",)], ), }, expected_indexes=[ @@ -375,7 +375,7 @@ def case_doubly_nested_object() -> QueryTC: def case_nested_object_underexpansion() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=1, returns={ "purchaseOrders": [ @@ -405,7 +405,7 @@ def case_nested_object_underexpansion() -> QueryTC: ), "prefix__tcatalog": ( ["table_name"], - [("prefix__t",)], + [("tests.prefix__t",)], ), }, ) @@ -414,7 +414,7 @@ def case_nested_object_underexpansion() -> QueryTC: def case_tables_and_lists() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=3, returns={ "purchaseOrders": [ @@ -502,9 +502,9 @@ def case_tables_and_lists() -> QueryTC: "prefix__tcatalog": ( ["table_name"], [ - ("prefix__t",), - ("prefix__t__sub_object__sub_objects",), - ("prefix__t__sub_objects",), + ("tests.prefix__t",), + ("tests.prefix__t__sub_object__sub_objects",), + ("tests.prefix__t__sub_objects",), ], ), }, @@ -518,7 +518,7 @@ def case_tables_and_lists() -> QueryTC: def case_id_generation() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=4, returns={ "purchaseOrders": [ @@ -591,7 +591,7 @@ def case_id_generation() -> QueryTC: def case_indexing_id_like() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=4, returns={ "purchaseOrders": [ @@ -623,7 +623,7 @@ def case_indexing_id_like() -> QueryTC: def case_drop_raw(json_depth: int) -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=json_depth, keep_raw=False, returns={ @@ -641,7 +641,7 @@ def case_drop_raw(json_depth: int) -> QueryTC: ["id", "value"], [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], ), - "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + "prefix__tcatalog": (["table_name"], [("tests.prefix__t",)]), }, expected_indexes=[ ("prefix__t", "id"), @@ -654,7 +654,7 @@ def case_drop_raw(json_depth: int) -> QueryTC: def case_null_records() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=1, returns={ "purchaseOrders": [ @@ -677,7 +677,7 @@ def case_null_records() -> QueryTC: def case_erm_keys() -> QueryTC: return QueryTC( Call( - "prefix", + "tests.prefix", json_depth=3, returns={ "pageSize": 30, @@ -699,7 +699,7 @@ def case_erm_keys() -> QueryTC: ["id", "value"], [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], ), - "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + "prefix__tcatalog": (["table_name"], [("tests.prefix__t",)]), }, expected_indexes=[ ("prefix__t", "id"), @@ -732,7 +732,6 @@ def _act(uut: "ldlite.LDLite", tc: QueryTC) -> None: def _assert( conn: "dbapi.DBAPIConnection", - res_schema: str, # TODO: have schema be part of tc tc: QueryTC, ) -> None: with closing(conn.cursor()) as cur: @@ -740,9 +739,8 @@ def _assert( """ SELECT table_name FROM information_schema.tables - WHERE table_schema=$1 + WHERE table_schema='tests' """, - (res_schema,), ) assert sorted([r[0] for r in cur.fetchall()]) == sorted(tc.expected_tables) @@ -758,7 +756,7 @@ def _assert( for c in cols ], ), - table=sql.Identifier(table), + table=sql.Identifier("tests", table), ) .as_string(), ) @@ -820,7 +818,7 @@ def test_duckdb( _act(uut, tc) with duckdb.connect(dsn) as conn: - _assert(cast("dbapi.DBAPIConnection", conn), "main", tc) + _assert(cast("dbapi.DBAPIConnection", conn), tc) @mock.patch("httpx_folio.auth.httpx.post") @@ -842,4 +840,4 @@ def test_postgres( _act(uut, tc) with psycopg.connect(dsn, cursor_factory=psycopg.RawCursor) as conn: - _assert(cast("dbapi.DBAPIConnection", conn), "public", tc) + _assert(cast("dbapi.DBAPIConnection", conn), tc) From 96f1ce6376d5bc78df765d708cad0b588658bc80 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Tue, 10 Mar 2026 14:17:25 -0400 Subject: [PATCH 18/25] Extract more specific datatypes (#69) Another huge benefit of the transformation refactor is that we can more easily reason about how the transformation is happening and how datatype conversion happens. This converts columns that have been text into datetimes. It also gets makes the numeric types more specific. As a nice side result of these changes the size of these tables should go down significantly and also they'll be faster even without indexes. I don't love the pytz is a requirement in order for duckdb to have the timestamptz type. Hopefully they fix this upstream at some point. --- pylock.lint.toml | 104 ++++++++++++--------- pylock.maximal.toml | 50 ++++++---- pylock.minimal.toml | 14 ++- pylock.toml | 104 ++++++++++++--------- pyproject.toml | 3 + src/ldlite/_csv.py | 3 + src/ldlite/database/_duckdb.py | 4 + src/ldlite/database/_expansion/metadata.py | 61 +++++------- src/ldlite/database/_expansion/nodes.py | 12 ++- src/ldlite/database/_postgres.py | 8 ++ tests/test_expansion.py | 38 +++++--- tests/test_json_operators.py | 25 +++++ 12 files changed, 261 insertions(+), 165 deletions(-) diff --git a/pylock.lint.toml b/pylock.lint.toml index fb6f477..b0cd92d 100644 --- a/pylock.lint.toml +++ b/pylock.lint.toml @@ -223,44 +223,44 @@ dependencies = [] [[packages]] name = "duckdb" -version = "1.4.4" -requires-python = ">=3.9.0" -sdist = {name = "duckdb-1.4.4.tar.gz", url = "https://files.pythonhosted.org/packages/36/9d/ab66a06e416d71b7bdcb9904cdf8d4db3379ef632bb8e9495646702d9718/duckdb-1.4.4.tar.gz", hashes = {sha256 = "8bba52fd2acb67668a4615ee17ee51814124223de836d9e2fdcbc4c9021b3d3c"}} -wheels = [ - {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/97/a6/f19e2864e651b0bd8e4db2b0c455e7e0d71e0d4cd2cd9cc052f518e43eb3/duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "25874f8b1355e96178079e37312c3ba6d61a2354f51319dae860cf21335c3a20"}}, - {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/0e/93/8a24e932c67414fd2c45bed83218e62b73348996bf859eda020c224774b2/duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "452c5b5d6c349dc5d1154eb2062ee547296fcbd0c20e9df1ed00b5e1809089da"}}, - {name = "duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/62/13/e5378ff5bb1d4397655d840b34b642b1b23cdd82ae19599e62dc4b9461c9/duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8e5c2d8a0452df55e092959c0bfc8ab8897ac3ea0f754cb3b0ab3e165cd79aff"}}, - {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2d/94/24364da564b27aeebe44481f15bd0197a0b535ec93f188a6b1b98c22f082/duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1af6e76fe8bd24875dc56dd8e38300d64dc708cd2e772f67b9fbc635cc3066a3"}}, - {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/0a/6ae31b2914b4dc34243279b2301554bcbc5f1a09ccc82600486c49ab71d1/duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d0440f59e0cd9936a9ebfcf7a13312eda480c79214ffed3878d75947fc3b7d6d"}}, - {name = "duckdb-1.4.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d2/b1/fd5c37c53d45efe979f67e9bd49aaceef640147bb18f0699a19edd1874d6/duckdb-1.4.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "59c8d76016dde854beab844935b1ec31de358d4053e792988108e995b18c08e7"}}, - {name = "duckdb-1.4.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/2d/13e6024e613679d8a489dd922f199ef4b1d08a456a58eadd96dc2f05171f/duckdb-1.4.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "53cd6423136ab44383ec9955aefe7599b3fb3dd1fe006161e6396d8167e0e0d4"}}, - {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/7f/fe/64810fee20030f2bf96ce28b527060564864ce5b934b50888eda2cbf99dd/duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "337f8b24e89bc2e12dadcfe87b4eb1c00fd920f68ab07bc9b70960d6523b8bc3"}}, - {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9c/9b/3c7c5e48456b69365d952ac201666053de2700f5b0144a699a4dc6854507/duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "0509b39ea7af8cff0198a99d206dca753c62844adab54e545984c2e2c1381616"}}, - {name = "duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a6/7b/64e68a7b857ed0340045501535a0da99ea5d9d5ea3708fec0afb8663eb27/duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "fb94de6d023de9d79b7edc1ae07ee1d0b4f5fa8a9dcec799650b5befdf7aafec"}}, - {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/09/5b/3e7aa490841784d223de61beb2ae64e82331501bf5a415dc87a0e27b4663/duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0d636ceda422e7babd5e2f7275f6a0d1a3405e6a01873f00d38b72118d30c10b"}}, - {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/53/32/256df3dbaa198c58539ad94f9a41e98c2c8ff23f126b8f5f52c7dcd0a738/duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "7df7351328ffb812a4a289732f500d621e7de9942a3a2c9b6d4afcf4c0e72526"}}, - {name = "duckdb-1.4.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a4/f0/620323fd87062ea43e527a2d5ed9e55b525e0847c17d3b307094ddab98a2/duckdb-1.4.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "6fb1225a9ea5877421481d59a6c556a9532c32c16c7ae6ca8d127e2b878c9389"}}, - {name = "duckdb-1.4.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/07/a397fdb7c95388ba9c055b9a3d38dfee92093f4427bc6946cf9543b1d216/duckdb-1.4.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "f28a18cc790217e5b347bb91b2cab27aafc557c58d3d8382e04b4fe55d0c3f66"}}, - {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/58/33/beadaa69f8458afe466126f2c5ee48c4759cc9d5d784f8703d44e0b52c3c/duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "ddcfd9c6ff234da603a1edd5fd8ae6107f4d042f74951b65f91bc5e2643856b3"}}, - {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/66/82413f386df10467affc87f65bac095b7c88dbd9c767584164d5f4dc4cb8/duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "6792ca647216bd5c4ff16396e4591cfa9b4a72e5ad7cdd312cec6d67e8431a7c"}}, - {name = "duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/8c/c13d396fd4e9bf970916dc5b4fea410c1b10fe531069aea65f1dcf849a71/duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "1f8d55843cc940e36261689054f7dfb6ce35b1f5b0953b0d355b6adb654b0d52"}}, - {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/77/2446a0b44226bb95217748d911c7ca66a66ca10f6481d5178d9370819631/duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c65d15c440c31e06baaebfd2c06d71ce877e132779d309f1edf0a85d23c07e92"}}, - {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/2e/a3/97715bba30040572fb15d02c26f36be988d48bc00501e7ac02b1d65ef9d0/duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "b297eff642503fd435a9de5a9cb7db4eccb6f61d61a55b30d2636023f149855f"}}, - {name = "duckdb-1.4.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/0a/18b9167adf528cbe3867ef8a84a5f19f37bedccb606a8a9e59cfea1880c8/duckdb-1.4.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d525de5f282b03aa8be6db86b1abffdceae5f1055113a03d5b50cd2fb8cf2ef8"}}, - {name = "duckdb-1.4.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f8/15/37af97f5717818f3d82d57414299c293b321ac83e048c0a90bb8b6a09072/duckdb-1.4.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "50f2eb173c573811b44aba51176da7a4e5c487113982be6a6a1c37337ec5fa57"}}, - {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/04/68/19233412033a2bc5a144a3f531f64e3548d4487251e3f16b56c31411a06f/duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5ba684f498d4e924c7e8f30dd157da8da34c8479746c5011b6c0e037e9c60ad2"}}, - {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b3/3e/cec70e546c298ab76d80b990109e111068d82cca67942c42328eaa7d6fdb/duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "5536eb952a8aa6ae56469362e344d4e6403cc945a80bc8c5c2ebdd85d85eb64b"}}, - {name = "duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/f0/cf4241a040ec4f571859a738007ec773b642fbc27df4cbcf34b0c32ea559/duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "47dd4162da6a2be59a0aef640eb08d6360df1cf83c317dcc127836daaf3b7f7c"}}, - {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/11/64/de2bb4ec1e35ec9ebf6090a95b930fc56934a0ad6f34a24c5972a14a77ef/duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6cb357cfa3403910e79e2eb46c8e445bb1ee2fd62e9e9588c6b999df4256abc1"}}, - {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/a2/ac0f5ee16df890d141304bcd48733516b7202c0de34cd3555634d6eb4551/duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4c25d5b0febda02b7944e94fdae95aecf952797afc8cb920f677b46a7c251955"}}, - {name = "duckdb-1.4.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/37/a2/9a3402edeedaecf72de05fe9ff7f0303d701b8dfc136aea4a4be1a5f7eee/duckdb-1.4.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6703dd1bb650025b3771552333d305d62ddd7ff182de121483d4e042ea6e2e00"}}, - {name = "duckdb-1.4.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f6/e6/052ea6dcdf35b259fd182eff3efd8d75a071de4010c9807556098df137b9/duckdb-1.4.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bf138201f56e5d6fc276a25138341b3523e2f84733613fc43f02c54465619a95"}}, - {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/a2/9f/67a75f1e88f84946909826fa7aadd0c4b0dc067f24956142751fd9d59fe6/duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "e870a441cb1c41d556205deb665749f26347ed13b3a247b53714f5d589596977"}}, - {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/6b/7a/e9277d0567884c21f345ad43cc01aeaa2abe566d5fdf22e35c3861dd44fa/duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "49123b579e4a6323e65139210cd72dddc593a72d840211556b60f9703bda8526"}}, - {name = "duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/96/3a7630d2779d2bae6f3cdf540a088ed45166adefd3c429971e5b85ce8f84/duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "5e1933fac5293fea5926b0ee75a55b8cfe7f516d867310a5b251831ab61fe62b"}}, - {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/ad/f62a3a65d200e8afc1f75cf0dd3f0aa84ef0dd07c484414a11f2abed810e/duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "707530f6637e91dc4b8125260595299ec9dd157c09f5d16c4186c5988bfbd09a"}}, - {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/5f/23bd586ecb21273b41b5aa4b16fd88b7fecb53ed48d897273651c0c3d66f/duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "453b115f4777467f35103d8081770ac2f223fb5799178db5b06186e3ab51d1f2"}}, - {name = "duckdb-1.4.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/d0/4ce78bf341c930d4a22a56cb686bfc2c975eaf25f653a7ac25e3929d98bb/duckdb-1.4.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "a3c8542db7ffb128aceb7f3b35502ebaddcd4f73f1227569306cc34bad06680c"}}, +version = "1.5.0" +requires-python = ">=3.10.0" +sdist = {name = "duckdb-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/ee/11/e05a7eb73a373d523e45d83c261025e02bc31ebf868e6282c30c4d02cc59/duckdb-1.5.0.tar.gz", hashes = {sha256 = "f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd"}} +wheels = [ + {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/66/9f/dd806d4e8ecd99006eb240068f34e1054533da1857ad06ac726305cd102d/duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa"}}, + {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/c2/7b7b8a5c65d5535c88a513e267b5e6d7a55ab3e9b67e4ddd474454653268/duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021"}}, + {name = "duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/23/c5/9a52a2cdb228b8d8d191a603254364d929274d9cc7d285beada8f7daa712/duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985"}}, + {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/68/646045cb97982702a8a143dc2e45f3bdcb79fbe2d559a98d74b8c160e5e2/duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113"}}, + {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/1b/5abf0c7f38febb3b4a231c784223fceccfd3f2bfd957699d786f46e41ce6/duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c"}}, + {name = "duckdb-1.5.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/a4/a90f2901cc0a1ce7ca4f0564b8492b9dbfe048a6395b27933d46ae9be473/duckdb-1.5.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977"}}, + {name = "duckdb-1.5.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/64/aa/f14dd5e241ec80d9f9d82196ca65e0c53badfc8a7a619d5497c5626657ad/duckdb-1.5.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36"}}, + {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/35/5d/af5501221f42e4e3662c047ecec4dcd0761229fceeba3c67ad4d9d8741df/duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d"}}, + {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/bd/a278d73fedbd3783bf9aedb09cad4171fe8e55bd522952a84f6849522eb6/duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b"}}, + {name = "duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/76/fc/c916e928606946209c20fb50898dabf120241fb528a244e2bd8cde1bd9e2/duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656"}}, + {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/53/07/1390e69db922423b2e111e32ed342b3e8fad0a31c144db70681ea1ba4d56/duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6"}}, + {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/54/13/b58d718415cde993823a54952ea511d2612302f1d2bc220549d0cef752a4/duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f"}}, + {name = "duckdb-1.5.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e0/96/4460429651e371eb5ff745a4790e7fa0509c7a58c71fc4f0f893404c9646/duckdb-1.5.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b"}}, + {name = "duckdb-1.5.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ba/54/6d5b805113214b830fa3c267bb3383fb8febaa30760d0162ef59aadb110a/duckdb-1.5.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8"}}, + {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/43/73/120e673e48ae25aaf689044c25ef51b0ea1d088563c9a2532612aea18e0a/duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd"}}, + {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/21/e9/61143471958d36d3f3e764cb4cd43330be208ddbff1c78d3310b9ee67fe8/duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375"}}, + {name = "duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4f/71/76e37c9a599ad89dd944e6cbb3e6a8ad196944a421758e83adea507637b6/duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59"}}, + {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/b8/de1831656d5d13173e27c79c7259c8b9a7bdc314fdc8920604838ea4c46d/duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30"}}, + {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/8d/33d349a3bcbd3e9b7b4e904c19d5b97f058c4c20791b89a8d6323bb93dce/duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6"}}, + {name = "duckdb-1.5.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/ec/591a4cad582fae04bc8f8b4a435eceaaaf3838cf0ca771daae16a3c2995b/duckdb-1.5.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86"}}, + {name = "duckdb-1.5.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/db/62/42e0a13f9919173bec121c0ff702406e1cdd91d8084c3e0b3412508c3891/duckdb-1.5.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7"}}, + {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/01/0c/0282b10a1c96810606b916b8d58a03f2131bd3ede14d2851f58b0b860e7c/duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86"}}, + {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/e8/cbbc920078a794f24f63017fc55c9cbdb17d6fb94d3973f479b2d9f2983d/duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41"}}, + {name = "duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/31/b6/6cae794d5856259b0060f79d5db71c7fdba043950eaa6a9d72b0bad16095/duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16"}}, + {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/82/07/aba3887658b93a36ce702dd00ca6a6422de3d14c7ee3a4b4c03ea20a99c0/duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2"}}, + {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/a2/723e6df48754e468fa50d7878eb860906c975eafe317c4134a8482ca220e/duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417"}}, + {name = "duckdb-1.5.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/03/af/4dcbdf8f2349ed0b054c254ec59bc362ce6ddf603af35f770124c0984686/duckdb-1.5.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2"}}, + {name = "duckdb-1.5.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/60/5e/1bb7e75a63bf3dc49bc5a2cd27a65ffeef151f52a32db980983516f2d9f6/duckdb-1.5.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298"}}, + {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/e0/5d/8fa129bbd604d0e91aa9a0a407e7d2acc559b6024c3f887868fd7a13871d/duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78"}}, + {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/0c/31/db320641a262a897755e634d16838c98d5ca7dc91f4e096e104e244a3a01/duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa"}}, + {name = "duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0b/45/5725684794fbabf54d8dbae5247685799a6bf8e1e930ebff3a76a726772c/duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381"}}, + {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/27/68/f110c66b43e27191d7e53d3587e118568b73d66f23cb9bd6c7e0a560fd6d/duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999"}}, + {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/ec/9d/46affc9257377cbc865e494650312a7a08a56e85aa8d702eb297bec430b7/duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730"}}, + {name = "duckdb-1.5.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/34/dac03ab7340989cda258655387959c88342ea3b44949751391267bcbc830/duckdb-1.5.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac"}}, ] marker = "\"default\" in dependency_groups" @@ -407,10 +407,10 @@ dependencies = [ [[packages]] name = "pytest-cases" -version = "3.9.1" -sdist = {name = "pytest_cases-3.9.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/69/8b41e074e9e1a9fa85c3765971f213e1b8d4a2f648b457af32dea792bdb8/pytest_cases-3.9.1.tar.gz", hashes = {sha256 = "c4e181f1b525c931a318d4812fa8de656c2c8fb77fccf1571ecf0cc5fe8e7f8f"}} +version = "3.10.1" +sdist = {name = "pytest_cases-3.10.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/a2/c7abc3b606125cf3732e8e613092b0e2549365e824b5f37972125c22806b/pytest_cases-3.10.1.tar.gz", hashes = {sha256 = "451f9e3ecd5d2d81a4362c10c441126f5b3d1ae3a7efaf59f60b1fb930df2d69"}} wheels = [ - {name = "pytest_cases-3.9.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/92/82/db006f1d06e5d31805ac47f9ce979937e3d026292f2759543b744f8040be/pytest_cases-3.9.1-py2.py3-none-any.whl",hashes = {sha256 = "60507716650c5ed1ce4a36a3c137f1c3ec58f4fef1ee8678404be074612fcd21"}}, + {name = "pytest_cases-3.10.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/61/f2/7a29fb0571562034b05c38dceabba48dcc622be5d6c5448db80779e55de7/pytest_cases-3.10.1-py2.py3-none-any.whl",hashes = {sha256 = "0deb8a85b6132e44adbc1cfc57897c6a624ec23f48ab445a43c7d56a6b9315a4"}}, ] marker = "\"test\" in dependency_groups" @@ -422,6 +422,18 @@ dependencies = [ "pytest", ] +[[packages]] +name = "pytz" +version = "2026.1.post1" +sdist = {name = "pytz-2026.1.post1.tar.gz", url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hashes = {sha256 = "3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1"}} +wheels = [ + {name = "pytz-2026.1.post1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl",hashes = {sha256 = "f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + [[packages]] name = "tqdm" version = "4.67.3" @@ -440,11 +452,11 @@ dependencies = [ [[packages]] name = "types-tqdm" -version = "4.67.3.20260205" -requires-python = ">=3.9" -sdist = {name = "types_tqdm-4.67.3.20260205.tar.gz", url = "https://files.pythonhosted.org/packages/53/46/790b9872523a48163bdda87d47849b4466017640e5259d06eed539340afd/types_tqdm-4.67.3.20260205.tar.gz", hashes = {sha256 = "f3023682d4aa3bbbf908c8c6bb35f35692d319460d9bbd3e646e8852f3dd9f85"}} +version = "4.67.3.20260303" +requires-python = ">=3.10" +sdist = {name = "types_tqdm-4.67.3.20260303.tar.gz", url = "https://files.pythonhosted.org/packages/e1/64/3e7cb0f40c4bf9578098b6873df33a96f7e0de90f3a039e614d22bfde40a/types_tqdm-4.67.3.20260303.tar.gz", hashes = {sha256 = "7bfddb506a75aedb4030fabf4f05c5638c9a3bbdf900d54ec6c82be9034bfb96"}} wheels = [ - {name = "types_tqdm-4.67.3.20260205-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl",hashes = {sha256 = "85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173"}}, + {name = "types_tqdm-4.67.3.20260303-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/37/32/e4a1fce59155c74082f1a42d0ffafa59652bfb8cff35b04d56333877748e/types_tqdm-4.67.3.20260303-py3-none-any.whl",hashes = {sha256 = "459decf677e4b05cef36f9012ef8d6e20578edefb6b78c15bd0b546247eda62d"}}, ] marker = "\"types\" in dependency_groups" @@ -820,7 +832,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} +hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.maximal.toml b/pylock.maximal.toml index 70c5380..346435c 100644 --- a/pylock.maximal.toml +++ b/pylock.maximal.toml @@ -125,17 +125,17 @@ dependencies = [] [[packages]] name = "duckdb" -version = "1.4.4" -requires-python = ">=3.9.0" -sdist = {name = "duckdb-1.4.4.tar.gz", url = "https://files.pythonhosted.org/packages/36/9d/ab66a06e416d71b7bdcb9904cdf8d4db3379ef632bb8e9495646702d9718/duckdb-1.4.4.tar.gz", hashes = {sha256 = "8bba52fd2acb67668a4615ee17ee51814124223de836d9e2fdcbc4c9021b3d3c"}} -wheels = [ - {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/97/a6/f19e2864e651b0bd8e4db2b0c455e7e0d71e0d4cd2cd9cc052f518e43eb3/duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "25874f8b1355e96178079e37312c3ba6d61a2354f51319dae860cf21335c3a20"}}, - {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/0e/93/8a24e932c67414fd2c45bed83218e62b73348996bf859eda020c224774b2/duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "452c5b5d6c349dc5d1154eb2062ee547296fcbd0c20e9df1ed00b5e1809089da"}}, - {name = "duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/62/13/e5378ff5bb1d4397655d840b34b642b1b23cdd82ae19599e62dc4b9461c9/duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8e5c2d8a0452df55e092959c0bfc8ab8897ac3ea0f754cb3b0ab3e165cd79aff"}}, - {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2d/94/24364da564b27aeebe44481f15bd0197a0b535ec93f188a6b1b98c22f082/duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1af6e76fe8bd24875dc56dd8e38300d64dc708cd2e772f67b9fbc635cc3066a3"}}, - {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/0a/6ae31b2914b4dc34243279b2301554bcbc5f1a09ccc82600486c49ab71d1/duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d0440f59e0cd9936a9ebfcf7a13312eda480c79214ffed3878d75947fc3b7d6d"}}, - {name = "duckdb-1.4.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d2/b1/fd5c37c53d45efe979f67e9bd49aaceef640147bb18f0699a19edd1874d6/duckdb-1.4.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "59c8d76016dde854beab844935b1ec31de358d4053e792988108e995b18c08e7"}}, - {name = "duckdb-1.4.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/2d/13e6024e613679d8a489dd922f199ef4b1d08a456a58eadd96dc2f05171f/duckdb-1.4.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "53cd6423136ab44383ec9955aefe7599b3fb3dd1fe006161e6396d8167e0e0d4"}}, +version = "1.5.0" +requires-python = ">=3.10.0" +sdist = {name = "duckdb-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/ee/11/e05a7eb73a373d523e45d83c261025e02bc31ebf868e6282c30c4d02cc59/duckdb-1.5.0.tar.gz", hashes = {sha256 = "f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd"}} +wheels = [ + {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/66/9f/dd806d4e8ecd99006eb240068f34e1054533da1857ad06ac726305cd102d/duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa"}}, + {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/c2/7b7b8a5c65d5535c88a513e267b5e6d7a55ab3e9b67e4ddd474454653268/duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021"}}, + {name = "duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/23/c5/9a52a2cdb228b8d8d191a603254364d929274d9cc7d285beada8f7daa712/duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985"}}, + {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/68/646045cb97982702a8a143dc2e45f3bdcb79fbe2d559a98d74b8c160e5e2/duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113"}}, + {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/1b/5abf0c7f38febb3b4a231c784223fceccfd3f2bfd957699d786f46e41ce6/duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c"}}, + {name = "duckdb-1.5.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/a4/a90f2901cc0a1ce7ca4f0564b8492b9dbfe048a6395b27933d46ae9be473/duckdb-1.5.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977"}}, + {name = "duckdb-1.5.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/64/aa/f14dd5e241ec80d9f9d82196ca65e0c53badfc8a7a619d5497c5626657ad/duckdb-1.5.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36"}}, ] marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" @@ -224,10 +224,10 @@ dependencies = [ [[packages]] name = "pytest-cases" -version = "3.9.1" -sdist = {name = "pytest_cases-3.9.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/69/8b41e074e9e1a9fa85c3765971f213e1b8d4a2f648b457af32dea792bdb8/pytest_cases-3.9.1.tar.gz", hashes = {sha256 = "c4e181f1b525c931a318d4812fa8de656c2c8fb77fccf1571ecf0cc5fe8e7f8f"}} +version = "3.10.1" +sdist = {name = "pytest_cases-3.10.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/a2/c7abc3b606125cf3732e8e613092b0e2549365e824b5f37972125c22806b/pytest_cases-3.10.1.tar.gz", hashes = {sha256 = "451f9e3ecd5d2d81a4362c10c441126f5b3d1ae3a7efaf59f60b1fb930df2d69"}} wheels = [ - {name = "pytest_cases-3.9.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/92/82/db006f1d06e5d31805ac47f9ce979937e3d026292f2759543b744f8040be/pytest_cases-3.9.1-py2.py3-none-any.whl",hashes = {sha256 = "60507716650c5ed1ce4a36a3c137f1c3ec58f4fef1ee8678404be074612fcd21"}}, + {name = "pytest_cases-3.10.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/61/f2/7a29fb0571562034b05c38dceabba48dcc622be5d6c5448db80779e55de7/pytest_cases-3.10.1-py2.py3-none-any.whl",hashes = {sha256 = "0deb8a85b6132e44adbc1cfc57897c6a624ec23f48ab445a43c7d56a6b9315a4"}}, ] marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" @@ -239,6 +239,18 @@ dependencies = [ "pytest", ] +[[packages]] +name = "pytz" +version = "2026.1.post1" +sdist = {name = "pytz-2026.1.post1.tar.gz", url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hashes = {sha256 = "3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1"}} +wheels = [ + {name = "pytz-2026.1.post1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl",hashes = {sha256 = "f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a"}}, +] +marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + [[packages]] name = "tqdm" version = "4.67.3" @@ -257,11 +269,11 @@ dependencies = [ [[packages]] name = "types-tqdm" -version = "4.67.3.20260205" -requires-python = ">=3.9" -sdist = {name = "types_tqdm-4.67.3.20260205.tar.gz", url = "https://files.pythonhosted.org/packages/53/46/790b9872523a48163bdda87d47849b4466017640e5259d06eed539340afd/types_tqdm-4.67.3.20260205.tar.gz", hashes = {sha256 = "f3023682d4aa3bbbf908c8c6bb35f35692d319460d9bbd3e646e8852f3dd9f85"}} +version = "4.67.3.20260303" +requires-python = ">=3.10" +sdist = {name = "types_tqdm-4.67.3.20260303.tar.gz", url = "https://files.pythonhosted.org/packages/e1/64/3e7cb0f40c4bf9578098b6873df33a96f7e0de90f3a039e614d22bfde40a/types_tqdm-4.67.3.20260303.tar.gz", hashes = {sha256 = "7bfddb506a75aedb4030fabf4f05c5638c9a3bbdf900d54ec6c82be9034bfb96"}} wheels = [ - {name = "types_tqdm-4.67.3.20260205-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl",hashes = {sha256 = "85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173"}}, + {name = "types_tqdm-4.67.3.20260303-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/37/32/e4a1fce59155c74082f1a42d0ffafa59652bfb8cff35b04d56333877748e/types_tqdm-4.67.3.20260303-py3-none-any.whl",hashes = {sha256 = "459decf677e4b05cef36f9012ef8d6e20578edefb6b78c15bd0b546247eda62d"}}, ] marker = "python_version >= \"3.14\" and \"types\" in dependency_groups" @@ -564,7 +576,7 @@ marker = "sys_platform == \"win32\" and python_version >= \"3.14\" and \"default dependencies = [] [tool.pdm] -hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} +hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.minimal.toml b/pylock.minimal.toml index 5c62add..f47e824 100644 --- a/pylock.minimal.toml +++ b/pylock.minimal.toml @@ -348,6 +348,18 @@ dependencies = [ "pytest", ] +[[packages]] +name = "pytz" +version = "2021.3" +sdist = {name = "pytz-2021.3.tar.gz", url = "https://files.pythonhosted.org/packages/e3/8e/1cde9d002f48a940b9d9d38820aaf444b229450c0854bdf15305ce4a3d1a/pytz-2021.3.tar.gz", hashes = {sha256 = "acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}} +wheels = [ + {name = "pytz-2021.3-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d3/e3/d9f046b5d1c94a3aeab15f1f867aa414f8ee9d196fae6865f1d6a0ee1a0b/pytz-2021.3-py2.py3-none-any.whl",hashes = {sha256 = "3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + [[packages]] name = "tqdm" version = "4.64.0" @@ -715,7 +727,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} +hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} strategy = ["direct_minimal_versions", "inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.toml b/pylock.toml index fb6f477..b0cd92d 100644 --- a/pylock.toml +++ b/pylock.toml @@ -223,44 +223,44 @@ dependencies = [] [[packages]] name = "duckdb" -version = "1.4.4" -requires-python = ">=3.9.0" -sdist = {name = "duckdb-1.4.4.tar.gz", url = "https://files.pythonhosted.org/packages/36/9d/ab66a06e416d71b7bdcb9904cdf8d4db3379ef632bb8e9495646702d9718/duckdb-1.4.4.tar.gz", hashes = {sha256 = "8bba52fd2acb67668a4615ee17ee51814124223de836d9e2fdcbc4c9021b3d3c"}} -wheels = [ - {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/97/a6/f19e2864e651b0bd8e4db2b0c455e7e0d71e0d4cd2cd9cc052f518e43eb3/duckdb-1.4.4-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "25874f8b1355e96178079e37312c3ba6d61a2354f51319dae860cf21335c3a20"}}, - {name = "duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/0e/93/8a24e932c67414fd2c45bed83218e62b73348996bf859eda020c224774b2/duckdb-1.4.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "452c5b5d6c349dc5d1154eb2062ee547296fcbd0c20e9df1ed00b5e1809089da"}}, - {name = "duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/62/13/e5378ff5bb1d4397655d840b34b642b1b23cdd82ae19599e62dc4b9461c9/duckdb-1.4.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "8e5c2d8a0452df55e092959c0bfc8ab8897ac3ea0f754cb3b0ab3e165cd79aff"}}, - {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2d/94/24364da564b27aeebe44481f15bd0197a0b535ec93f188a6b1b98c22f082/duckdb-1.4.4-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1af6e76fe8bd24875dc56dd8e38300d64dc708cd2e772f67b9fbc635cc3066a3"}}, - {name = "duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/0a/6ae31b2914b4dc34243279b2301554bcbc5f1a09ccc82600486c49ab71d1/duckdb-1.4.4-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d0440f59e0cd9936a9ebfcf7a13312eda480c79214ffed3878d75947fc3b7d6d"}}, - {name = "duckdb-1.4.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d2/b1/fd5c37c53d45efe979f67e9bd49aaceef640147bb18f0699a19edd1874d6/duckdb-1.4.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "59c8d76016dde854beab844935b1ec31de358d4053e792988108e995b18c08e7"}}, - {name = "duckdb-1.4.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/2d/13e6024e613679d8a489dd922f199ef4b1d08a456a58eadd96dc2f05171f/duckdb-1.4.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "53cd6423136ab44383ec9955aefe7599b3fb3dd1fe006161e6396d8167e0e0d4"}}, - {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/7f/fe/64810fee20030f2bf96ce28b527060564864ce5b934b50888eda2cbf99dd/duckdb-1.4.4-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "337f8b24e89bc2e12dadcfe87b4eb1c00fd920f68ab07bc9b70960d6523b8bc3"}}, - {name = "duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9c/9b/3c7c5e48456b69365d952ac201666053de2700f5b0144a699a4dc6854507/duckdb-1.4.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "0509b39ea7af8cff0198a99d206dca753c62844adab54e545984c2e2c1381616"}}, - {name = "duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a6/7b/64e68a7b857ed0340045501535a0da99ea5d9d5ea3708fec0afb8663eb27/duckdb-1.4.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "fb94de6d023de9d79b7edc1ae07ee1d0b4f5fa8a9dcec799650b5befdf7aafec"}}, - {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/09/5b/3e7aa490841784d223de61beb2ae64e82331501bf5a415dc87a0e27b4663/duckdb-1.4.4-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0d636ceda422e7babd5e2f7275f6a0d1a3405e6a01873f00d38b72118d30c10b"}}, - {name = "duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/53/32/256df3dbaa198c58539ad94f9a41e98c2c8ff23f126b8f5f52c7dcd0a738/duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "7df7351328ffb812a4a289732f500d621e7de9942a3a2c9b6d4afcf4c0e72526"}}, - {name = "duckdb-1.4.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a4/f0/620323fd87062ea43e527a2d5ed9e55b525e0847c17d3b307094ddab98a2/duckdb-1.4.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "6fb1225a9ea5877421481d59a6c556a9532c32c16c7ae6ca8d127e2b878c9389"}}, - {name = "duckdb-1.4.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/07/a397fdb7c95388ba9c055b9a3d38dfee92093f4427bc6946cf9543b1d216/duckdb-1.4.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "f28a18cc790217e5b347bb91b2cab27aafc557c58d3d8382e04b4fe55d0c3f66"}}, - {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/58/33/beadaa69f8458afe466126f2c5ee48c4759cc9d5d784f8703d44e0b52c3c/duckdb-1.4.4-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "ddcfd9c6ff234da603a1edd5fd8ae6107f4d042f74951b65f91bc5e2643856b3"}}, - {name = "duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/66/82413f386df10467affc87f65bac095b7c88dbd9c767584164d5f4dc4cb8/duckdb-1.4.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "6792ca647216bd5c4ff16396e4591cfa9b4a72e5ad7cdd312cec6d67e8431a7c"}}, - {name = "duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/8c/c13d396fd4e9bf970916dc5b4fea410c1b10fe531069aea65f1dcf849a71/duckdb-1.4.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "1f8d55843cc940e36261689054f7dfb6ce35b1f5b0953b0d355b6adb654b0d52"}}, - {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/77/2446a0b44226bb95217748d911c7ca66a66ca10f6481d5178d9370819631/duckdb-1.4.4-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c65d15c440c31e06baaebfd2c06d71ce877e132779d309f1edf0a85d23c07e92"}}, - {name = "duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/2e/a3/97715bba30040572fb15d02c26f36be988d48bc00501e7ac02b1d65ef9d0/duckdb-1.4.4-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "b297eff642503fd435a9de5a9cb7db4eccb6f61d61a55b30d2636023f149855f"}}, - {name = "duckdb-1.4.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/0a/18b9167adf528cbe3867ef8a84a5f19f37bedccb606a8a9e59cfea1880c8/duckdb-1.4.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d525de5f282b03aa8be6db86b1abffdceae5f1055113a03d5b50cd2fb8cf2ef8"}}, - {name = "duckdb-1.4.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f8/15/37af97f5717818f3d82d57414299c293b321ac83e048c0a90bb8b6a09072/duckdb-1.4.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "50f2eb173c573811b44aba51176da7a4e5c487113982be6a6a1c37337ec5fa57"}}, - {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/04/68/19233412033a2bc5a144a3f531f64e3548d4487251e3f16b56c31411a06f/duckdb-1.4.4-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "5ba684f498d4e924c7e8f30dd157da8da34c8479746c5011b6c0e037e9c60ad2"}}, - {name = "duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b3/3e/cec70e546c298ab76d80b990109e111068d82cca67942c42328eaa7d6fdb/duckdb-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "5536eb952a8aa6ae56469362e344d4e6403cc945a80bc8c5c2ebdd85d85eb64b"}}, - {name = "duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/f0/cf4241a040ec4f571859a738007ec773b642fbc27df4cbcf34b0c32ea559/duckdb-1.4.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "47dd4162da6a2be59a0aef640eb08d6360df1cf83c317dcc127836daaf3b7f7c"}}, - {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/11/64/de2bb4ec1e35ec9ebf6090a95b930fc56934a0ad6f34a24c5972a14a77ef/duckdb-1.4.4-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6cb357cfa3403910e79e2eb46c8e445bb1ee2fd62e9e9588c6b999df4256abc1"}}, - {name = "duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/a2/ac0f5ee16df890d141304bcd48733516b7202c0de34cd3555634d6eb4551/duckdb-1.4.4-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4c25d5b0febda02b7944e94fdae95aecf952797afc8cb920f677b46a7c251955"}}, - {name = "duckdb-1.4.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/37/a2/9a3402edeedaecf72de05fe9ff7f0303d701b8dfc136aea4a4be1a5f7eee/duckdb-1.4.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6703dd1bb650025b3771552333d305d62ddd7ff182de121483d4e042ea6e2e00"}}, - {name = "duckdb-1.4.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f6/e6/052ea6dcdf35b259fd182eff3efd8d75a071de4010c9807556098df137b9/duckdb-1.4.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bf138201f56e5d6fc276a25138341b3523e2f84733613fc43f02c54465619a95"}}, - {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/a2/9f/67a75f1e88f84946909826fa7aadd0c4b0dc067f24956142751fd9d59fe6/duckdb-1.4.4-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "e870a441cb1c41d556205deb665749f26347ed13b3a247b53714f5d589596977"}}, - {name = "duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/6b/7a/e9277d0567884c21f345ad43cc01aeaa2abe566d5fdf22e35c3861dd44fa/duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "49123b579e4a6323e65139210cd72dddc593a72d840211556b60f9703bda8526"}}, - {name = "duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/96/3a7630d2779d2bae6f3cdf540a088ed45166adefd3c429971e5b85ce8f84/duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "5e1933fac5293fea5926b0ee75a55b8cfe7f516d867310a5b251831ab61fe62b"}}, - {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/ad/f62a3a65d200e8afc1f75cf0dd3f0aa84ef0dd07c484414a11f2abed810e/duckdb-1.4.4-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "707530f6637e91dc4b8125260595299ec9dd157c09f5d16c4186c5988bfbd09a"}}, - {name = "duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a2/5f/23bd586ecb21273b41b5aa4b16fd88b7fecb53ed48d897273651c0c3d66f/duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "453b115f4777467f35103d8081770ac2f223fb5799178db5b06186e3ab51d1f2"}}, - {name = "duckdb-1.4.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8b/d0/4ce78bf341c930d4a22a56cb686bfc2c975eaf25f653a7ac25e3929d98bb/duckdb-1.4.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "a3c8542db7ffb128aceb7f3b35502ebaddcd4f73f1227569306cc34bad06680c"}}, +version = "1.5.0" +requires-python = ">=3.10.0" +sdist = {name = "duckdb-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/ee/11/e05a7eb73a373d523e45d83c261025e02bc31ebf868e6282c30c4d02cc59/duckdb-1.5.0.tar.gz", hashes = {sha256 = "f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd"}} +wheels = [ + {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/66/9f/dd806d4e8ecd99006eb240068f34e1054533da1857ad06ac726305cd102d/duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa"}}, + {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/c2/7b7b8a5c65d5535c88a513e267b5e6d7a55ab3e9b67e4ddd474454653268/duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021"}}, + {name = "duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/23/c5/9a52a2cdb228b8d8d191a603254364d929274d9cc7d285beada8f7daa712/duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985"}}, + {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/68/646045cb97982702a8a143dc2e45f3bdcb79fbe2d559a98d74b8c160e5e2/duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113"}}, + {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/1b/5abf0c7f38febb3b4a231c784223fceccfd3f2bfd957699d786f46e41ce6/duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c"}}, + {name = "duckdb-1.5.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/a4/a90f2901cc0a1ce7ca4f0564b8492b9dbfe048a6395b27933d46ae9be473/duckdb-1.5.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977"}}, + {name = "duckdb-1.5.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/64/aa/f14dd5e241ec80d9f9d82196ca65e0c53badfc8a7a619d5497c5626657ad/duckdb-1.5.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36"}}, + {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/35/5d/af5501221f42e4e3662c047ecec4dcd0761229fceeba3c67ad4d9d8741df/duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d"}}, + {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/bd/a278d73fedbd3783bf9aedb09cad4171fe8e55bd522952a84f6849522eb6/duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b"}}, + {name = "duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/76/fc/c916e928606946209c20fb50898dabf120241fb528a244e2bd8cde1bd9e2/duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656"}}, + {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/53/07/1390e69db922423b2e111e32ed342b3e8fad0a31c144db70681ea1ba4d56/duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6"}}, + {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/54/13/b58d718415cde993823a54952ea511d2612302f1d2bc220549d0cef752a4/duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f"}}, + {name = "duckdb-1.5.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e0/96/4460429651e371eb5ff745a4790e7fa0509c7a58c71fc4f0f893404c9646/duckdb-1.5.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b"}}, + {name = "duckdb-1.5.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ba/54/6d5b805113214b830fa3c267bb3383fb8febaa30760d0162ef59aadb110a/duckdb-1.5.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8"}}, + {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/43/73/120e673e48ae25aaf689044c25ef51b0ea1d088563c9a2532612aea18e0a/duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd"}}, + {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/21/e9/61143471958d36d3f3e764cb4cd43330be208ddbff1c78d3310b9ee67fe8/duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375"}}, + {name = "duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4f/71/76e37c9a599ad89dd944e6cbb3e6a8ad196944a421758e83adea507637b6/duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59"}}, + {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/b8/de1831656d5d13173e27c79c7259c8b9a7bdc314fdc8920604838ea4c46d/duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30"}}, + {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/8d/33d349a3bcbd3e9b7b4e904c19d5b97f058c4c20791b89a8d6323bb93dce/duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6"}}, + {name = "duckdb-1.5.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/ec/591a4cad582fae04bc8f8b4a435eceaaaf3838cf0ca771daae16a3c2995b/duckdb-1.5.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86"}}, + {name = "duckdb-1.5.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/db/62/42e0a13f9919173bec121c0ff702406e1cdd91d8084c3e0b3412508c3891/duckdb-1.5.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7"}}, + {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/01/0c/0282b10a1c96810606b916b8d58a03f2131bd3ede14d2851f58b0b860e7c/duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86"}}, + {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/e8/cbbc920078a794f24f63017fc55c9cbdb17d6fb94d3973f479b2d9f2983d/duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41"}}, + {name = "duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/31/b6/6cae794d5856259b0060f79d5db71c7fdba043950eaa6a9d72b0bad16095/duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16"}}, + {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/82/07/aba3887658b93a36ce702dd00ca6a6422de3d14c7ee3a4b4c03ea20a99c0/duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2"}}, + {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/a2/723e6df48754e468fa50d7878eb860906c975eafe317c4134a8482ca220e/duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417"}}, + {name = "duckdb-1.5.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/03/af/4dcbdf8f2349ed0b054c254ec59bc362ce6ddf603af35f770124c0984686/duckdb-1.5.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2"}}, + {name = "duckdb-1.5.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/60/5e/1bb7e75a63bf3dc49bc5a2cd27a65ffeef151f52a32db980983516f2d9f6/duckdb-1.5.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298"}}, + {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/e0/5d/8fa129bbd604d0e91aa9a0a407e7d2acc559b6024c3f887868fd7a13871d/duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78"}}, + {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/0c/31/db320641a262a897755e634d16838c98d5ca7dc91f4e096e104e244a3a01/duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa"}}, + {name = "duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0b/45/5725684794fbabf54d8dbae5247685799a6bf8e1e930ebff3a76a726772c/duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381"}}, + {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/27/68/f110c66b43e27191d7e53d3587e118568b73d66f23cb9bd6c7e0a560fd6d/duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999"}}, + {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/ec/9d/46affc9257377cbc865e494650312a7a08a56e85aa8d702eb297bec430b7/duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730"}}, + {name = "duckdb-1.5.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/34/dac03ab7340989cda258655387959c88342ea3b44949751391267bcbc830/duckdb-1.5.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac"}}, ] marker = "\"default\" in dependency_groups" @@ -407,10 +407,10 @@ dependencies = [ [[packages]] name = "pytest-cases" -version = "3.9.1" -sdist = {name = "pytest_cases-3.9.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/69/8b41e074e9e1a9fa85c3765971f213e1b8d4a2f648b457af32dea792bdb8/pytest_cases-3.9.1.tar.gz", hashes = {sha256 = "c4e181f1b525c931a318d4812fa8de656c2c8fb77fccf1571ecf0cc5fe8e7f8f"}} +version = "3.10.1" +sdist = {name = "pytest_cases-3.10.1.tar.gz", url = "https://files.pythonhosted.org/packages/c1/a2/c7abc3b606125cf3732e8e613092b0e2549365e824b5f37972125c22806b/pytest_cases-3.10.1.tar.gz", hashes = {sha256 = "451f9e3ecd5d2d81a4362c10c441126f5b3d1ae3a7efaf59f60b1fb930df2d69"}} wheels = [ - {name = "pytest_cases-3.9.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/92/82/db006f1d06e5d31805ac47f9ce979937e3d026292f2759543b744f8040be/pytest_cases-3.9.1-py2.py3-none-any.whl",hashes = {sha256 = "60507716650c5ed1ce4a36a3c137f1c3ec58f4fef1ee8678404be074612fcd21"}}, + {name = "pytest_cases-3.10.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/61/f2/7a29fb0571562034b05c38dceabba48dcc622be5d6c5448db80779e55de7/pytest_cases-3.10.1-py2.py3-none-any.whl",hashes = {sha256 = "0deb8a85b6132e44adbc1cfc57897c6a624ec23f48ab445a43c7d56a6b9315a4"}}, ] marker = "\"test\" in dependency_groups" @@ -422,6 +422,18 @@ dependencies = [ "pytest", ] +[[packages]] +name = "pytz" +version = "2026.1.post1" +sdist = {name = "pytz-2026.1.post1.tar.gz", url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hashes = {sha256 = "3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1"}} +wheels = [ + {name = "pytz-2026.1.post1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl",hashes = {sha256 = "f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a"}}, +] +marker = "\"default\" in dependency_groups" + +[packages.tool.pdm] +dependencies = [] + [[packages]] name = "tqdm" version = "4.67.3" @@ -440,11 +452,11 @@ dependencies = [ [[packages]] name = "types-tqdm" -version = "4.67.3.20260205" -requires-python = ">=3.9" -sdist = {name = "types_tqdm-4.67.3.20260205.tar.gz", url = "https://files.pythonhosted.org/packages/53/46/790b9872523a48163bdda87d47849b4466017640e5259d06eed539340afd/types_tqdm-4.67.3.20260205.tar.gz", hashes = {sha256 = "f3023682d4aa3bbbf908c8c6bb35f35692d319460d9bbd3e646e8852f3dd9f85"}} +version = "4.67.3.20260303" +requires-python = ">=3.10" +sdist = {name = "types_tqdm-4.67.3.20260303.tar.gz", url = "https://files.pythonhosted.org/packages/e1/64/3e7cb0f40c4bf9578098b6873df33a96f7e0de90f3a039e614d22bfde40a/types_tqdm-4.67.3.20260303.tar.gz", hashes = {sha256 = "7bfddb506a75aedb4030fabf4f05c5638c9a3bbdf900d54ec6c82be9034bfb96"}} wheels = [ - {name = "types_tqdm-4.67.3.20260205-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl",hashes = {sha256 = "85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173"}}, + {name = "types_tqdm-4.67.3.20260303-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/37/32/e4a1fce59155c74082f1a42d0ffafa59652bfb8cff35b04d56333877748e/types_tqdm-4.67.3.20260303-py3-none-any.whl",hashes = {sha256 = "459decf677e4b05cef36f9012ef8d6e20578edefb6b78c15bd0b546247eda62d"}}, ] marker = "\"types\" in dependency_groups" @@ -820,7 +832,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "fc3d3c9728a89b11648ffab29807d5c42006e80d65c41b735dac8d12d3dd8f1d"} +hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pyproject.toml b/pyproject.toml index e5a780e..a18a6f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,9 @@ authors = [ dependencies = [ # 1.3 introduces json each "duckdb>=1.3", + # pytz is required for timestamptz columns in duckdb + # 2021.3 was released with 3.10 + "pytz>=2021.3", # 4.64 is the first release with type stubs "tqdm>=4.64.0", # 0.3 allows checking the path for id based paging diff --git a/src/ldlite/_csv.py b/src/ldlite/_csv.py index dbe8eca..b8e7ae9 100644 --- a/src/ldlite/_csv.py +++ b/src/ldlite/_csv.py @@ -63,11 +63,14 @@ def to_csv( if i != 0: s += "," if attrs[i][1] in [ + "INTEGER", "NUMBER", "DECIMAL(18,3)", "bigint", + "integer", "numeric", 20, + 23, 1700, ]: s += str(d).rstrip("0").rstrip(".") diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index 1ca8508..241b85b 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -57,6 +57,10 @@ def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: main.json_type(j) == 'DOUBLE' ; +CREATE OR REPLACE FUNCTION ldlite_system.jis_bigint(j) AS + COALESCE(TRY_CAST(j AS NUMERIC), 0) > 2147483647 +; + CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j) AS j IS NULL OR j == 'null'::JSON OR main.json_extract_string(j, '$') IN ('NULL', 'null', '', '{}', '[]') ; diff --git a/src/ldlite/database/_expansion/metadata.py b/src/ldlite/database/_expansion/metadata.py index e18b854..50087ff 100644 --- a/src/ldlite/database/_expansion/metadata.py +++ b/src/ldlite/database/_expansion/metadata.py @@ -8,7 +8,7 @@ @dataclass class Metadata: - prop: str + prop: str | None # array is technically a type # but the metadata query returns inner type of the array # the jtype_of function normalizes the names between pg and duckdb @@ -17,6 +17,7 @@ class Metadata: is_uuid: bool is_datetime: bool is_float: bool + is_bigint: bool def __post_init__(self) -> None: # Mixed json_type columns (which shouldn't really happen) @@ -31,6 +32,10 @@ def is_object(self) -> bool: @property def snake(self) -> str: + if self.prop is None: + # this doesn't realy come up in practice + return "$" + return "".join("_" + c.lower() if c.isupper() else c for c in self.prop).lstrip( "_", ) @@ -40,47 +45,31 @@ def select_column( json_col: sql.Identifier, alias: str, ) -> sql.Composed: - # '$' is a special character that means the root of the json - # I couldn't figure out how to make the array expansion work - # without it + str_extract = ( + "{json_col}->>{prop}" + if self.prop is not None + else "ldlite_system.jself_string({json_col})" + ) + nullable_str_extract = f"NULLIF(NULLIF({str_extract}, ''), 'null')" + if self.is_array or self.is_object: - stmt = sql.SQL( - "{json_col}->{prop} AS {alias}" - if self.prop != "$" - else "{json_col} AS {alias}", - ) + stmt = "{json_col}" if self.prop is None else "{json_col}->{prop}" + elif self.json_type == "number" and self.is_float: + stmt = f"({str_extract})::numeric" + elif self.json_type == "number" and self.is_bigint: + stmt = f"({str_extract})::bigint" elif self.json_type == "number": - stmt = sql.SQL( - "({json_col}->>{prop})::numeric AS {alias}" - if self.prop != "$" - else "ldlite_system.jself_string({json_col})::numeric AS {alias}", - ) + stmt = f"({str_extract})::integer" elif self.json_type == "boolean": - stmt = sql.SQL( - "NULLIF(NULLIF({json_col}->>{prop}, ''), 'null')::bool AS {alias}" - if self.prop != "$" - else "NULLIF(NULLIF(" - "ldlite_system.jself_string({json_col})" - ", ''), 'null')::bool AS {alias}", - ) + stmt = f"({nullable_str_extract})::bool" elif self.json_type == "string" and self.is_uuid: - stmt = sql.SQL( - "NULLIF(NULLIF({json_col}->>{prop}, ''), 'null')::uuid AS {alias}" - if self.prop != "$" - else "NULLIF(NULLIF(" - "ldlite_system.jself_string({json_col})" - ", ''), 'null')::uuid AS {alias}", - ) + stmt = f"({nullable_str_extract})::uuid" + elif self.json_type == "string" and self.is_datetime: + stmt = f"({nullable_str_extract})::timestamptz" else: - stmt = sql.SQL( - "NULLIF(NULLIF({json_col}->>{prop}, ''), 'null') AS {alias}" - if self.prop != "$" - else "NULLIF(NULLIF(" - "ldlite_system.jself_string({json_col})" - ", ''), 'null') AS {alias}", - ) + stmt = nullable_str_extract - return stmt.format( + return sql.SQL(stmt + " AS {alias}").format( json_col=json_col, prop=self.prop, alias=sql.Identifier(alias), diff --git a/src/ldlite/database/_expansion/nodes.py b/src/ldlite/database/_expansion/nodes.py index 75ea842..8d9e092 100644 --- a/src/ldlite/database/_expansion/nodes.py +++ b/src/ldlite/database/_expansion/nodes.py @@ -233,11 +233,16 @@ def unnest( SELECT 1 FROM all_values WHERE json_type = 'string' AND NOT ldlite_system.jis_datetime(ld_value) ) AS is_datetime - ,NOT EXISTS + ,EXISTS ( SELECT 1 FROM all_values - WHERE json_type = 'number' AND NOT ldlite_system.jis_float(ld_value) + WHERE json_type = 'number' AND ldlite_system.jis_float(ld_value) ) AS is_float + ,EXISTS + ( + SELECT 1 FROM all_values + WHERE json_type = 'number' AND ldlite_system.jis_bigint(ld_value) + ) AS is_bigint """, ) .format( @@ -310,12 +315,13 @@ def __init__( ): super().__init__(name, path, parent, values) self.meta = Metadata( - "$", + None, meta.json_type, False, meta.is_uuid, meta.is_datetime, meta.is_float, + meta.is_bigint, ) def explode( diff --git a/src/ldlite/database/_postgres.py b/src/ldlite/database/_postgres.py index 2b51f9c..3084784 100644 --- a/src/ldlite/database/_postgres.py +++ b/src/ldlite/database/_postgres.py @@ -72,6 +72,14 @@ def _setup_jfuncs(conn: psycopg.Connection) -> None: PARALLEL SAFE STRICT; +CREATE OR REPLACE FUNCTION ldlite_system.jis_bigint(j JSONB) RETURNS BOOLEAN AS $$ +SELECT (j)::numeric > 2147483647 +$$ +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE +STRICT; + CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j JSONB) RETURNS BOOLEAN AS $$ SELECT j IS NULL OR j = 'null'::jsonb OR j #>> '{}' IN ('NULL', 'null', '', '{}', '[]') $$ diff --git a/tests/test_expansion.py b/tests/test_expansion.py index 8967736..b24a844 100644 --- a/tests/test_expansion.py +++ b/tests/test_expansion.py @@ -49,7 +49,9 @@ def case_typed_columns() -> ExpansionTC: b""" { "id": "id1", - "numeric": 1, + "timestamptz": "2028-01-23T00:00:00.000+00:00", + "integer": 1, + "numeric": 1.2, "text": "value", "boolean": false, "uuid": "88888888-8888-1888-8888-888888888888" @@ -58,7 +60,9 @@ def case_typed_columns() -> ExpansionTC: b""" { "id": "id2", - "numeric": 2, + "timestamptz": "2025-06-20T17:37:58.675+00:00", + "integer": 2, + "numeric": 2.3, "text": "00000000-0000-1000-A000-000000000000", "boolean": false, "uuid": "11111111-1111-1111-8111-111111111111" @@ -72,14 +76,16 @@ def case_typed_columns() -> ExpansionTC: FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'prefix__t' AND COLUMN_NAME = '{a[0]}' """, - exp_pg=a[0], - exp_duck=a[1], + exp_pg=a[1], + exp_duck=a[2], ) for a in [ - ("numeric", "DECIMAL(18,3)"), - ("text", "VARCHAR"), - ("uuid", "UUID"), - ("boolean", "BOOLEAN"), + ("integer", "integer", "INTEGER"), + ("numeric", "numeric", "DECIMAL(18,3)"), + ("text", "text", "VARCHAR"), + ("uuid", "uuid", "UUID"), + ("boolean", "boolean", "BOOLEAN"), + ("timestamptz", "timestamp with time zone", "TIMESTAMP WITH TIME ZONE"), ] ], ) @@ -90,11 +96,12 @@ def case_typed_columns() -> ExpansionTC: [ ("all_null", None, None), ("nullable_numeric", "numeric", "DECIMAL(18,3)"), + ("nullable_integer", "integer", "INTEGER"), ("nullable_uuid", "uuid", "UUID"), ("nullable_bool", "boolean", "BOOLEAN"), - ("nullable_object__id", "numeric", "DECIMAL(18,3)"), - ("nullable_array", "numeric", "DECIMAL(18,3)"), - ("sortof_nullable_array__id", "numeric", "DECIMAL(18,3)"), + ("nullable_object__id", "integer", "INTEGER"), + ("nullable_array", "integer", "INTEGER"), + ("sortof_nullable_array__id", "integer", "INTEGER"), ], idgen="prop={assertion[0]}", ) @@ -104,6 +111,7 @@ def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: b""" { "all_null": null, + "nullable_integer": null, "nullable_numeric": null, "nullable_bool": null, "nullable_uuid": null, @@ -115,7 +123,8 @@ def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: b""" { "all_null": null, - "nullable_numeric": 5, + "nullable_integer": 7, + "nullable_numeric": 5.5, "nullable_uuid": null, "nullable_bool": false, "nullable_object": { "id": 5 }, @@ -126,7 +135,8 @@ def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: b""" { "all_null": null, - "nullable_numeric": null, + "nullable_integer": 0, + "nullable_numeric": 1, "nullable_bool": true, "nullable_uuid": "0b03c888-102b-18e9-afb7-85e22229ca4d", "nullable_object": { "id": null}, @@ -284,7 +294,7 @@ def case_basic_array() -> ExpansionTC: ) for a in [ ("list1", "VARCHAR", "text"), - ("list2", "DECIMAL(18,3)", "numeric"), + ("list2", "INTEGER", "integer"), ] ], ], diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index 8b1f8c8..2ae7d24 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -50,6 +50,8 @@ def case_jobject_keys() -> JsonTC: ("str", "string"), ("num", "number"), ("float", "number"), + ("bigfloat", "number"), + ("bigint", "number"), ("bool", "boolean"), ("obj", "object"), ("arr_str", "array"), @@ -160,6 +162,8 @@ def case_jis_datetime(p: tuple[Any, ...]) -> JsonTC: p=[ ("num", False), ("float", True), + ("bigfloat", True), + ("bigint", False), ], ) def case_jis_float(p: tuple[Any, ...]) -> JsonTC: @@ -173,6 +177,25 @@ def case_jis_float(p: tuple[Any, ...]) -> JsonTC: ) +@parametrize( + p=[ + ("num", False), + ("float", False), + ("bigfloat", True), + ("bigint", True), + ], +) +def case_jis_bigint(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT {assertion}ldlite_system.jis_bigint(jc->$1) +FROM j;""", + p[:1], + "" if (p[1]) else """ NOT """, + (), + ) + + def _assert(conn: "dbapi.DBAPIConnection", jtype: str, tc: JsonTC) -> None: with closing(conn.cursor()) as cur: query = tc.query.format(assertion="", jtype=jtype) @@ -206,6 +229,8 @@ def _arrange(conn: "dbapi.DBAPIConnection") -> None: "str_empty": "", "num": 12, "float": 16.3, + "bigint": 2147483648, + "bigfloat": 2147483648.1, "bool": true, "uuid": "5b285d03-5490-1111-8888-52b2003b475c", "uuid_nof": "5b285d03-5490-FFFF-0000-52b2003b475c", From a9b6ed8b2056dfbfaa2d1a1eb29d62c30074a7eb Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Fri, 13 Mar 2026 09:57:45 -0400 Subject: [PATCH 19/25] Record history more accurately (#70) One thing that's come up a couple of times while running in alpha mode is that the history doesn't reflect what actually happens because it isn't updated in the same transaction as the download/transform. This changes the columns to be more informational as well as modifying the dashboard to be incrementally updated in transactions. This is also a lot cleaner as state doesn't have be maintained the whole runtime and can be distributed more easily. While testing this and comparing with the existing data I noticed there were two regressions. The first was a bug with jagged json where only rows with all the nested objects would be fully transformed. The second had to do with the _version column some tables have which was losing the leading underscore. These are both fixed here. --- src/ldlite/__init__.py | 33 +---- src/ldlite/database/__init__.py | 21 +-- src/ldlite/database/_duckdb.py | 7 +- src/ldlite/database/_expansion/metadata.py | 12 +- src/ldlite/database/_expansion/nodes.py | 1 - src/ldlite/database/_postgres.py | 5 + src/ldlite/database/_typed_database.py | 159 ++++++++++++++++----- tests/test_drop_tables.py | 2 +- tests/test_expansion.py | 95 ++++++++++++ tests/test_load_history.py | 24 ++-- 10 files changed, 265 insertions(+), 94 deletions(-) diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index 3d9d3ef..e6cd1f8 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -35,7 +35,6 @@ """ import sys -from datetime import datetime, timezone from typing import TYPE_CHECKING, NoReturn, cast import duckdb @@ -53,7 +52,7 @@ autocommit, sqlid, ) -from .database import Database, LoadHistory +from .database import Database if TYPE_CHECKING: from collections.abc import Iterator @@ -308,7 +307,12 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 if self.db is None or self._database is None: self._check_db() return [] - start = datetime.now(timezone.utc) + + self._database.prepare_history( + table, + path, + query if query and isinstance(query, str) else None, + ) if not self._quiet: print("ldlite: querying: " + path, file=sys.stderr) @@ -328,7 +332,6 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 file=sys.stderr, ) - download_started = datetime.now(timezone.utc) processed = self._database.ingest_records( table, cast( @@ -346,10 +349,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 ), ), ) - download = datetime.now(timezone.utc) - download_elapsed = datetime.now(timezone.utc) - download_started - transform_started = datetime.now(timezone.utc) if not use_legacy_transform: no_iters_format = ( "{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}]" @@ -377,7 +377,6 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 ) if keep_raw: newtables = [table, *newtables] - transform_elapsed = datetime.now(timezone.utc) - transform_started with tqdm( desc="indexing", @@ -385,7 +384,6 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 disable=self._quiet, bar_format=no_iters_format, ) as progress: - index_started = datetime.now(timezone.utc) self._database.index_prefix(table, progress) else: @@ -424,10 +422,7 @@ def query( # noqa: C901, PLR0912, PLR0913, PLR0915 finally: autocommit(self.db, self.dbtype, True) - transform_elapsed = datetime.now(timezone.utc) - transform_started - # Create indexes on id columns (for postgres) - index_started = datetime.now(timezone.utc) if self.dbtype == DBType.POSTGRES: class PbarNoop: @@ -464,20 +459,6 @@ def close(self) -> None: ... pbar.update(1) pbar.close() - index_elapsed = datetime.now(timezone.utc) - index_started - self._database.record_history( - LoadHistory( - table, - path, - query if query and isinstance(query, str) else None, - processed, - download, - start, - download_elapsed, - transform_elapsed, - index_elapsed, - ), - ) # Return table names if not self._quiet: print("ldlite: created tables: " + ", ".join(newtables), file=sys.stderr) diff --git a/src/ldlite/database/__init__.py b/src/ldlite/database/__init__.py index e1df517..b7fb915 100644 --- a/src/ldlite/database/__init__.py +++ b/src/ldlite/database/__init__.py @@ -3,31 +3,14 @@ from __future__ import annotations from abc import ABC, abstractmethod -from dataclasses import dataclass from typing import TYPE_CHECKING, NoReturn if TYPE_CHECKING: - import datetime from collections.abc import Iterator from tqdm import tqdm -@dataclass(frozen=True) -class LoadHistory: - """Represents the statistics and history of a single ldlite operation.""" - - table_name: str - path: str - query: str | None - total: int - download_time: datetime.datetime - start_time: datetime.datetime - download_interval: datetime.timedelta - transform_interval: datetime.timedelta - index_interval: datetime.timedelta - - class Database(ABC): """The required interface for LDLite to utilite a database.""" @@ -69,5 +52,5 @@ def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> N """Finds and indexes all tables at the given prefix.""" @abstractmethod - def record_history(self, history: LoadHistory) -> None: - """Records the statistics and history of a single ldlite operation.""" + def prepare_history(self, prefix: str, path: str, query: str | None) -> None: + """Creates an entry with the current parameters in the history table.""" diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index 241b85b..7ab8cc8 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -1,4 +1,5 @@ from collections.abc import Iterator +from datetime import datetime, timezone from itertools import count from typing import TYPE_CHECKING, Any, cast @@ -89,6 +90,7 @@ def ingest_records( records: Iterator[bytes], ) -> int: pfx = Prefix(prefix) + download_started = datetime.now(timezone.utc) pkey = count(1) with self._conn_factory() as conn: self._prepare_raw_table(conn, pfx) @@ -102,9 +104,12 @@ def ingest_records( with conn.begin() as tx, tx.cursor() as cur: for r in records: cur.execute(insert_sql, (next(pkey), r.decode())) + + total = next(pkey) - 1 + self._download_complete(conn, pfx, total, download_started) tx.commit() - return next(pkey) - 1 + return total def source_table_cte_stmt(self, keep_source: bool) -> str: # noqa: ARG002 return "WITH ld_source AS (SELECT * FROM {source_table})" diff --git a/src/ldlite/database/_expansion/metadata.py b/src/ldlite/database/_expansion/metadata.py index 50087ff..995b812 100644 --- a/src/ldlite/database/_expansion/metadata.py +++ b/src/ldlite/database/_expansion/metadata.py @@ -33,12 +33,16 @@ def is_object(self) -> bool: @property def snake(self) -> str: if self.prop is None: - # this doesn't realy come up in practice + # this doesn't really come up in practice return "$" - return "".join("_" + c.lower() if c.isupper() else c for c in self.prop).lstrip( - "_", - ) + snake = "".join("_" + c.lower() if c.isupper() else c for c in self.prop) + + # there's also sorts of weird edge cases here that don't come up in practice + if (naked := self.prop.lstrip("_")) and len(naked) > 0 and naked[0].isupper(): + snake = snake.removeprefix("_") + + return snake def select_column( self, diff --git a/src/ldlite/database/_expansion/nodes.py b/src/ldlite/database/_expansion/nodes.py index 8d9e092..4f91027 100644 --- a/src/ldlite/database/_expansion/nodes.py +++ b/src/ldlite/database/_expansion/nodes.py @@ -277,7 +277,6 @@ def unnest( SELECT {cols} FROM ld_source -WHERE NOT ldlite_system.jis_null({json_col}) """, ) .format( diff --git a/src/ldlite/database/_postgres.py b/src/ldlite/database/_postgres.py index 3084784..9c7dd2a 100644 --- a/src/ldlite/database/_postgres.py +++ b/src/ldlite/database/_postgres.py @@ -1,4 +1,5 @@ from collections.abc import Iterator +from datetime import datetime, timezone from itertools import count import psycopg @@ -120,6 +121,7 @@ def ingest_records( records: Iterator[bytes], ) -> int: pfx = Prefix(prefix) + download_started = datetime.now(timezone.utc) pkey = count(1) with self._conn_factory() as conn: self._prepare_raw_table(conn, pfx) @@ -141,7 +143,10 @@ def ingest_records( rb.extend(r) copy.write_row((next(pkey).to_bytes(4, "big"), rb)) + total = next(pkey) - 1 + self._download_complete(conn, pfx, total, download_started) conn.commit() + return next(pkey) - 1 def preprocess_source_table( diff --git a/src/ldlite/database/_typed_database.py b/src/ldlite/database/_typed_database.py index 1303931..742c966 100644 --- a/src/ldlite/database/_typed_database.py +++ b/src/ldlite/database/_typed_database.py @@ -3,7 +3,7 @@ from abc import abstractmethod from contextlib import closing -from datetime import timezone +from datetime import datetime, timezone from typing import TYPE_CHECKING, Any, Generic, NoReturn, TypeVar, cast from uuid import uuid4 @@ -11,7 +11,7 @@ from psycopg import sql from tqdm import tqdm -from . import Database, LoadHistory +from . import Database from ._expansion import expand_nonmarc from ._expansion.context import ExpandContext from ._prefix import Prefix @@ -34,15 +34,22 @@ def __init__(self, conn_factory: Callable[[], DB]): cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') cur.execute(""" CREATE TABLE IF NOT EXISTS "ldlite_system"."load_history_v1" ( - "table_name" TEXT UNIQUE - ,"path" TEXT - ,"query" TEXT - ,"row_count" INTEGER - ,"download_complete_utc" TIMESTAMP - ,"start_utc" TIMESTAMP - ,"download_time" INTERVAL - ,"transform_time" INTERVAL - ,"index_time" INTERVAL + "table_prefix" TEXT UNIQUE + ,"folio_path" TEXT -- 1 + ,"query_text" TEXT -- 2 + ,"load_start" TIMESTAMPTZ -- 3 + + ,"rowcount" INTEGER -- 4 + ,"download_complete" TIMESTAMPTZ -- 5 + + ,"final_rowcount" INTEGER -- 6 + ,"transform_complete" TIMESTAMPTZ -- 7 + ,"data_refresh_start" TIMESTAMPTZ -- 8 + ,"data_refresh_end" TIMESTAMPTZ -- 9 + + ,"download_time" INTERVAL -- 10 + ,"transform_time" INTERVAL -- 11 + ,"index_time" INTERVAL -- 12 );""") self._setup_jfuncs(conn) @@ -65,7 +72,10 @@ def drop_prefix( self._drop_extracted_tables(conn, pfx) self._drop_raw_table(conn, pfx) conn.execute( - 'DELETE FROM "ldlite_system"."load_history_v1" WHERE "table_name" = $1', + """ +DELETE FROM "ldlite_system"."load_history_v1" +WHERE "table_prefix" = $1; +""", (pfx.load_history_key,), ) conn.commit() @@ -195,6 +205,7 @@ def expand_prefix( transform_progress: tqdm[NoReturn] | None = None, ) -> list[str]: pfx = Prefix(prefix) + transform_started = datetime.now(timezone.utc) with closing(self._conn_factory()) as conn: self._drop_extracted_tables(conn, pfx) if json_depth < 1: @@ -262,12 +273,22 @@ def expand_prefix( [(pfx.catalog_table_row(t),) for t in created_tables], ) + with conn.cursor() as cur: + cur.execute( + sql.SQL("SELECT COUNT(*) FROM {table}") + .format(table=pfx.output_table("").id) + .as_string(), + ) + total = cast("tuple[int]", cur.fetchone())[0] + + self._transform_complete(conn, pfx, total, transform_started) conn.commit() return created_tables def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> None: pfx = Prefix(prefix) + index_started = datetime.now(timezone.utc) with closing(self._conn_factory()) as conn: with closing(conn.cursor()) as cur: cur.execute( @@ -321,33 +342,105 @@ def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> N if progress is not None: progress.update(1) + self._index_complete(conn, pfx, index_started) conn.commit() - def record_history(self, history: LoadHistory) -> None: - with closing(self._conn_factory()) as conn, conn.cursor() as cur: + def prepare_history( + self, + prefix: str, + path: str, + query: str | None, + ) -> None: + with closing(self._conn_factory()) as conn, closing(conn.cursor()) as cur: cur.execute( """ -INSERT INTO "ldlite_system"."load_history_v1" VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9) -ON CONFLICT ("table_name") DO UPDATE SET - "path" = EXCLUDED."path" - ,"query" = EXCLUDED."query" - ,"row_count" = EXCLUDED."row_count" - ,"download_complete_utc" = EXCLUDED."download_complete_utc" - ,"start_utc" = EXCLUDED."start_utc" - ,"download_time" = EXCLUDED."download_time" - ,"transform_time" = EXCLUDED."transform_time" - ,"index_time" = EXCLUDED."index_time" +INSERT INTO "ldlite_system"."load_history_v1" +( + "table_prefix" + ,"folio_path" + ,"query_text" + ,"load_start" +) +VALUES($1,$2,$3,$4) +ON CONFLICT ("table_prefix") DO UPDATE SET + "folio_path" = EXCLUDED."folio_path" + ,"query_text" = EXCLUDED."query_text" + ,"load_start" = EXCLUDED."load_start" """, ( - Prefix(history.table_name).load_history_key, - history.path, - history.query, - history.total, - history.download_time.astimezone(timezone.utc), - history.start_time.astimezone(timezone.utc), - history.download_interval, - history.transform_interval, - history.index_interval, + Prefix(prefix).load_history_key, + path, + query, + datetime.now(timezone.utc), ), ) conn.commit() + + def _download_complete( + self, + conn: DB, + pfx: Prefix, + rowcount: int, + download_start: datetime, + ) -> None: + with conn.cursor() as cur: + cur.execute( + """ +UPDATE "ldlite_system"."load_history_v1" SET + "rowcount" = $2 + ,"download_complete" = $3 + ,"download_time" = $4 +WHERE "table_prefix" = $1; +""", + ( + pfx.load_history_key, + rowcount, + datetime.now(timezone.utc), + datetime.now(timezone.utc) - download_start, + ), + ) + + def _transform_complete( + self, + conn: DB, + pfx: Prefix, + final_rowcount: int, + transform_start: datetime, + ) -> None: + with conn.cursor() as cur: + cur.execute( + """ +UPDATE "ldlite_system"."load_history_v1" SET + "final_rowcount" = $2 + ,"transform_complete" = $3 + ,"transform_time" = $4 + ,"data_refresh_start" = "load_start" + ,"data_refresh_end" = "download_complete" +WHERE "table_prefix" = $1 +""", + ( + pfx.load_history_key, + final_rowcount, + datetime.now(timezone.utc), + datetime.now(timezone.utc) - transform_start, + ), + ) + + def _index_complete( + self, + conn: DB, + pfx: Prefix, + index_start: datetime, + ) -> None: + with conn.cursor() as cur: + cur.execute( + """ +UPDATE "ldlite_system"."load_history_v1" SET + "index_time" = $2 +WHERE "table_prefix" = $1 +""", + ( + pfx.load_history_key, + datetime.now(timezone.utc) - index_start, + ), + ) diff --git a/tests/test_drop_tables.py b/tests/test_drop_tables.py index 1050cd3..1f4084b 100644 --- a/tests/test_drop_tables.py +++ b/tests/test_drop_tables.py @@ -125,7 +125,7 @@ def _assert( assert ud[0] == len(tc.calls_list) - 1 cur.execute( 'SELECT COUNT(*) FROM "ldlite_system"."load_history_v1" ' - 'WHERE "table_name" = $1', + 'WHERE "table_prefix" = $1', (tc.drop,), ) assert (d := cur.fetchone()) is not None diff --git a/tests/test_expansion.py b/tests/test_expansion.py index b24a844..9fcd6bc 100644 --- a/tests/test_expansion.py +++ b/tests/test_expansion.py @@ -91,6 +91,101 @@ def case_typed_columns() -> ExpansionTC: ) +def case_camel() -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "camelCase": 1, + "_camelCase": 1, + "__camelCase": 1, + "PascalCase": 1, + "_PascalCase": 1, + "__PascalCase": 1 +} +""", + ], + assertions=[ + Assertion( + """ +SELECT COLUMN_NAME +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME = 'prefix__t' AND COLUMN_NAME <> '__id' +ORDER BY COLUMN_NAME COLLATE "C"; +""", + expect=[ + ("__camel_case",), + ("__pascal_case",), + ("_camel_case",), + ("_pascal_case",), + ("camel_case",), + ("pascal_case",), + ], + ), + ], + ) + + +def case_jagged_json() -> ExpansionTC: + return ExpansionTC( + records=[ + b""" +{ + "id": "id1", + "both": { "id": "both_id1" }, + "first_only": { "id": "first_id1" } +} +""", + b""" +{ + "id": "id2", + "both": { "id": "both_id2" }, + "second_only": { "id": "second_id2" } +} +""", + b""" +{ + "id": "id3", + "both": { "id": "both_id3" }, + "first_only": { "id": "first_id3" } +} +""", + ], + assertions=[ + Assertion( + """ +SELECT COUNT(*) +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME = 'prefix__t' +""", + expect=5, + ), + Assertion( + """ +SELECT COUNT(*) +FROM tests.prefix__t +""", + expect=3, + ), + Assertion( + """ +SELECT COLUMN_NAME +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_NAME = 'prefix__t' +ORDER BY COLUMN_NAME COLLATE "C"; +""", + expect=[ + ("__id",), + ("both__id",), + ("first_only__id",), + ("id",), + ("second_only__id",), + ], + ), + ], + ) + + @parametrize( "assertion", [ diff --git a/tests/test_load_history.py b/tests/test_load_history.py index d26120e..44720c6 100644 --- a/tests/test_load_history.py +++ b/tests/test_load_history.py @@ -133,20 +133,26 @@ def _assert( for tn, (q, t) in tc.expected_loads.items(): cur.execute( 'SELECT * FROM "ldlite_system"."load_history_v1" ' - 'WHERE "table_name" = $1', + 'WHERE "table_prefix" = $1', (tn,), ) assert (d := cur.fetchone()) is not None assert d[1] == "/patched" assert d[2] == q - assert d[3] == t - assert d[4] > d[5] - assert d[6] > timedelta(microseconds=0) - assert d[6] < timedelta(seconds=1) - assert d[7] > timedelta(microseconds=0) - assert d[7] < timedelta(seconds=1) - assert d[8] > timedelta(microseconds=0) - assert d[8] < timedelta(seconds=1) + assert d[4] == t + assert d[6] == t + + assert d[7] > d[5] + assert d[8] == d[3] + assert d[9] == d[5] + assert d[9] > d[8] + + assert d[10] > timedelta(microseconds=0) + assert d[10] < timedelta(seconds=1) + assert d[11] > timedelta(microseconds=0) + assert d[11] < timedelta(seconds=1) + assert d[12] > timedelta(microseconds=0) + assert d[12] < timedelta(seconds=1) @mock.patch("httpx_folio.auth.httpx.post") From a5fc7ecce91fe476faa929f8a8f9773a9717389b Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Mon, 23 Mar 2026 14:21:04 -0400 Subject: [PATCH 20/25] Stabilize disk and memory utilization (#71) For every endpoint except for instances LDLite had been running great. This is a result of a weeks long struggle to get the instances to also run. There were two big issues * Starting a transaction and then having a bunch of intermediate temp tables ballooned the disk space as the rows were never cleaned up even though they were deleted * Depending on the query plan the memory would sometimes spike to 100% and DigitalOcean would kill the connection My initial theory was that this was disk spilling and so I reviewed a lot of query plans to eliminate it. Each query was a little guilty but switching to WITH ORDINAL instead of ROW_NUMBER and switching away from multiple exists queries based on a single CTE cleaned it up. The memory spikes were due to the query plan going bad because it couldn't see into the jfuncs. I ended up using the postgres native name so the query planner can be happier and just shimming them for duckdb. Rather than wait until the end of the transaction to drop all the temp tables they're now session scoped and get dropped explicitly after they're no longer necessary. This PR loads all the data and does it in a single night which is a huge improvement over not running or taking 34 hours. As I worked through it I discovered bigger changes that could tame the memory and disk but was hesitant to rewrite a large chunk before I had something that worked "ok". The disk and memory still balloon too much for a release of LDLite but they at least work in Five Colleges environment with excessively provisioned disk. --- .github/workflows/test.yaml | 6 +- pylock.lint.toml | 292 ++++++++++----------- pylock.maximal.toml | 88 +++---- pylock.minimal.toml | 62 ++--- pylock.toml | 292 ++++++++++----------- pyproject.toml | 5 +- src/ldlite/database/_duckdb.py | 46 +--- src/ldlite/database/_expansion/__init__.py | 85 +++--- src/ldlite/database/_expansion/metadata.py | 157 +++++++---- src/ldlite/database/_expansion/nodes.py | 276 +++++++++++-------- src/ldlite/database/_postgres.py | 93 ++----- src/ldlite/database/_typed_database.py | 100 +++---- tests/test_expansion.py | 4 +- tests/test_json_operators.py | 130 +-------- tests/test_query.py | 4 +- 15 files changed, 785 insertions(+), 855 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3570639..410cdf6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -25,7 +25,7 @@ jobs: - run: pdm install -G:all --lockfile pylock.toml # test - - run: pdm run test + - run: pdm run test -k 'not test_srs' test-minimal-deps: runs-on: ubuntu-latest @@ -41,7 +41,7 @@ jobs: - run: pdm install -G:all --lockfile pylock.minimal.toml # test - - run: pdm run test + - run: pdm run test -k 'not test_srs' test-maximal-deps: runs-on: ubuntu-latest @@ -57,4 +57,4 @@ jobs: - run: pdm install -G:all --lockfile pylock.maximal.toml # test - - run: pdm run test + - run: pdm run test -k 'not test_srs' diff --git a/pylock.lint.toml b/pylock.lint.toml index b0cd92d..7185c13 100644 --- a/pylock.lint.toml +++ b/pylock.lint.toml @@ -106,115 +106,115 @@ dependencies = [] [[packages]] name = "coverage" -version = "7.13.4" +version = "7.13.5" requires-python = ">=3.10" -sdist = {name = "coverage-7.13.4.tar.gz", url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hashes = {sha256 = "e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}} -wheels = [ - {name = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}}, - {name = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}}, - {name = "coverage-7.13.4-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl",hashes = {sha256 = "8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}}, - {name = "coverage-7.13.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}}, - {name = "coverage-7.13.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}}, - {name = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}}, - {name = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}}, - {name = "coverage-7.13.4-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl",hashes = {sha256 = "c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}}, - {name = "coverage-7.13.4-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}}, - {name = "coverage-7.13.4-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}}, - {name = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}}, - {name = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}}, - {name = "coverage-7.13.4-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl",hashes = {sha256 = "f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}}, - {name = "coverage-7.13.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}}, - {name = "coverage-7.13.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}}, - {name = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}}, - {name = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}}, - {name = "coverage-7.13.4-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl",hashes = {sha256 = "2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}}, - {name = "coverage-7.13.4-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}}, - {name = "coverage-7.13.4-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}}, - {name = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"}}, - {name = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/a0/2ea570925524ef4e00bb6c82649f5682a77fac5ab910a65c9284de422600/coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/ac/45dc2e19a1939098d783c846e130b8f862fbb50d09e0af663988f2f21973/coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/2d/4d/26d236ff35abc3b5e63540d3386e4c3b192168c1d96da5cb2f43c640970f/coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/ec/55/14a966c757d1348b2e19caf699415a2a4c4f7feaa4bbc6326a51f5c7dd1b/coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/33/50116647905837c66d28b2af1321b845d5f5d19be9655cb84d4a0ea806b4/coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c2/b4/8efb11a46e3665d92635a56e4f2d4529de6d33f2cb38afd47d779d15fc99/coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/51/24/8cd73dd399b812cc76bb0ac260e671c4163093441847ffe058ac9fda1e32/coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/03/94/0a4b12f1d0e029ce1ccc1c800944a9984cbe7d678e470bb6d3c6bc38a0da/coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/44/6002fbf88f6698ca034360ce474c406be6d5a985b3fdb3401128031eef6b/coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"}}, - {name = "coverage-7.13.4-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/de/c6/a0279f7c00e786be75a749a5674e6fa267bcbd8209cd10c9a450c655dfa7/coverage-7.13.4-cp312-cp312-win32.whl",hashes = {sha256 = "01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"}}, - {name = "coverage-7.13.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/77/4e/c0a25a425fcf5557d9abd18419c95b63922e897bc86c1f327f155ef234a9/coverage-7.13.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"}}, - {name = "coverage-7.13.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/47/ac/92da44ad9a6f4e3a7debd178949d6f3769bedca33830ce9b1dcdab589a37/coverage-7.13.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"}}, - {name = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"}}, - {name = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"}}, - {name = "coverage-7.13.4-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl",hashes = {sha256 = "784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"}}, - {name = "coverage-7.13.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"}}, - {name = "coverage-7.13.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"}}, - {name = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/d4/7827d9ffa34d5d4d752eec907022aa417120936282fc488306f5da08c292/coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"}}, - {name = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/b0/d69df26607c64043292644dbb9dc54b0856fabaa2cbb1eeee3331cc9e280/coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/82/a4/c1523f7c9e47b2271dbf8c2a097e7a1f89ef0d66f5840bb59b7e8814157b/coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/02/aa7ec01d1a5023c4b680ab7257f9bfde9defe8fdddfe40be096ac19e8177/coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/35/98/85aba0aed5126d896162087ef3f0e789a225697245256fc6181b95f47207/coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/96/72/1db59bd67494bc162e3e4cd5fbc7edba2c7026b22f7c8ef1496d58c2b94c/coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/9d/97/72899c59c7066961de6e3daa142d459d47d104956db43e057e034f015c8a/coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/39/1f/f1885573b5970235e908da4389176936c8933e86cb316b9620aab1585fa2/coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a8/cf/e80390c5b7480b722fa3e994f8202807799b85bc562aa4f1dde209fbb7be/coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/bf/f89a8350d85572f95412debb0fb9bb4795b1d5b5232bd652923c759e787b/coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/6e/612a02aece8178c818df273e8d1642190c4875402ca2ba74514394b27aba/coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/cb/98/b5afc39af67c2fa6786b03c3a7091fc300947387ce8914b096db8a73d67a/coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"}}, - {name = "coverage-7.13.4-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/51/30/2bba8ef0682d5bd210c38fe497e12a06c9f8d663f7025e9f5c2c31ce847d/coverage-7.13.4-cp310-cp310-win32.whl",hashes = {sha256 = "a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"}}, - {name = "coverage-7.13.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/78/13/331f94934cf6c092b8ea59ff868eb587bc8fe0893f02c55bc6c0183a192e/coverage-7.13.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"}}, - {name = "coverage-7.13.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl",hashes = {sha256 = "1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}}, +sdist = {name = "coverage-7.13.5.tar.gz", url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hashes = {sha256 = "c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179"}} +wheels = [ + {name = "coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f"}}, + {name = "coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0"}}, + {name = "coverage-7.13.5-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl",hashes = {sha256 = "35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc"}}, + {name = "coverage-7.13.5-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl",hashes = {sha256 = "2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633"}}, + {name = "coverage-7.13.5-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl",hashes = {sha256 = "1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8"}}, + {name = "coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b"}}, + {name = "coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a"}}, + {name = "coverage-7.13.5-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl",hashes = {sha256 = "0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215"}}, + {name = "coverage-7.13.5-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43"}}, + {name = "coverage-7.13.5-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45"}}, + {name = "coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/8c/74fedc9663dcf168b0a059d4ea756ecae4da77a489048f94b5f512a8d0b3/coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1"}}, + {name = "coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/5f/13/93419671cee82b780bab7ea96b67c8ef448f5f295f36bf5031154ec9a790/coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/4e/5e/3ee3b835647be646dcf3c65a7c6c18f87c27326a858f72ab22c12730773d/coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/b3/cb5bd1a04cfcc49ede6cd8409d80bee17661167686741e041abc7ee1b9a9/coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/1b/66/c1dceb7b9714473800b075f5c8a84f4588f887a90eb8645282031676e242/coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b7/62/5502b73b97aa2e53ea22a39cf8649ff44827bef76d90bf638777daa27a9d/coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/7d/37/7792c2d69854397ca77a55c4646e5897c467928b0e27f2d235d83b5d08c6/coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a3/23/bc866fb6163be52a8a9e5d708ba0d3b1283c12158cefca0a8bbb6e247a43/coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/7d/8b/ef67e1c222ef49860701d346b8bbb70881bef283bd5f6cbba68a39a086c7/coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/46/0d/866d1f74f0acddbb906db212e096dee77a8e2158ca5e6bb44729f9d93298/coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17"}}, + {name = "coverage-7.13.5-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/7a/f5/be742fec31118f02ce42b21c6af187ad6a344fed546b56ca60caacc6a9a0/coverage-7.13.5-cp313-cp313-win32.whl",hashes = {sha256 = "ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85"}}, + {name = "coverage-7.13.5-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl",hashes = {sha256 = "631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b"}}, + {name = "coverage-7.13.5-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/48/af/fea819c12a095781f6ccd504890aaddaf88b8fab263c4940e82c7b770124/coverage-7.13.5-cp313-cp313-win_arm64.whl",hashes = {sha256 = "f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664"}}, + {name = "coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/d2/17879af479df7fbbd44bd528a31692a48f6b25055d16482fdf5cdb633805/coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d"}}, + {name = "coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5b/4c/d20e554f988c8f91d6a02c5118f9abbbf73a8768a3048cb4962230d5743f/coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/29/9c/f9f5277b95184f764b24e7231e166dfdb5780a46d408a2ac665969416d61/coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d5/f6/7f1ab39393eeb50cfe4747ae8ef0e4fc564b989225aa1152e13a180d74f8/coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/d7/62c084fb489ed9c6fbdf57e006752e7c516ea46fd690e5ed8b8617c7d52e/coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a9/f6/df63d8660e1a0bff6125947afda112a0502736f470d62ca68b288ea762d8/coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/5b/02/353ca81d36779bd108f6d384425f7139ac3c58c750dcfaafe5d0bee6436b/coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/16/2e79106d5749bcaf3aee6d309123548e3276517cd7851faa8da213bc61bf/coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/29/c7/c29e0c59ffa6942030ae6f50b88ae49988e7e8da06de7ecdbf49c6d4feae/coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/40/48/097cdc3db342f34006a308ab41c3a7c11c3f0d84750d340f45d88a782e00/coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/bb/1f/4994af354689e14fd03a75f8ec85a9a68d94e0188bbdab3fc1516b55e512/coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/22/c6/9bb9ef55903e628033560885f5c31aa227e46878118b63ab15dc7ba87797/coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2"}}, + {name = "coverage-7.13.5-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/14/4f/f5df9007e50b15e53e01edea486814783a7f019893733d9e4d6caad75557/coverage-7.13.5-cp313-cp313t-win32.whl",hashes = {sha256 = "67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a"}}, + {name = "coverage-7.13.5-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e1/98/aa7fccaa97d0f3192bec013c4e6fd6d294a6ed44b640e6bb61f479e00ed5/coverage-7.13.5-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819"}}, + {name = "coverage-7.13.5-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/3d/8b/e5c469f7352651e5f013198e9e21f97510b23de957dd06a84071683b4b60/coverage-7.13.5-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911"}}, + {name = "coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/a0/c3/a396306ba7db865bf96fc1fb3b7fd29bcbf3d829df642e77b13555163cd6/coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01"}}, + {name = "coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a6/16/a68a19e5384e93f811dccc51034b1fd0b865841c390e3c931dcc4699e035/coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/29/72/20b917c6793af3a5ceb7fb9c50033f3ec7865f2911a1416b34a7cfa0813b/coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8c/49/cd14b789536ac6a4778c453c6a2338bc0a2fb60c5a5a41b4008328b9acc1/coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/9d/00/7b0edcfe64e2ed4c0340dac14a52ad0f4c9bd0b8b5e531af7d55b703db7c/coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/93/89/7ffc4ba0f5d0a55c1e84ea7cee39c9fc06af7b170513d83fbf3bbefce280/coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/81/bd/73ddf85f93f7e6fa83e77ccecb6162d9415c79007b4bc124008a4995e4a7/coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/81/278aff4e8dec4926a0bcb9486320752811f543a3ce5b602cc7a29978d073/coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/70/ee/fe1621488e2e0a58d7e94c4800f0d96f79671553488d401a612bebae324b/coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/a6/f79fb37aa104b562207cc23cb5711ab6793608e246cae1e93f26b2236ed9/coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/75/f0/ed15262a58ec81ce457ceb717b7f78752a1713556b19081b76e90896e8d4/coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/e9/9129958f20e7e9d4d56d51d42ccf708d15cac355ff4ac6e736e97a9393d2/coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c"}}, + {name = "coverage-7.13.5-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/a4/d7/0ad9b15812d81272db94379fe4c6df8fd17781cc7671fdfa30c76ba5ff7b/coverage-7.13.5-cp312-cp312-win32.whl",hashes = {sha256 = "bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf"}}, + {name = "coverage-7.13.5-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/29/3d/821a9a5799fac2556bcf0bd37a70d1d11fa9e49784b6d22e92e8b2f85f18/coverage-7.13.5-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810"}}, + {name = "coverage-7.13.5-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/2238c2ad08e35cf4f020ea721f717e09ec3152aea75d191a7faf3ef009a8/coverage-7.13.5-cp312-cp312-win_arm64.whl",hashes = {sha256 = "bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de"}}, + {name = "coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/4b/37/d24c8f8220ff07b839b2c043ea4903a33b0f455abe673ae3c03bbdb7f212/coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d"}}, + {name = "coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/55/2f/e0e5b237bffdb5d6c530ce87cc1d413a5b7d7dfd60fb067ad6d254c35c76/coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/da/69/2f47bb6fa1b8d1e3e5d0c4be8ccb4313c63d742476a619418f85740d597b/coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d5/d0/79db81da58965bd29dabc8f4ad2a2af70611a57cba9d1ec006f072f30a54/coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e5/32/d0d7cc8168f91ddab44c0ce4806b969df5f5fdfdbb568eaca2dbc2a04936/coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4d/06/a055311d891ddbe231cd69fdd20ea4be6e3603ffebddf8704b8ca8e10a3c/coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d6/f6/d0fd2d21e29a657b5f77a2fe7082e1568158340dceb941954f776dce1b7b/coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/4e/ab/0d7fb2efc2e9a5eb7ddcc6e722f834a69b454b7e6e5888c3a8567ecffb31/coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ba/6f/7467b917bbf5408610178f62a49c0ed4377bb16c1657f689cc61470da8ce/coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/75/2c/1172fb689df92135f5bfbbd69fc83017a76d24ea2e2f3a1154007e2fb9f8/coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8"}}, + {name = "coverage-7.13.5-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/67/21/9ac389377380a07884e3b48ba7a620fcd9dbfaf1d40565facdc6b36ec9ef/coverage-7.13.5-cp311-cp311-win32.whl",hashes = {sha256 = "259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf"}}, + {name = "coverage-7.13.5-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl",hashes = {sha256 = "258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9"}}, + {name = "coverage-7.13.5-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/a6/1d3f6155fb0010ca68eba7fe48ca6c9da7385058b77a95848710ecf189b1/coverage-7.13.5-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028"}}, + {name = "coverage-7.13.5-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/69/33/e8c48488c29a73fd089f9d71f9653c1be7478f2ad6b5bc870db11a55d23d/coverage-7.13.5-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "e0723d2c96324561b9aa76fb982406e11d93cdb388a7a7da2b16e04719cf7ca5"}}, + {name = "coverage-7.13.5-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/da/bd/b0ebe9f677d7f4b74a3e115eec7ddd4bcf892074963a00d91e8b164a6386/coverage-7.13.5-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "52f444e86475992506b32d4e5ca55c24fc88d73bcbda0e9745095b28ef4dc0cf"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/48/cc/5cb9502f4e01972f54eedd48218bb203fe81e294be606a2bc93970208013/coverage-7.13.5-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "704de6328e3d612a8f6c07000a878ff38181ec3263d5a11da1db294fa6a9bdf8"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/7d/d8/3217636d86c7e7b12e126e4f30ef1581047da73140614523af7495ed5f2d/coverage-7.13.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "a1a6d79a14e1ec1832cabc833898636ad5f3754a678ef8bb4908515208bf84f4"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/30/2002ac6729ba2d4357438e2ed3c447ad8562866c8c63fc16f6dfc33afe56/coverage-7.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "79060214983769c7ba3f0cee10b54c97609dca4d478fa1aa32b914480fd5738d"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/6c/85/552496626d6b9359eb0e2f86f920037c9cbfba09b24d914c6e1528155f7d/coverage-7.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "356e76b46783a98c2a2fe81ec79df4883a1e62895ea952968fb253c114e7f930"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/44/21/40256eabdcbccdb6acf6b381b3016a154399a75fe39d406f790ae84d1f3c/coverage-7.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "0cef0cdec915d11254a7f549c1170afecce708d30610c6abdded1f74e581666d"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/e8/96e2a6c3f21a0ea77d7830b254a1542d0328acc8d7bdf6a284ba7e529f77/coverage-7.13.5-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "dc022073d063b25a402454e5712ef9e007113e3a676b96c5f29b2bda29352f40"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/da/ba/8477f549e554827da390ec659f3c38e4b6d95470f4daafc2d8ff94eaa9c2/coverage-7.13.5-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "9b74db26dfea4f4e50d48a4602207cd1e78be33182bc9cbf22da94f332f99878"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/55/59/bc22aef0e6aa179d5b1b001e8b3654785e9adf27ef24c93dc4228ebd5d68/coverage-7.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "ad146744ca4fd09b50c482650e3c1b1f4dfa1d4792e0a04a369c7f23336f0400"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/de/1b/c6a023a160806a5137dca53468fd97530d6acad24a22003b1578a9c2e429/coverage-7.13.5-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "c555b48be1853fe3997c11c4bd521cdd9a9612352de01fa4508f16ec341e6fe0"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/2d/3f/3532c85a55aa2f899fa17c186f831cfa1aa434d88ff792a709636f64130e/coverage-7.13.5-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7034b5c56a58ae5e85f23949d52c14aca2cfc6848a31764995b7de88f13a1ea0"}}, + {name = "coverage-7.13.5-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/aa/2e/b9d56af4a24ef45dfbcda88e06870cb7d57b2b0bfa3a888d79b4c8debd76/coverage-7.13.5-cp310-cp310-win32.whl",hashes = {sha256 = "eb7fdf1ef130660e7415e0253a01a7d5a88c9c4d158bcf75cbbd922fd65a5b58"}}, + {name = "coverage-7.13.5-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/cc/d938417e7a4d7f0433ad4edee8bb2acdc60dc7ac5af19e2a07a048ecbee3/coverage-7.13.5-cp310-cp310-win_amd64.whl",hashes = {sha256 = "3e1bb5f6c78feeb1be3475789b14a0f0a5b47d505bfc7267126ccbd50289999e"}}, + {name = "coverage-7.13.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl",hashes = {sha256 = "34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61"}}, ] marker = "\"test\" in dependency_groups" @@ -223,44 +223,44 @@ dependencies = [] [[packages]] name = "duckdb" -version = "1.5.0" +version = "1.5.1" requires-python = ">=3.10.0" -sdist = {name = "duckdb-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/ee/11/e05a7eb73a373d523e45d83c261025e02bc31ebf868e6282c30c4d02cc59/duckdb-1.5.0.tar.gz", hashes = {sha256 = "f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd"}} -wheels = [ - {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/66/9f/dd806d4e8ecd99006eb240068f34e1054533da1857ad06ac726305cd102d/duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa"}}, - {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/c2/7b7b8a5c65d5535c88a513e267b5e6d7a55ab3e9b67e4ddd474454653268/duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021"}}, - {name = "duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/23/c5/9a52a2cdb228b8d8d191a603254364d929274d9cc7d285beada8f7daa712/duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985"}}, - {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/68/646045cb97982702a8a143dc2e45f3bdcb79fbe2d559a98d74b8c160e5e2/duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113"}}, - {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/1b/5abf0c7f38febb3b4a231c784223fceccfd3f2bfd957699d786f46e41ce6/duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c"}}, - {name = "duckdb-1.5.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/a4/a90f2901cc0a1ce7ca4f0564b8492b9dbfe048a6395b27933d46ae9be473/duckdb-1.5.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977"}}, - {name = "duckdb-1.5.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/64/aa/f14dd5e241ec80d9f9d82196ca65e0c53badfc8a7a619d5497c5626657ad/duckdb-1.5.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36"}}, - {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/35/5d/af5501221f42e4e3662c047ecec4dcd0761229fceeba3c67ad4d9d8741df/duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d"}}, - {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/bd/a278d73fedbd3783bf9aedb09cad4171fe8e55bd522952a84f6849522eb6/duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b"}}, - {name = "duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/76/fc/c916e928606946209c20fb50898dabf120241fb528a244e2bd8cde1bd9e2/duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656"}}, - {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/53/07/1390e69db922423b2e111e32ed342b3e8fad0a31c144db70681ea1ba4d56/duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6"}}, - {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/54/13/b58d718415cde993823a54952ea511d2612302f1d2bc220549d0cef752a4/duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f"}}, - {name = "duckdb-1.5.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e0/96/4460429651e371eb5ff745a4790e7fa0509c7a58c71fc4f0f893404c9646/duckdb-1.5.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b"}}, - {name = "duckdb-1.5.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ba/54/6d5b805113214b830fa3c267bb3383fb8febaa30760d0162ef59aadb110a/duckdb-1.5.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8"}}, - {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/43/73/120e673e48ae25aaf689044c25ef51b0ea1d088563c9a2532612aea18e0a/duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd"}}, - {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/21/e9/61143471958d36d3f3e764cb4cd43330be208ddbff1c78d3310b9ee67fe8/duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375"}}, - {name = "duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4f/71/76e37c9a599ad89dd944e6cbb3e6a8ad196944a421758e83adea507637b6/duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59"}}, - {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/b8/de1831656d5d13173e27c79c7259c8b9a7bdc314fdc8920604838ea4c46d/duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30"}}, - {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/8d/33d349a3bcbd3e9b7b4e904c19d5b97f058c4c20791b89a8d6323bb93dce/duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6"}}, - {name = "duckdb-1.5.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/ec/591a4cad582fae04bc8f8b4a435eceaaaf3838cf0ca771daae16a3c2995b/duckdb-1.5.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86"}}, - {name = "duckdb-1.5.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/db/62/42e0a13f9919173bec121c0ff702406e1cdd91d8084c3e0b3412508c3891/duckdb-1.5.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7"}}, - {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/01/0c/0282b10a1c96810606b916b8d58a03f2131bd3ede14d2851f58b0b860e7c/duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86"}}, - {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/e8/cbbc920078a794f24f63017fc55c9cbdb17d6fb94d3973f479b2d9f2983d/duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41"}}, - {name = "duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/31/b6/6cae794d5856259b0060f79d5db71c7fdba043950eaa6a9d72b0bad16095/duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16"}}, - {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/82/07/aba3887658b93a36ce702dd00ca6a6422de3d14c7ee3a4b4c03ea20a99c0/duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2"}}, - {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/a2/723e6df48754e468fa50d7878eb860906c975eafe317c4134a8482ca220e/duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417"}}, - {name = "duckdb-1.5.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/03/af/4dcbdf8f2349ed0b054c254ec59bc362ce6ddf603af35f770124c0984686/duckdb-1.5.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2"}}, - {name = "duckdb-1.5.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/60/5e/1bb7e75a63bf3dc49bc5a2cd27a65ffeef151f52a32db980983516f2d9f6/duckdb-1.5.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298"}}, - {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/e0/5d/8fa129bbd604d0e91aa9a0a407e7d2acc559b6024c3f887868fd7a13871d/duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78"}}, - {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/0c/31/db320641a262a897755e634d16838c98d5ca7dc91f4e096e104e244a3a01/duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa"}}, - {name = "duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0b/45/5725684794fbabf54d8dbae5247685799a6bf8e1e930ebff3a76a726772c/duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381"}}, - {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/27/68/f110c66b43e27191d7e53d3587e118568b73d66f23cb9bd6c7e0a560fd6d/duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999"}}, - {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/ec/9d/46affc9257377cbc865e494650312a7a08a56e85aa8d702eb297bec430b7/duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730"}}, - {name = "duckdb-1.5.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/34/dac03ab7340989cda258655387959c88342ea3b44949751391267bcbc830/duckdb-1.5.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac"}}, +sdist = {name = "duckdb-1.5.1.tar.gz", url = "https://files.pythonhosted.org/packages/ae/62/590caabec6c41003f46a244b6fd707d35ca2e552e0c70cbf454e08bf6685/duckdb-1.5.1.tar.gz", hashes = {sha256 = "b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d"}} +wheels = [ + {name = "duckdb-1.5.1-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/ad/75/e9e7893542ca738bcde2d41d459e3438950219c71c57ad28b049dc2ae616/duckdb-1.5.1-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161"}}, + {name = "duckdb-1.5.1-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/db/f7420ee7109a922124c02f377ae1c56156e9e4aa434f4726848adaef0219/duckdb-1.5.1-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87"}}, + {name = "duckdb-1.5.1-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/df/57/2c4c3de1f1110417592741863ba58b4eca2f7690a421712762ddbdcd72e6/duckdb-1.5.1-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e"}}, + {name = "duckdb-1.5.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/81/e173b33ffac53124a3e39e97fb60a538f26651a0df6e393eb9bf7540126c/duckdb-1.5.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc"}}, + {name = "duckdb-1.5.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/4c/47e838393aa90d3d78549c8c04cb09452efeb14aaae0ee24dc0bd61c3a41/duckdb-1.5.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d"}}, + {name = "duckdb-1.5.1-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f4/9b/ce65743e0e85f5c984d2f7e8a81bc908d0bac345d6d8b6316436b29430e7/duckdb-1.5.1-cp314-cp314-win_amd64.whl",hashes = {sha256 = "d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f"}}, + {name = "duckdb-1.5.1-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e6/ac/f9e4e731635192571f86f52d86234f537c7f8ca4f6917c56b29051c077ef/duckdb-1.5.1-cp314-cp314-win_arm64.whl",hashes = {sha256 = "a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7"}}, + {name = "duckdb-1.5.1-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/a5/f2/af476945e3b97417945b0f660b5efa661863547c0ea104251bb6387342b1/duckdb-1.5.1-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9"}}, + {name = "duckdb-1.5.1-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/fe/9d/5a542b3933647369e601175190093597ce0ac54909aea0dd876ec51ffad4/duckdb-1.5.1-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c"}}, + {name = "duckdb-1.5.1-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/53/a5/b59cff67f5e0420b8f337ad86406801cffacae219deed83961dcceefda67/duckdb-1.5.1-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f"}}, + {name = "duckdb-1.5.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/12/d72a82fe502aae82b97b481bf909be8e22db5a403290799ad054b4f90eb4/duckdb-1.5.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91"}}, + {name = "duckdb-1.5.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/f9/c3/ee49319b15f139e04c067378f0e763f78336fbab38ba54b0852467dd9da4/duckdb-1.5.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1"}}, + {name = "duckdb-1.5.1-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a8/f5/a15498e75a27a136c791ca1889beade96d388dadf9811375db155fc96d1a/duckdb-1.5.1-cp313-cp313-win_amd64.whl",hashes = {sha256 = "05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a"}}, + {name = "duckdb-1.5.1-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/93/81/b3612d2bbe237f75791095e16767c61067ea5d31c76e8591c212dac13bd0/duckdb-1.5.1-cp313-cp313-win_arm64.whl",hashes = {sha256 = "a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07"}}, + {name = "duckdb-1.5.1-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/3f/06/be4c62f812c6e23898733073ace0482eeb18dffabe0585d63a3bf38bca1e/duckdb-1.5.1-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6"}}, + {name = "duckdb-1.5.1-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/03/1794dcdda75ff203ab0982ff7eb5232549b58b9af66f243f1b7212d6d6be/duckdb-1.5.1-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225"}}, + {name = "duckdb-1.5.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/87/03/293bccd838a293d42ea26dec7f4eb4f58b57b6c9ffcfabc6518a5f20a24a/duckdb-1.5.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59"}}, + {name = "duckdb-1.5.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/15/2c/7b4f11879aa2924838168b4640da999dccda1b4a033d43cb998fd6dc33ea/duckdb-1.5.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23"}}, + {name = "duckdb-1.5.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/6f/d6/8f9a6b1fbcc669108ec6a4d625a70be9e480b437ed9b70cd56b78cd577a6/duckdb-1.5.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611"}}, + {name = "duckdb-1.5.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c4/fe/8d02c6473273468cf8d43fd5d73c677f8cdfcd036c1e884df0613f124c2b/duckdb-1.5.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9"}}, + {name = "duckdb-1.5.1-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/96/0b/2be786b9c153eb263bf5d3d5f7ab621b14a715d7e70f92b24ecf8536369e/duckdb-1.5.1-cp312-cp312-win_arm64.whl",hashes = {sha256 = "6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb"}}, + {name = "duckdb-1.5.1-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/42/3e/827ffcf58f0abc6ad6dcf826c5d24ebfc65e03ad1a20d74cad9806f91c99/duckdb-1.5.1-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad"}}, + {name = "duckdb-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/04/b5/e921ecf8a7e0cc7da2100c98bef64b3da386df9444f467d6389364851302/duckdb-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3"}}, + {name = "duckdb-1.5.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/da/ed804006cd09ba303389d573c8b15d74220667cbd1fd990c26e98d0e0a5b/duckdb-1.5.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101"}}, + {name = "duckdb-1.5.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/43/c904d81a61306edab81a9d74bb37bbe65679639abb7030d4c4fec9ed84f7/duckdb-1.5.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141"}}, + {name = "duckdb-1.5.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/50/db/358715d677bfe5e117d9e1f2d6cc2fc2b0bd621144d1f15335b8b59f95d7/duckdb-1.5.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71"}}, + {name = "duckdb-1.5.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3f/db/fd647ce46315347976f5576a279bacb8134d23b1f004bd0bcda7ce9cf429/duckdb-1.5.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130"}}, + {name = "duckdb-1.5.1-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/27/95/e29d42792707619da5867ffab338d7e7b086242c7296aa9cfc6dcf52d568/duckdb-1.5.1-cp311-cp311-win_arm64.whl",hashes = {sha256 = "5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723"}}, + {name = "duckdb-1.5.1-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/eb/63/d6477057ea6103f80ed9499580c8602183211689889ec50c32f25a935e3d/duckdb-1.5.1-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096"}}, + {name = "duckdb-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b8/22e6c605d9281df7a83653f4a60168eec0f650b23f1d4648aca940d79d00/duckdb-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b"}}, + {name = "duckdb-1.5.1-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/85/b1/88a457cd3105525cba0d4c155f847c5c32fa4f543d3ba4ee38b4fd75f82e/duckdb-1.5.1-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea"}}, + {name = "duckdb-1.5.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/c5/3b/800c3f1d54ae0062b3e9b0b54fc54d6c155d731311931d748fc9c5c565f9/duckdb-1.5.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5"}}, + {name = "duckdb-1.5.1-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/09/4c4dd94f521d016e0fb83cca2c203d10ce1e3f8bcc679691b5271fc98b83/duckdb-1.5.1-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7"}}, + {name = "duckdb-1.5.1-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d0/b3/eb3c70be70d0b3fa6c8051d6fa4b7fb3d5787fa77b3f50b7e38d5f7cc6fd/duckdb-1.5.1-cp310-cp310-win_amd64.whl",hashes = {sha256 = "e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277"}}, ] marker = "\"default\" in dependency_groups" @@ -832,7 +832,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} +hashes = {sha256 = "061931787fa314a49ab4166aff1388c48f1f32235d8761350e985732c46520b3"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.maximal.toml b/pylock.maximal.toml index 346435c..473e11d 100644 --- a/pylock.maximal.toml +++ b/pylock.maximal.toml @@ -82,41 +82,41 @@ dependencies = [] [[packages]] name = "coverage" -version = "7.13.4" +version = "7.13.5" requires-python = ">=3.10" -sdist = {name = "coverage-7.13.4.tar.gz", url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hashes = {sha256 = "e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}} -wheels = [ - {name = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}}, - {name = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}}, - {name = "coverage-7.13.4-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl",hashes = {sha256 = "8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}}, - {name = "coverage-7.13.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}}, - {name = "coverage-7.13.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}}, - {name = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}}, - {name = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}}, - {name = "coverage-7.13.4-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl",hashes = {sha256 = "c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}}, - {name = "coverage-7.13.4-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}}, - {name = "coverage-7.13.4-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}}, - {name = "coverage-7.13.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl",hashes = {sha256 = "1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}}, +sdist = {name = "coverage-7.13.5.tar.gz", url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hashes = {sha256 = "c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179"}} +wheels = [ + {name = "coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f"}}, + {name = "coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0"}}, + {name = "coverage-7.13.5-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl",hashes = {sha256 = "35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc"}}, + {name = "coverage-7.13.5-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl",hashes = {sha256 = "2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633"}}, + {name = "coverage-7.13.5-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl",hashes = {sha256 = "1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8"}}, + {name = "coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b"}}, + {name = "coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a"}}, + {name = "coverage-7.13.5-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl",hashes = {sha256 = "0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215"}}, + {name = "coverage-7.13.5-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43"}}, + {name = "coverage-7.13.5-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45"}}, + {name = "coverage-7.13.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl",hashes = {sha256 = "34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61"}}, ] marker = "python_version >= \"3.14\" and \"test\" in dependency_groups" @@ -125,17 +125,17 @@ dependencies = [] [[packages]] name = "duckdb" -version = "1.5.0" +version = "1.5.1" requires-python = ">=3.10.0" -sdist = {name = "duckdb-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/ee/11/e05a7eb73a373d523e45d83c261025e02bc31ebf868e6282c30c4d02cc59/duckdb-1.5.0.tar.gz", hashes = {sha256 = "f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd"}} +sdist = {name = "duckdb-1.5.1.tar.gz", url = "https://files.pythonhosted.org/packages/ae/62/590caabec6c41003f46a244b6fd707d35ca2e552e0c70cbf454e08bf6685/duckdb-1.5.1.tar.gz", hashes = {sha256 = "b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d"}} wheels = [ - {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/66/9f/dd806d4e8ecd99006eb240068f34e1054533da1857ad06ac726305cd102d/duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa"}}, - {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/c2/7b7b8a5c65d5535c88a513e267b5e6d7a55ab3e9b67e4ddd474454653268/duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021"}}, - {name = "duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/23/c5/9a52a2cdb228b8d8d191a603254364d929274d9cc7d285beada8f7daa712/duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985"}}, - {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/68/646045cb97982702a8a143dc2e45f3bdcb79fbe2d559a98d74b8c160e5e2/duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113"}}, - {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/1b/5abf0c7f38febb3b4a231c784223fceccfd3f2bfd957699d786f46e41ce6/duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c"}}, - {name = "duckdb-1.5.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/a4/a90f2901cc0a1ce7ca4f0564b8492b9dbfe048a6395b27933d46ae9be473/duckdb-1.5.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977"}}, - {name = "duckdb-1.5.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/64/aa/f14dd5e241ec80d9f9d82196ca65e0c53badfc8a7a619d5497c5626657ad/duckdb-1.5.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36"}}, + {name = "duckdb-1.5.1-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/ad/75/e9e7893542ca738bcde2d41d459e3438950219c71c57ad28b049dc2ae616/duckdb-1.5.1-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161"}}, + {name = "duckdb-1.5.1-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/db/f7420ee7109a922124c02f377ae1c56156e9e4aa434f4726848adaef0219/duckdb-1.5.1-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87"}}, + {name = "duckdb-1.5.1-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/df/57/2c4c3de1f1110417592741863ba58b4eca2f7690a421712762ddbdcd72e6/duckdb-1.5.1-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e"}}, + {name = "duckdb-1.5.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/81/e173b33ffac53124a3e39e97fb60a538f26651a0df6e393eb9bf7540126c/duckdb-1.5.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc"}}, + {name = "duckdb-1.5.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/4c/47e838393aa90d3d78549c8c04cb09452efeb14aaae0ee24dc0bd61c3a41/duckdb-1.5.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d"}}, + {name = "duckdb-1.5.1-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f4/9b/ce65743e0e85f5c984d2f7e8a81bc908d0bac345d6d8b6316436b29430e7/duckdb-1.5.1-cp314-cp314-win_amd64.whl",hashes = {sha256 = "d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f"}}, + {name = "duckdb-1.5.1-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e6/ac/f9e4e731635192571f86f52d86234f537c7f8ca4f6917c56b29051c077ef/duckdb-1.5.1-cp314-cp314-win_arm64.whl",hashes = {sha256 = "a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7"}}, ] marker = "python_version >= \"3.14\" and \"default\" in dependency_groups" @@ -576,7 +576,7 @@ marker = "sys_platform == \"win32\" and python_version >= \"3.14\" and \"default dependencies = [] [tool.pdm] -hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} +hashes = {sha256 = "061931787fa314a49ab4166aff1388c48f1f32235d8761350e985732c46520b3"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.minimal.toml b/pylock.minimal.toml index f47e824..527e5d3 100644 --- a/pylock.minimal.toml +++ b/pylock.minimal.toml @@ -209,38 +209,34 @@ dependencies = [] [[packages]] name = "duckdb" -version = "1.3.0" -requires-python = ">=3.7.0" -sdist = {name = "duckdb-1.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/3e/82/680b108da1870e48d98464ddcf03820f983421b5bbd8dd8beff98d583db7/duckdb-1.3.0.tar.gz", hashes = {sha256 = "09aaa4b1dca24f4d1f231e7ae66b6413e317b7e04e2753541d42df6c8113fac7"}} -wheels = [ - {name = "duckdb-1.3.0-cp313-cp313-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/32/d5/d2666a682cda7152d0f391067e0307eec3e913b3462d2b5b944a3aab4d1d/duckdb-1.3.0-cp313-cp313-macosx_12_0_arm64.whl",hashes = {sha256 = "176b9818d940c52ac7f31c64a98cf172d7c19d2a006017c9c4e9c06c246e36bf"}}, - {name = "duckdb-1.3.0-cp313-cp313-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/91/60/feb19a432c0b327b3d03171042acbafa688edb9a02f3034f7ae963d0f62d/duckdb-1.3.0-cp313-cp313-macosx_12_0_universal2.whl",hashes = {sha256 = "03981f7e8793f07a4a9a2ba387640e71d0a99ebcaf8693ab09f96d59e628b713"}}, - {name = "duckdb-1.3.0-cp313-cp313-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/f8/393beb10a24115347c8a4b75d59e6e1d49f7391722717a614bb71430673a/duckdb-1.3.0-cp313-cp313-macosx_12_0_x86_64.whl",hashes = {sha256 = "a177d55a38a62fdf79b59a0eaa32531a1dbb443265f6d67f64992cc1e82b755c"}}, - {name = "duckdb-1.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/71/45/da77973a7da7747385e16aa88c65a7b0e634585b5f7f92a6bb423838077c/duckdb-1.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b1c30e3749823147d5578bc3f01f35d1a0433a1c768908d946056ec8d6e1757e"}}, - {name = "duckdb-1.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/51/adc86c800e7ecfe828e94cccc28ac727b54a886124da08e3808cf77bf1b9/duckdb-1.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5855f3a564baf22eeeab70c120b51f5a11914f1f1634f03382daeb6b1dea4c62"}}, - {name = "duckdb-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/9d/ac3a6ddcaaf9bbd5584bb471794f017498326d11f754ee28b3c0a5c7aee8/duckdb-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9b1fac15a48056f7c2739cf8800873063ba2f691e91a9b2fc167658a401ca76a"}}, - {name = "duckdb-1.3.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ab/e9/f83285b0cb3729f24321a038f272490dfb76ca531b7cef832037b7bd077c/duckdb-1.3.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "fbdfc1c0b83b90f780ae74038187ee696bb56ab727a289752372d7ec42dda65b"}}, - {name = "duckdb-1.3.0-cp312-cp312-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e4/b8/0931871f55a10aacd1af024c8d1e5de68337032379438aba05e26e9a1132/duckdb-1.3.0-cp312-cp312-macosx_12_0_arm64.whl",hashes = {sha256 = "f24038fe9b83dcbaeafb1ed76ec3b3f38943c1c8d27ab464ad384db8a6658b61"}}, - {name = "duckdb-1.3.0-cp312-cp312-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/af/d5/a08f76900391ff248b18fc1d5742db4b7bcf910c4be00314ce7b3069223f/duckdb-1.3.0-cp312-cp312-macosx_12_0_universal2.whl",hashes = {sha256 = "956c85842841bef68f4a5388c6b225b933151a7c06d568390fc895fc44607913"}}, - {name = "duckdb-1.3.0-cp312-cp312-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/05/f1/9dfa45484422bd6c598e76fb2d005de48373aea66b037471b4568c1e938a/duckdb-1.3.0-cp312-cp312-macosx_12_0_x86_64.whl",hashes = {sha256 = "efe883d822ed56fcfbb6a7b397c13f6a0d2eaeb3bc4ef4510f84fadb3dfe416d"}}, - {name = "duckdb-1.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/4e/093944cbca2e4b3fe5da99c46df9f4ae293c6768f15f14a959aaa2064a50/duckdb-1.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3872a3a1b80ffba5264ea236a3754d0c41d3c7b01bdf8cdcb1c180fc1b8dc8e2"}}, - {name = "duckdb-1.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b0/9e/b1a7c086db03f3cc85c513e70034bd515e68e25013875e5f0b40c4bf5d0a/duckdb-1.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "30bf45ad78a5a997f378863e036e917b481d18d685e5c977cd0a3faf2e31fbaf"}}, - {name = "duckdb-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5e/b4/5baef852efec9480dcfb44bed5adc56f6fcee09919037cf54fbbe87ac427/duckdb-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "85cbd8e1d65df8a0780023baf5045d3033fabd154799bc9ea6d9ab5728f41eb3"}}, - {name = "duckdb-1.3.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/36/4f/f7ab120ecd827fdff59f14e1de9771335aa7656a29c3259fa7949de1f276/duckdb-1.3.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "8754c40dac0f26d9fb0363bbb5df02f7a61ce6a6728d5efc02c3bc925d7c89c3"}}, - {name = "duckdb-1.3.0-cp311-cp311-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/48/a5/0a7dd8f256aa75e254717732905fb96858a9e54e881a5da0966b5760393a/duckdb-1.3.0-cp311-cp311-macosx_12_0_arm64.whl",hashes = {sha256 = "60a58b85929754abb21db1e739d2f53eaef63e6015e62ba58eae3425030e7935"}}, - {name = "duckdb-1.3.0-cp311-cp311-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/10/b9/5a2275f765f3ca6375797066bc3870bdc8dc3f4c91b84f4230709e012c50/duckdb-1.3.0-cp311-cp311-macosx_12_0_universal2.whl",hashes = {sha256 = "1d46b5a20f078b1b2284243e02a1fde7e12cbb8d205fce62e4700bcfe6a09881"}}, - {name = "duckdb-1.3.0-cp311-cp311-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/a4/f6/20da96bc7e3886cf424461a45de3f76247b7731a5f7552615bd31e73f1ac/duckdb-1.3.0-cp311-cp311-macosx_12_0_x86_64.whl",hashes = {sha256 = "0044e5ffb2d46308099640a92f99980a44e12bb68642aa9e6b08acbf300d64a1"}}, - {name = "duckdb-1.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/43/21/ffe5aeb9d32a49d2de6d368b3fe3e53c2246eccec916375d65c45dc58339/duckdb-1.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5cb813de2ca2f5e7c77392a67bdcaa174bfd69ebbfdfc983024af270c77a0447"}}, - {name = "duckdb-1.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/0c/111dc4a3dcdd7007ca610e41a85634fbfa258ab960a6445e02872b67ab02/duckdb-1.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "7a0c993eb6df2b30b189ad747f3aea1b0b87b78ab7f80c6e7c57117b6e8dbfb0"}}, - {name = "duckdb-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/00/71c174b65f167af4d77aafa6a01445f08238e84dd679638836472f1141af/duckdb-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "6728e209570d36ece66dd7249e5d6055326321137cd807f26300733283930cd4"}}, - {name = "duckdb-1.3.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/2c/cb/c84a617f79bedb2220ea0b0a9826b2fb1a534568c5742789ca2c0812d465/duckdb-1.3.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "7e652b7c8dbdb91a94fd7d543d3e115d24a25aa0791a373a852e20cb7bb21154"}}, - {name = "duckdb-1.3.0-cp310-cp310-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8d/8f/ac97536d4ba130c9ec097c99b88ce4fa2ceb2c90471d4f0312066c1c694d/duckdb-1.3.0-cp310-cp310-macosx_12_0_arm64.whl",hashes = {sha256 = "fc65c1e97aa010359c43c0342ea423e6efa3cb8c8e3f133b0765451ce674e3db"}}, - {name = "duckdb-1.3.0-cp310-cp310-macosx_12_0_universal2.whl",url = "https://files.pythonhosted.org/packages/db/30/d8a740b91021056b00f6d5c6ce8136f15fbc4a738ff8a9ce0b4a3d29604d/duckdb-1.3.0-cp310-cp310-macosx_12_0_universal2.whl",hashes = {sha256 = "8fc91b629646679e33806342510335ccbbeaf2b823186f0ae829fd48e7a63c66"}}, - {name = "duckdb-1.3.0-cp310-cp310-macosx_12_0_x86_64.whl",url = "https://files.pythonhosted.org/packages/5a/d0/75cdba51cc7f35494d8621267cd6ac8de9a649f12fa64c9a2e2b2892f55b/duckdb-1.3.0-cp310-cp310-macosx_12_0_x86_64.whl",hashes = {sha256 = "1a69b970553fd015c557238d427ef00be3c8ed58c3bc3641aef987e33f8bf614"}}, - {name = "duckdb-1.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/fe/3e/164119d03fabf2851ef36b4cccd1763d7950aadea2466cbf0e568e7de9fe/duckdb-1.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1003e84c07b84680cee6d06e4795b6e861892474704f7972058594a52c7473cf"}}, - {name = "duckdb-1.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/27/a5a21c73eea6dbc207a426f13c23358712e444ba4ce9f4fa7e8cb3f73a09/duckdb-1.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "992239b54ca6f015ad0ed0d80f3492c065313c4641df0a226183b8860cb7f5b0"}}, - {name = "duckdb-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f7/e4/5ac11e11fec8cef4780b3867c0bda258650444a46793827a0ab473765853/duckdb-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0ba1c5af59e8147216149b814b1970b8f7e3c240494a9688171390db3c504b29"}}, - {name = "duckdb-1.3.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/68/89/57c0812d9d9c899b0986a1ec1c80a91ea9056bc9a718777caae42ae3a0a2/duckdb-1.3.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "57b794ca28e22b23bd170506cb1d4704a3608e67f0fe33273db9777b69bdf26a"}}, +version = "1.4.1" +requires-python = ">=3.9.0" +sdist = {name = "duckdb-1.4.1.tar.gz", url = "https://files.pythonhosted.org/packages/ea/e7/21cf50a3d52ffceee1f0bcc3997fa96a5062e6bab705baee4f6c4e33cce5/duckdb-1.4.1.tar.gz", hashes = {sha256 = "f903882f045d057ebccad12ac69975952832edfe133697694854bb784b8d6c76"}} +wheels = [ + {name = "duckdb-1.4.1-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/d7/08/705988c33e38665c969f7876b3ca4328be578554aa7e3dc0f34158da3e64/duckdb-1.4.1-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "46496a2518752ae0c6c5d75d4cdecf56ea23dd098746391176dd8e42cf157791"}}, + {name = "duckdb-1.4.1-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/99/c5/7c9165f1e6b9069441bcda4da1e19382d4a2357783d37ff9ae238c5c41ac/duckdb-1.4.1-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "1c65ae7e9b541cea07d8075343bcfebdecc29a3c0481aa6078ee63d51951cfcd"}}, + {name = "duckdb-1.4.1-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/38/46/267f4a570a0ee3ae6871ddc03435f9942884284e22a7ba9b7cb252ee69b6/duckdb-1.4.1-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "598d1a314e34b65d9399ddd066ccce1eeab6a60a2ef5885a84ce5ed62dbaf729"}}, + {name = "duckdb-1.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/15/7b/c4f272a40c36d82df20937d93a1780eb39ab0107fe42b62cba889151eab9/duckdb-1.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "e2f16b8def782d484a9f035fc422bb6f06941ed0054b4511ddcdc514a7fb6a75"}}, + {name = "duckdb-1.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/17/fc/9b958751f0116d7b0406406b07fa6f5a10c22d699be27826d0b896f9bf51/duckdb-1.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "a5a7d0aed068a5c33622a8848857947cab5cfb3f2a315b1251849bac2c74c492"}}, + {name = "duckdb-1.4.1-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/30/79/4f544d73fcc0513b71296cb3ebb28a227d22e80dec27204977039b9fa875/duckdb-1.4.1-cp313-cp313-win_amd64.whl",hashes = {sha256 = "280fd663dacdd12bb3c3bf41f3e5b2e5b95e00b88120afabb8b8befa5f335c6f"}}, + {name = "duckdb-1.4.1-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/0e/6c/906a3fe41cd247b5638866fc1245226b528de196588802d4df4df1e6e819/duckdb-1.4.1-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "cd1765a7d180b7482874586859fc23bc9969d7d6c96ced83b245e6c6f49cde7f"}}, + {name = "duckdb-1.4.1-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/66/c7/01dd33083f01f618c2a29f6dd068baf16945b8cbdb132929d3766610bbbb/duckdb-1.4.1-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "8ed7a86725185470953410823762956606693c0813bb64e09c7d44dbd9253a64"}}, + {name = "duckdb-1.4.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/e2/f983b4b7ae1dfbdd2792dd31dee9a0d35f88554452cbfc6c9d65e22fdfa9/duckdb-1.4.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "8a189bdfc64cfb9cc1adfbe4f2dcfde0a4992ec08505ad8ce33c886e4813f0bf"}}, + {name = "duckdb-1.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ed/34/fb69a7be19b90f573b3cc890961be7b11870b77514769655657514f10a98/duckdb-1.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a9090089b6486f7319c92acdeed8acda022d4374032d78a465956f50fc52fabf"}}, + {name = "duckdb-1.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/a5/1395d7b49d5589e85da9a9d7ffd8b50364c9d159c2807bef72d547f0ad1e/duckdb-1.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "142552ea3e768048e0e8c832077a545ca07792631c59edaee925e3e67401c2a0"}}, + {name = "duckdb-1.4.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c0/21/08f10706d30252753349ec545833fc0cea67c11abd0b5223acf2827f1056/duckdb-1.4.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "567f3b3a785a9e8650612461893c49ca799661d2345a6024dda48324ece89ded"}}, + {name = "duckdb-1.4.1-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/d9/52/606f13fa9669a24166d2fe523e28982d8ef9039874b4de774255c7806d1f/duckdb-1.4.1-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "605d563c1d5203ca992497cd33fb386ac3d533deca970f9dcf539f62a34e22a9"}}, + {name = "duckdb-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/84/57/138241952ece868b9577e607858466315bed1739e1fbb47205df4dfdfd88/duckdb-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "d3305c7c4b70336171de7adfdb50431f23671c000f11839b580c4201d9ce6ef5"}}, + {name = "duckdb-1.4.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a3/81/afa3a0a78498a6f4acfea75c48a70c5082032d9ac87822713d7c2d164af1/duckdb-1.4.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "a063d6febbe34b32f1ad2e68822db4d0e4b1102036f49aaeeb22b844427a75df"}}, + {name = "duckdb-1.4.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/47/dd/5f6064fbd9248e37a3e806a244f81e0390ab8f989d231b584fb954f257fc/duckdb-1.4.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d1ffcaaf74f7d1df3684b54685cbf8d3ce732781c541def8e1ced304859733ae"}}, + {name = "duckdb-1.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a1/10/b54969a1c42fd9344ad39228d671faceb8aa9f144b67cd9531a63551757f/duckdb-1.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "685d3d1599dc08160e0fa0cf09e93ac4ff8b8ed399cb69f8b5391cd46b5b207c"}}, + {name = "duckdb-1.4.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ed/d5/7332ae8f804869a4e895937821b776199a283f8d9fc775fd3ae5a0558099/duckdb-1.4.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "78f1d28a15ae73bd449c43f80233732adffa49be1840a32de8f1a6bb5b286764"}}, + {name = "duckdb-1.4.1-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/68/cc/00a07de0e33d16763edd4132d7c8a2f9efd57a2f296a25a948f239a1fadf/duckdb-1.4.1-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "296b4fff3908fb4c47b0aa1d77bd1933375e75401009d2dc81af8e7a0b8a05b4"}}, + {name = "duckdb-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/17/ea/fb0fda8886d1928f1b2a53a1163ef94f6f4b41f6d8b29eee457acfc2fa67/duckdb-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "0b4182800092115feee5d71a8691efb283d3c9f5eb0b36362b308ef007a12222"}}, + {name = "duckdb-1.4.1-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/b4/5f/052e6436a71f461e61cd3a982954c029145a84b58cefa1dfb3eb2d96e4fc/duckdb-1.4.1-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "67cc3b6c7f7ba07a69e9331b8ccea7a60cbcd4204bb473e5da9b71588bd2eca9"}}, + {name = "duckdb-1.4.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/c2/fd/3ae3c89d0f6ad54c0be4430e572306fbfc9f173c97b23c5025a540449325/duckdb-1.4.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0cef0cee7030b561640cb9af718f8841b19cdd2aa020d53561057b5743bea90b"}}, + {name = "duckdb-1.4.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/3c/eef454cd7c3880c2d55b50e18a9c7a213bf91ded79efcfb573d8d6dd8a47/duckdb-1.4.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "2bf93347f37a46bacce6ac859d651dbf5731e2c94a64ab358300425b09e3de23"}}, + {name = "duckdb-1.4.1-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bb/5b/b619f4c986a1cb0b06315239da9ce5fd94a20c07a344d03e2635d56a6967/duckdb-1.4.1-cp310-cp310-win_amd64.whl",hashes = {sha256 = "2e60d2361f978908a3d96eebaf1f4b346f283afcc467351aae50ea45ca293a2b"}}, ] marker = "\"default\" in dependency_groups" @@ -727,7 +723,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} +hashes = {sha256 = "061931787fa314a49ab4166aff1388c48f1f32235d8761350e985732c46520b3"} strategy = ["direct_minimal_versions", "inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pylock.toml b/pylock.toml index b0cd92d..7185c13 100644 --- a/pylock.toml +++ b/pylock.toml @@ -106,115 +106,115 @@ dependencies = [] [[packages]] name = "coverage" -version = "7.13.4" +version = "7.13.5" requires-python = ">=3.10" -sdist = {name = "coverage-7.13.4.tar.gz", url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hashes = {sha256 = "e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}} -wheels = [ - {name = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}}, - {name = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}}, - {name = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}}, - {name = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}}, - {name = "coverage-7.13.4-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl",hashes = {sha256 = "8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}}, - {name = "coverage-7.13.4-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl",hashes = {sha256 = "245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}}, - {name = "coverage-7.13.4-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl",hashes = {sha256 = "ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}}, - {name = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}}, - {name = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}}, - {name = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}}, - {name = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}}, - {name = "coverage-7.13.4-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl",hashes = {sha256 = "c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}}, - {name = "coverage-7.13.4-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}}, - {name = "coverage-7.13.4-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}}, - {name = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}}, - {name = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}}, - {name = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}}, - {name = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}}, - {name = "coverage-7.13.4-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl",hashes = {sha256 = "f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}}, - {name = "coverage-7.13.4-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}}, - {name = "coverage-7.13.4-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}}, - {name = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}}, - {name = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}}, - {name = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}}, - {name = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}}, - {name = "coverage-7.13.4-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl",hashes = {sha256 = "2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}}, - {name = "coverage-7.13.4-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}}, - {name = "coverage-7.13.4-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}}, - {name = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"}}, - {name = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/a0/2ea570925524ef4e00bb6c82649f5682a77fac5ab910a65c9284de422600/coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e8/ac/45dc2e19a1939098d783c846e130b8f862fbb50d09e0af663988f2f21973/coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/2d/4d/26d236ff35abc3b5e63540d3386e4c3b192168c1d96da5cb2f43c640970f/coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"}}, - {name = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/ec/55/14a966c757d1348b2e19caf699415a2a4c4f7feaa4bbc6326a51f5c7dd1b/coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/77/33/50116647905837c66d28b2af1321b845d5f5d19be9655cb84d4a0ea806b4/coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/c2/b4/8efb11a46e3665d92635a56e4f2d4529de6d33f2cb38afd47d779d15fc99/coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/51/24/8cd73dd399b812cc76bb0ac260e671c4163093441847ffe058ac9fda1e32/coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/03/94/0a4b12f1d0e029ce1ccc1c800944a9984cbe7d678e470bb6d3c6bc38a0da/coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"}}, - {name = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/73/44/6002fbf88f6698ca034360ce474c406be6d5a985b3fdb3401128031eef6b/coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"}}, - {name = "coverage-7.13.4-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/de/c6/a0279f7c00e786be75a749a5674e6fa267bcbd8209cd10c9a450c655dfa7/coverage-7.13.4-cp312-cp312-win32.whl",hashes = {sha256 = "01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"}}, - {name = "coverage-7.13.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/77/4e/c0a25a425fcf5557d9abd18419c95b63922e897bc86c1f327f155ef234a9/coverage-7.13.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"}}, - {name = "coverage-7.13.4-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/47/ac/92da44ad9a6f4e3a7debd178949d6f3769bedca33830ce9b1dcdab589a37/coverage-7.13.4-cp312-cp312-win_arm64.whl",hashes = {sha256 = "b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"}}, - {name = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"}}, - {name = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"}}, - {name = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"}}, - {name = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"}}, - {name = "coverage-7.13.4-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl",hashes = {sha256 = "784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"}}, - {name = "coverage-7.13.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"}}, - {name = "coverage-7.13.4-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl",hashes = {sha256 = "79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"}}, - {name = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/d4/7827d9ffa34d5d4d752eec907022aa417120936282fc488306f5da08c292/coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"}}, - {name = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/b0/d69df26607c64043292644dbb9dc54b0856fabaa2cbb1eeee3331cc9e280/coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/82/a4/c1523f7c9e47b2271dbf8c2a097e7a1f89ef0d66f5840bb59b7e8814157b/coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/02/aa7ec01d1a5023c4b680ab7257f9bfde9defe8fdddfe40be096ac19e8177/coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/35/98/85aba0aed5126d896162087ef3f0e789a225697245256fc6181b95f47207/coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/96/72/1db59bd67494bc162e3e4cd5fbc7edba2c7026b22f7c8ef1496d58c2b94c/coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"}}, - {name = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/9d/97/72899c59c7066961de6e3daa142d459d47d104956db43e057e034f015c8a/coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/39/1f/f1885573b5970235e908da4389176936c8933e86cb316b9620aab1585fa2/coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/a8/cf/e80390c5b7480b722fa3e994f8202807799b85bc562aa4f1dde209fbb7be/coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/bf/f89a8350d85572f95412debb0fb9bb4795b1d5b5232bd652923c759e787b/coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/f7/6e/612a02aece8178c818df273e8d1642190c4875402ca2ba74514394b27aba/coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"}}, - {name = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/cb/98/b5afc39af67c2fa6786b03c3a7091fc300947387ce8914b096db8a73d67a/coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"}}, - {name = "coverage-7.13.4-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/51/30/2bba8ef0682d5bd210c38fe497e12a06c9f8d663f7025e9f5c2c31ce847d/coverage-7.13.4-cp310-cp310-win32.whl",hashes = {sha256 = "a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"}}, - {name = "coverage-7.13.4-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/78/13/331f94934cf6c092b8ea59ff868eb587bc8fe0893f02c55bc6c0183a192e/coverage-7.13.4-cp310-cp310-win_amd64.whl",hashes = {sha256 = "2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"}}, - {name = "coverage-7.13.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl",hashes = {sha256 = "1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}}, +sdist = {name = "coverage-7.13.5.tar.gz", url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hashes = {sha256 = "c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179"}} +wheels = [ + {name = "coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f"}}, + {name = "coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6"}}, + {name = "coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0"}}, + {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0"}}, + {name = "coverage-7.13.5-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl",hashes = {sha256 = "35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc"}}, + {name = "coverage-7.13.5-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl",hashes = {sha256 = "2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633"}}, + {name = "coverage-7.13.5-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl",hashes = {sha256 = "1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8"}}, + {name = "coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b"}}, + {name = "coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90"}}, + {name = "coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea"}}, + {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a"}}, + {name = "coverage-7.13.5-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl",hashes = {sha256 = "0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215"}}, + {name = "coverage-7.13.5-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43"}}, + {name = "coverage-7.13.5-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45"}}, + {name = "coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/8c/74fedc9663dcf168b0a059d4ea756ecae4da77a489048f94b5f512a8d0b3/coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1"}}, + {name = "coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/5f/13/93419671cee82b780bab7ea96b67c8ef448f5f295f36bf5031154ec9a790/coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/4e/5e/3ee3b835647be646dcf3c65a7c6c18f87c27326a858f72ab22c12730773d/coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/b3/cb5bd1a04cfcc49ede6cd8409d80bee17661167686741e041abc7ee1b9a9/coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a"}}, + {name = "coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/1b/66/c1dceb7b9714473800b075f5c8a84f4588f887a90eb8645282031676e242/coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b7/62/5502b73b97aa2e53ea22a39cf8649ff44827bef76d90bf638777daa27a9d/coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/7d/37/7792c2d69854397ca77a55c4646e5897c467928b0e27f2d235d83b5d08c6/coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a3/23/bc866fb6163be52a8a9e5d708ba0d3b1283c12158cefca0a8bbb6e247a43/coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/7d/8b/ef67e1c222ef49860701d346b8bbb70881bef283bd5f6cbba68a39a086c7/coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6"}}, + {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/46/0d/866d1f74f0acddbb906db212e096dee77a8e2158ca5e6bb44729f9d93298/coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17"}}, + {name = "coverage-7.13.5-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/7a/f5/be742fec31118f02ce42b21c6af187ad6a344fed546b56ca60caacc6a9a0/coverage-7.13.5-cp313-cp313-win32.whl",hashes = {sha256 = "ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85"}}, + {name = "coverage-7.13.5-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl",hashes = {sha256 = "631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b"}}, + {name = "coverage-7.13.5-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/48/af/fea819c12a095781f6ccd504890aaddaf88b8fab263c4940e82c7b770124/coverage-7.13.5-cp313-cp313-win_arm64.whl",hashes = {sha256 = "f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664"}}, + {name = "coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/d2/17879af479df7fbbd44bd528a31692a48f6b25055d16482fdf5cdb633805/coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d"}}, + {name = "coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5b/4c/d20e554f988c8f91d6a02c5118f9abbbf73a8768a3048cb4962230d5743f/coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/29/9c/f9f5277b95184f764b24e7231e166dfdb5780a46d408a2ac665969416d61/coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d5/f6/7f1ab39393eeb50cfe4747ae8ef0e4fc564b989225aa1152e13a180d74f8/coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/d7/62c084fb489ed9c6fbdf57e006752e7c516ea46fd690e5ed8b8617c7d52e/coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a9/f6/df63d8660e1a0bff6125947afda112a0502736f470d62ca68b288ea762d8/coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd"}}, + {name = "coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/5b/02/353ca81d36779bd108f6d384425f7139ac3c58c750dcfaafe5d0bee6436b/coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/16/2e79106d5749bcaf3aee6d309123548e3276517cd7851faa8da213bc61bf/coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/29/c7/c29e0c59ffa6942030ae6f50b88ae49988e7e8da06de7ecdbf49c6d4feae/coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/40/48/097cdc3db342f34006a308ab41c3a7c11c3f0d84750d340f45d88a782e00/coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/bb/1f/4994af354689e14fd03a75f8ec85a9a68d94e0188bbdab3fc1516b55e512/coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479"}}, + {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/22/c6/9bb9ef55903e628033560885f5c31aa227e46878118b63ab15dc7ba87797/coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2"}}, + {name = "coverage-7.13.5-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/14/4f/f5df9007e50b15e53e01edea486814783a7f019893733d9e4d6caad75557/coverage-7.13.5-cp313-cp313t-win32.whl",hashes = {sha256 = "67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a"}}, + {name = "coverage-7.13.5-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e1/98/aa7fccaa97d0f3192bec013c4e6fd6d294a6ed44b640e6bb61f479e00ed5/coverage-7.13.5-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819"}}, + {name = "coverage-7.13.5-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/3d/8b/e5c469f7352651e5f013198e9e21f97510b23de957dd06a84071683b4b60/coverage-7.13.5-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911"}}, + {name = "coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/a0/c3/a396306ba7db865bf96fc1fb3b7fd29bcbf3d829df642e77b13555163cd6/coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01"}}, + {name = "coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a6/16/a68a19e5384e93f811dccc51034b1fd0b865841c390e3c931dcc4699e035/coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/29/72/20b917c6793af3a5ceb7fb9c50033f3ec7865f2911a1416b34a7cfa0813b/coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8c/49/cd14b789536ac6a4778c453c6a2338bc0a2fb60c5a5a41b4008328b9acc1/coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/9d/00/7b0edcfe64e2ed4c0340dac14a52ad0f4c9bd0b8b5e531af7d55b703db7c/coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/93/89/7ffc4ba0f5d0a55c1e84ea7cee39c9fc06af7b170513d83fbf3bbefce280/coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256"}}, + {name = "coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/81/bd/73ddf85f93f7e6fa83e77ccecb6162d9415c79007b4bc124008a4995e4a7/coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/81/278aff4e8dec4926a0bcb9486320752811f543a3ce5b602cc7a29978d073/coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/70/ee/fe1621488e2e0a58d7e94c4800f0d96f79671553488d401a612bebae324b/coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/a6/f79fb37aa104b562207cc23cb5711ab6793608e246cae1e93f26b2236ed9/coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/75/f0/ed15262a58ec81ce457ceb717b7f78752a1713556b19081b76e90896e8d4/coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf"}}, + {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/e9/9129958f20e7e9d4d56d51d42ccf708d15cac355ff4ac6e736e97a9393d2/coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c"}}, + {name = "coverage-7.13.5-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/a4/d7/0ad9b15812d81272db94379fe4c6df8fd17781cc7671fdfa30c76ba5ff7b/coverage-7.13.5-cp312-cp312-win32.whl",hashes = {sha256 = "bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf"}}, + {name = "coverage-7.13.5-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/29/3d/821a9a5799fac2556bcf0bd37a70d1d11fa9e49784b6d22e92e8b2f85f18/coverage-7.13.5-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810"}}, + {name = "coverage-7.13.5-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/2238c2ad08e35cf4f020ea721f717e09ec3152aea75d191a7faf3ef009a8/coverage-7.13.5-cp312-cp312-win_arm64.whl",hashes = {sha256 = "bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de"}}, + {name = "coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/4b/37/d24c8f8220ff07b839b2c043ea4903a33b0f455abe673ae3c03bbdb7f212/coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d"}}, + {name = "coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/55/2f/e0e5b237bffdb5d6c530ce87cc1d413a5b7d7dfd60fb067ad6d254c35c76/coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/da/69/2f47bb6fa1b8d1e3e5d0c4be8ccb4313c63d742476a619418f85740d597b/coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d5/d0/79db81da58965bd29dabc8f4ad2a2af70611a57cba9d1ec006f072f30a54/coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743"}}, + {name = "coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e5/32/d0d7cc8168f91ddab44c0ce4806b969df5f5fdfdbb568eaca2dbc2a04936/coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4d/06/a055311d891ddbe231cd69fdd20ea4be6e3603ffebddf8704b8ca8e10a3c/coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d6/f6/d0fd2d21e29a657b5f77a2fe7082e1568158340dceb941954f776dce1b7b/coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/4e/ab/0d7fb2efc2e9a5eb7ddcc6e722f834a69b454b7e6e5888c3a8567ecffb31/coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ba/6f/7467b917bbf5408610178f62a49c0ed4377bb16c1657f689cc61470da8ce/coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd"}}, + {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/75/2c/1172fb689df92135f5bfbbd69fc83017a76d24ea2e2f3a1154007e2fb9f8/coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8"}}, + {name = "coverage-7.13.5-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/67/21/9ac389377380a07884e3b48ba7a620fcd9dbfaf1d40565facdc6b36ec9ef/coverage-7.13.5-cp311-cp311-win32.whl",hashes = {sha256 = "259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf"}}, + {name = "coverage-7.13.5-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl",hashes = {sha256 = "258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9"}}, + {name = "coverage-7.13.5-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/a6/1d3f6155fb0010ca68eba7fe48ca6c9da7385058b77a95848710ecf189b1/coverage-7.13.5-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028"}}, + {name = "coverage-7.13.5-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/69/33/e8c48488c29a73fd089f9d71f9653c1be7478f2ad6b5bc870db11a55d23d/coverage-7.13.5-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "e0723d2c96324561b9aa76fb982406e11d93cdb388a7a7da2b16e04719cf7ca5"}}, + {name = "coverage-7.13.5-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/da/bd/b0ebe9f677d7f4b74a3e115eec7ddd4bcf892074963a00d91e8b164a6386/coverage-7.13.5-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "52f444e86475992506b32d4e5ca55c24fc88d73bcbda0e9745095b28ef4dc0cf"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/48/cc/5cb9502f4e01972f54eedd48218bb203fe81e294be606a2bc93970208013/coverage-7.13.5-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "704de6328e3d612a8f6c07000a878ff38181ec3263d5a11da1db294fa6a9bdf8"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/7d/d8/3217636d86c7e7b12e126e4f30ef1581047da73140614523af7495ed5f2d/coverage-7.13.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "a1a6d79a14e1ec1832cabc833898636ad5f3754a678ef8bb4908515208bf84f4"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/30/2002ac6729ba2d4357438e2ed3c447ad8562866c8c63fc16f6dfc33afe56/coverage-7.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "79060214983769c7ba3f0cee10b54c97609dca4d478fa1aa32b914480fd5738d"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/6c/85/552496626d6b9359eb0e2f86f920037c9cbfba09b24d914c6e1528155f7d/coverage-7.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "356e76b46783a98c2a2fe81ec79df4883a1e62895ea952968fb253c114e7f930"}}, + {name = "coverage-7.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/44/21/40256eabdcbccdb6acf6b381b3016a154399a75fe39d406f790ae84d1f3c/coverage-7.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "0cef0cdec915d11254a7f549c1170afecce708d30610c6abdded1f74e581666d"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/e8/96e2a6c3f21a0ea77d7830b254a1542d0328acc8d7bdf6a284ba7e529f77/coverage-7.13.5-cp310-cp310-musllinux_1_2_aarch64.whl",hashes = {sha256 = "dc022073d063b25a402454e5712ef9e007113e3a676b96c5f29b2bda29352f40"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/da/ba/8477f549e554827da390ec659f3c38e4b6d95470f4daafc2d8ff94eaa9c2/coverage-7.13.5-cp310-cp310-musllinux_1_2_i686.whl",hashes = {sha256 = "9b74db26dfea4f4e50d48a4602207cd1e78be33182bc9cbf22da94f332f99878"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/55/59/bc22aef0e6aa179d5b1b001e8b3654785e9adf27ef24c93dc4228ebd5d68/coverage-7.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "ad146744ca4fd09b50c482650e3c1b1f4dfa1d4792e0a04a369c7f23336f0400"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/de/1b/c6a023a160806a5137dca53468fd97530d6acad24a22003b1578a9c2e429/coverage-7.13.5-cp310-cp310-musllinux_1_2_riscv64.whl",hashes = {sha256 = "c555b48be1853fe3997c11c4bd521cdd9a9612352de01fa4508f16ec341e6fe0"}}, + {name = "coverage-7.13.5-cp310-cp310-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/2d/3f/3532c85a55aa2f899fa17c186f831cfa1aa434d88ff792a709636f64130e/coverage-7.13.5-cp310-cp310-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7034b5c56a58ae5e85f23949d52c14aca2cfc6848a31764995b7de88f13a1ea0"}}, + {name = "coverage-7.13.5-cp310-cp310-win32.whl",url = "https://files.pythonhosted.org/packages/aa/2e/b9d56af4a24ef45dfbcda88e06870cb7d57b2b0bfa3a888d79b4c8debd76/coverage-7.13.5-cp310-cp310-win32.whl",hashes = {sha256 = "eb7fdf1ef130660e7415e0253a01a7d5a88c9c4d158bcf75cbbd922fd65a5b58"}}, + {name = "coverage-7.13.5-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/cc/d938417e7a4d7f0433ad4edee8bb2acdc60dc7ac5af19e2a07a048ecbee3/coverage-7.13.5-cp310-cp310-win_amd64.whl",hashes = {sha256 = "3e1bb5f6c78feeb1be3475789b14a0f0a5b47d505bfc7267126ccbd50289999e"}}, + {name = "coverage-7.13.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl",hashes = {sha256 = "34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61"}}, ] marker = "\"test\" in dependency_groups" @@ -223,44 +223,44 @@ dependencies = [] [[packages]] name = "duckdb" -version = "1.5.0" +version = "1.5.1" requires-python = ">=3.10.0" -sdist = {name = "duckdb-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/ee/11/e05a7eb73a373d523e45d83c261025e02bc31ebf868e6282c30c4d02cc59/duckdb-1.5.0.tar.gz", hashes = {sha256 = "f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd"}} -wheels = [ - {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/66/9f/dd806d4e8ecd99006eb240068f34e1054533da1857ad06ac726305cd102d/duckdb-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa"}}, - {name = "duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/c2/7b7b8a5c65d5535c88a513e267b5e6d7a55ab3e9b67e4ddd474454653268/duckdb-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021"}}, - {name = "duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/23/c5/9a52a2cdb228b8d8d191a603254364d929274d9cc7d285beada8f7daa712/duckdb-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985"}}, - {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/68/646045cb97982702a8a143dc2e45f3bdcb79fbe2d559a98d74b8c160e5e2/duckdb-1.5.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113"}}, - {name = "duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/15/1b/5abf0c7f38febb3b4a231c784223fceccfd3f2bfd957699d786f46e41ce6/duckdb-1.5.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c"}}, - {name = "duckdb-1.5.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/a4/a90f2901cc0a1ce7ca4f0564b8492b9dbfe048a6395b27933d46ae9be473/duckdb-1.5.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977"}}, - {name = "duckdb-1.5.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/64/aa/f14dd5e241ec80d9f9d82196ca65e0c53badfc8a7a619d5497c5626657ad/duckdb-1.5.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36"}}, - {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/35/5d/af5501221f42e4e3662c047ecec4dcd0761229fceeba3c67ad4d9d8741df/duckdb-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d"}}, - {name = "duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/bd/a278d73fedbd3783bf9aedb09cad4171fe8e55bd522952a84f6849522eb6/duckdb-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b"}}, - {name = "duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/76/fc/c916e928606946209c20fb50898dabf120241fb528a244e2bd8cde1bd9e2/duckdb-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656"}}, - {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/53/07/1390e69db922423b2e111e32ed342b3e8fad0a31c144db70681ea1ba4d56/duckdb-1.5.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6"}}, - {name = "duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/54/13/b58d718415cde993823a54952ea511d2612302f1d2bc220549d0cef752a4/duckdb-1.5.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f"}}, - {name = "duckdb-1.5.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e0/96/4460429651e371eb5ff745a4790e7fa0509c7a58c71fc4f0f893404c9646/duckdb-1.5.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b"}}, - {name = "duckdb-1.5.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ba/54/6d5b805113214b830fa3c267bb3383fb8febaa30760d0162ef59aadb110a/duckdb-1.5.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8"}}, - {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/43/73/120e673e48ae25aaf689044c25ef51b0ea1d088563c9a2532612aea18e0a/duckdb-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd"}}, - {name = "duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/21/e9/61143471958d36d3f3e764cb4cd43330be208ddbff1c78d3310b9ee67fe8/duckdb-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375"}}, - {name = "duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4f/71/76e37c9a599ad89dd944e6cbb3e6a8ad196944a421758e83adea507637b6/duckdb-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59"}}, - {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/b8/de1831656d5d13173e27c79c7259c8b9a7bdc314fdc8920604838ea4c46d/duckdb-1.5.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30"}}, - {name = "duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/8d/33d349a3bcbd3e9b7b4e904c19d5b97f058c4c20791b89a8d6323bb93dce/duckdb-1.5.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6"}}, - {name = "duckdb-1.5.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e2/ec/591a4cad582fae04bc8f8b4a435eceaaaf3838cf0ca771daae16a3c2995b/duckdb-1.5.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86"}}, - {name = "duckdb-1.5.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/db/62/42e0a13f9919173bec121c0ff702406e1cdd91d8084c3e0b3412508c3891/duckdb-1.5.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7"}}, - {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/01/0c/0282b10a1c96810606b916b8d58a03f2131bd3ede14d2851f58b0b860e7c/duckdb-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86"}}, - {name = "duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/e8/cbbc920078a794f24f63017fc55c9cbdb17d6fb94d3973f479b2d9f2983d/duckdb-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41"}}, - {name = "duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/31/b6/6cae794d5856259b0060f79d5db71c7fdba043950eaa6a9d72b0bad16095/duckdb-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16"}}, - {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/82/07/aba3887658b93a36ce702dd00ca6a6422de3d14c7ee3a4b4c03ea20a99c0/duckdb-1.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2"}}, - {name = "duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/a2/723e6df48754e468fa50d7878eb860906c975eafe317c4134a8482ca220e/duckdb-1.5.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417"}}, - {name = "duckdb-1.5.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/03/af/4dcbdf8f2349ed0b054c254ec59bc362ce6ddf603af35f770124c0984686/duckdb-1.5.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2"}}, - {name = "duckdb-1.5.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/60/5e/1bb7e75a63bf3dc49bc5a2cd27a65ffeef151f52a32db980983516f2d9f6/duckdb-1.5.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298"}}, - {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/e0/5d/8fa129bbd604d0e91aa9a0a407e7d2acc559b6024c3f887868fd7a13871d/duckdb-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78"}}, - {name = "duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/0c/31/db320641a262a897755e634d16838c98d5ca7dc91f4e096e104e244a3a01/duckdb-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa"}}, - {name = "duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0b/45/5725684794fbabf54d8dbae5247685799a6bf8e1e930ebff3a76a726772c/duckdb-1.5.0-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381"}}, - {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/27/68/f110c66b43e27191d7e53d3587e118568b73d66f23cb9bd6c7e0a560fd6d/duckdb-1.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999"}}, - {name = "duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/ec/9d/46affc9257377cbc865e494650312a7a08a56e85aa8d702eb297bec430b7/duckdb-1.5.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730"}}, - {name = "duckdb-1.5.0-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/34/dac03ab7340989cda258655387959c88342ea3b44949751391267bcbc830/duckdb-1.5.0-cp310-cp310-win_amd64.whl",hashes = {sha256 = "238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac"}}, +sdist = {name = "duckdb-1.5.1.tar.gz", url = "https://files.pythonhosted.org/packages/ae/62/590caabec6c41003f46a244b6fd707d35ca2e552e0c70cbf454e08bf6685/duckdb-1.5.1.tar.gz", hashes = {sha256 = "b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d"}} +wheels = [ + {name = "duckdb-1.5.1-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/ad/75/e9e7893542ca738bcde2d41d459e3438950219c71c57ad28b049dc2ae616/duckdb-1.5.1-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161"}}, + {name = "duckdb-1.5.1-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/db/f7420ee7109a922124c02f377ae1c56156e9e4aa434f4726848adaef0219/duckdb-1.5.1-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87"}}, + {name = "duckdb-1.5.1-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/df/57/2c4c3de1f1110417592741863ba58b4eca2f7690a421712762ddbdcd72e6/duckdb-1.5.1-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e"}}, + {name = "duckdb-1.5.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/81/e173b33ffac53124a3e39e97fb60a538f26651a0df6e393eb9bf7540126c/duckdb-1.5.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc"}}, + {name = "duckdb-1.5.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/4c/47e838393aa90d3d78549c8c04cb09452efeb14aaae0ee24dc0bd61c3a41/duckdb-1.5.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d"}}, + {name = "duckdb-1.5.1-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f4/9b/ce65743e0e85f5c984d2f7e8a81bc908d0bac345d6d8b6316436b29430e7/duckdb-1.5.1-cp314-cp314-win_amd64.whl",hashes = {sha256 = "d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f"}}, + {name = "duckdb-1.5.1-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e6/ac/f9e4e731635192571f86f52d86234f537c7f8ca4f6917c56b29051c077ef/duckdb-1.5.1-cp314-cp314-win_arm64.whl",hashes = {sha256 = "a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7"}}, + {name = "duckdb-1.5.1-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/a5/f2/af476945e3b97417945b0f660b5efa661863547c0ea104251bb6387342b1/duckdb-1.5.1-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9"}}, + {name = "duckdb-1.5.1-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/fe/9d/5a542b3933647369e601175190093597ce0ac54909aea0dd876ec51ffad4/duckdb-1.5.1-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c"}}, + {name = "duckdb-1.5.1-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/53/a5/b59cff67f5e0420b8f337ad86406801cffacae219deed83961dcceefda67/duckdb-1.5.1-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f"}}, + {name = "duckdb-1.5.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/12/d72a82fe502aae82b97b481bf909be8e22db5a403290799ad054b4f90eb4/duckdb-1.5.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91"}}, + {name = "duckdb-1.5.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/f9/c3/ee49319b15f139e04c067378f0e763f78336fbab38ba54b0852467dd9da4/duckdb-1.5.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1"}}, + {name = "duckdb-1.5.1-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a8/f5/a15498e75a27a136c791ca1889beade96d388dadf9811375db155fc96d1a/duckdb-1.5.1-cp313-cp313-win_amd64.whl",hashes = {sha256 = "05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a"}}, + {name = "duckdb-1.5.1-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/93/81/b3612d2bbe237f75791095e16767c61067ea5d31c76e8591c212dac13bd0/duckdb-1.5.1-cp313-cp313-win_arm64.whl",hashes = {sha256 = "a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07"}}, + {name = "duckdb-1.5.1-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/3f/06/be4c62f812c6e23898733073ace0482eeb18dffabe0585d63a3bf38bca1e/duckdb-1.5.1-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6"}}, + {name = "duckdb-1.5.1-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/44/03/1794dcdda75ff203ab0982ff7eb5232549b58b9af66f243f1b7212d6d6be/duckdb-1.5.1-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225"}}, + {name = "duckdb-1.5.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/87/03/293bccd838a293d42ea26dec7f4eb4f58b57b6c9ffcfabc6518a5f20a24a/duckdb-1.5.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59"}}, + {name = "duckdb-1.5.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/15/2c/7b4f11879aa2924838168b4640da999dccda1b4a033d43cb998fd6dc33ea/duckdb-1.5.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23"}}, + {name = "duckdb-1.5.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/6f/d6/8f9a6b1fbcc669108ec6a4d625a70be9e480b437ed9b70cd56b78cd577a6/duckdb-1.5.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611"}}, + {name = "duckdb-1.5.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c4/fe/8d02c6473273468cf8d43fd5d73c677f8cdfcd036c1e884df0613f124c2b/duckdb-1.5.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9"}}, + {name = "duckdb-1.5.1-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/96/0b/2be786b9c153eb263bf5d3d5f7ab621b14a715d7e70f92b24ecf8536369e/duckdb-1.5.1-cp312-cp312-win_arm64.whl",hashes = {sha256 = "6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb"}}, + {name = "duckdb-1.5.1-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/42/3e/827ffcf58f0abc6ad6dcf826c5d24ebfc65e03ad1a20d74cad9806f91c99/duckdb-1.5.1-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad"}}, + {name = "duckdb-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/04/b5/e921ecf8a7e0cc7da2100c98bef64b3da386df9444f467d6389364851302/duckdb-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3"}}, + {name = "duckdb-1.5.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dd/da/ed804006cd09ba303389d573c8b15d74220667cbd1fd990c26e98d0e0a5b/duckdb-1.5.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101"}}, + {name = "duckdb-1.5.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b3/43/c904d81a61306edab81a9d74bb37bbe65679639abb7030d4c4fec9ed84f7/duckdb-1.5.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141"}}, + {name = "duckdb-1.5.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/50/db/358715d677bfe5e117d9e1f2d6cc2fc2b0bd621144d1f15335b8b59f95d7/duckdb-1.5.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71"}}, + {name = "duckdb-1.5.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3f/db/fd647ce46315347976f5576a279bacb8134d23b1f004bd0bcda7ce9cf429/duckdb-1.5.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130"}}, + {name = "duckdb-1.5.1-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/27/95/e29d42792707619da5867ffab338d7e7b086242c7296aa9cfc6dcf52d568/duckdb-1.5.1-cp311-cp311-win_arm64.whl",hashes = {sha256 = "5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723"}}, + {name = "duckdb-1.5.1-cp310-cp310-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/eb/63/d6477057ea6103f80ed9499580c8602183211689889ec50c32f25a935e3d/duckdb-1.5.1-cp310-cp310-macosx_10_9_universal2.whl",hashes = {sha256 = "46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096"}}, + {name = "duckdb-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/ba/b8/22e6c605d9281df7a83653f4a60168eec0f650b23f1d4648aca940d79d00/duckdb-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl",hashes = {sha256 = "caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b"}}, + {name = "duckdb-1.5.1-cp310-cp310-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/85/b1/88a457cd3105525cba0d4c155f847c5c32fa4f543d3ba4ee38b4fd75f82e/duckdb-1.5.1-cp310-cp310-macosx_11_0_arm64.whl",hashes = {sha256 = "8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea"}}, + {name = "duckdb-1.5.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/c5/3b/800c3f1d54ae0062b3e9b0b54fc54d6c155d731311931d748fc9c5c565f9/duckdb-1.5.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5"}}, + {name = "duckdb-1.5.1-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/09/4c4dd94f521d016e0fb83cca2c203d10ce1e3f8bcc679691b5271fc98b83/duckdb-1.5.1-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7"}}, + {name = "duckdb-1.5.1-cp310-cp310-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d0/b3/eb3c70be70d0b3fa6c8051d6fa4b7fb3d5787fa77b3f50b7e38d5f7cc6fd/duckdb-1.5.1-cp310-cp310-win_amd64.whl",hashes = {sha256 = "e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277"}}, ] marker = "\"default\" in dependency_groups" @@ -832,7 +832,7 @@ marker = "sys_platform == \"win32\" and \"default\" in dependency_groups" dependencies = [] [tool.pdm] -hashes = {sha256 = "b3cf474c257071e375683a8f88215a2f04a2a1983dea8fae923264a6b0c3b3be"} +hashes = {sha256 = "061931787fa314a49ab4166aff1388c48f1f32235d8761350e985732c46520b3"} strategy = ["inherit_metadata", "static_urls"] [[tool.pdm.targets]] diff --git a/pyproject.toml b/pyproject.toml index a18a6f0..cf1f86a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,8 +11,9 @@ authors = [ { name = "Nassib Nassar", email = "nassib@indexdata.com" }, ] dependencies = [ - # 1.3 introduces json each - "duckdb>=1.3", + # 1.4 introduces WITH ORDINALITY + # 1.4.1 fixes https://github.com/duckdb/duckdb-python/issues/78 + "duckdb>=1.4.1", # pytz is required for timestamptz columns in duckdb # 2021.3 was released with 3.10 "pytz>=2021.3", diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index 7ab8cc8..de0324d 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -17,18 +17,17 @@ class DuckDbDatabase(TypedDatabase[duckdb.DuckDBPyConnection]): def __init__(self, db: duckdb.DuckDBPyConnection) -> None: # See the notes below for why we're monkey patching DuckDB super().__init__( - lambda: cast( + lambda _: cast( "duckdb.DuckDBPyConnection", _MonkeyDBPyConnection(db.cursor()), ), ) - @staticmethod - def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: - with conn.cursor() as cur: + with self._conn_factory(True) as cur: cur.execute( r""" -CREATE OR REPLACE FUNCTION ldlite_system.jtype_of(j) AS +-- These are shims to be able to use the postgres native operations. +CREATE OR REPLACE FUNCTION jsonb_typeof(j) AS CASE coalesce(main.json_type(j), 'NULL') WHEN 'VARCHAR' THEN 'string' WHEN 'BIGINT' THEN 'number' @@ -42,38 +41,14 @@ def _setup_jfuncs(conn: duckdb.DuckDBPyConnection) -> None: END ; -CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j) AS TABLE - SELECT je.key as ld_key FROM json_each(j) je ORDER BY je.id +CREATE OR REPLACE FUNCTION jsonb_object_keys(j) AS TABLE + SELECT je.key as ld_key, id as "ordinality" FROM json_each(j) je ORDER BY je.id ; -CREATE OR REPLACE FUNCTION ldlite_system.jis_uuid(j) AS - regexp_full_match(main.json_extract_string(j, '$'), '(?i)^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89abAB][a-f0-9]{3}-[a-f0-9]{12}$') -; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_datetime(j) AS - regexp_full_match(main.json_extract_string(j, '$'), '^\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?$') -; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j) AS - main.json_type(j) == 'DOUBLE' -; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_bigint(j) AS - COALESCE(TRY_CAST(j AS NUMERIC), 0) > 2147483647 -; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j) AS - j IS NULL OR j == 'null'::JSON OR main.json_extract_string(j, '$') IN ('NULL', 'null', '', '{}', '[]') -; - -CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j) AS TABLE ( - SELECT value as ld_value FROM main.json_each(j) +CREATE OR REPLACE FUNCTION jsonb_array_elements(j) AS TABLE ( + SELECT value as ld_value, rowid + 1 AS "ordinality" FROM main.json_each(j) ); - -CREATE OR REPLACE FUNCTION ldlite_system.jself_string(j) AS - main.json_extract_string(j, '$') -; -""", # noqa: E501 +""", ) @property @@ -92,7 +67,7 @@ def ingest_records( pfx = Prefix(prefix) download_started = datetime.now(timezone.utc) pkey = count(1) - with self._conn_factory() as conn: + with self._conn_factory(False) as conn: self._prepare_raw_table(conn, pfx) insert_sql = ( @@ -132,6 +107,7 @@ def close(self) -> None: def execute(self, *args, **kwargs) -> duckdb.DuckDBPyConnection: print(args[0]) return self._cur.execute(*args, **kwargs) + """ def __enter__(self) -> "Self": diff --git a/src/ldlite/database/_expansion/__init__.py b/src/ldlite/database/_expansion/__init__.py index ae78c48..0d1fe41 100644 --- a/src/ldlite/database/_expansion/__init__.py +++ b/src/ldlite/database/_expansion/__init__.py @@ -15,20 +15,20 @@ def expand_nonmarc( root_name: str, root_values: list[str], ctx: ExpandContext, -) -> list[str]: - (_, created_tables) = _expand_nonmarc( +) -> list[tuple[str, sql.Composed]]: + (_, tables_to_create) = _expand_nonmarc( ObjectNode(root_name, "", None, root_values), 0, ctx, ) - return created_tables + return tables_to_create -def _expand_nonmarc( +def _expand_nonmarc( # noqa: PLR0915 root: ObjectNode, count: int, ctx: ExpandContext, -) -> tuple[int, list[str]]: +) -> tuple[int, list[tuple[str, sql.Composed]]]: ctx.scan_progress.total = (ctx.scan_progress.total or 0) + 1 ctx.scan_progress.refresh() ctx.transform_progress.total = (ctx.transform_progress.total or 0) + 1 @@ -45,6 +45,13 @@ def _expand_nonmarc( if not has_rows: return (0, []) + with ctx.conn.cursor() as cur: + cur.execute( + sql.SQL("DROP TABLE {previous_table}") + .format(previous_table=ctx.source_table) + .as_string(), + ) + expand_children_of = deque([root]) while expand_children_of: on = expand_children_of.popleft() @@ -63,11 +70,17 @@ def _expand_nonmarc( ctx.get_transform_table(count + 1), ctx.source_cte(False), ) + with ctx.conn.cursor() as cur: + cur.execute( + sql.SQL("DROP TABLE {previous_table}") + .format(previous_table=ctx.get_transform_table(count)) + .as_string(), + ) expand_children_of.append(c) count += 1 ctx.transform_progress.update(1) - created_tables = [] + tables_to_create = [] new_source_table = ctx.get_transform_table(count) arrays = root.descendents_oftype(ArrayNode) @@ -86,7 +99,7 @@ def _expand_nonmarc( count += 1 ctx.transform_progress.update(1) - if an.meta.is_object: + if an.is_object: (sub_index, array_tables) = _expand_nonmarc( ObjectNode( an.name, @@ -101,29 +114,29 @@ def _expand_nonmarc( ), ) count += sub_index - created_tables.extend(array_tables) + tables_to_create.extend(array_tables) else: with ctx.conn.cursor() as cur: (tname, tid) = ctx.get_output_table(an.name) - created_tables.append(tname) - cur.execute( - sql.SQL( - """ + tables_to_create.append( + ( + tname, + sql.SQL( + """ CREATE TABLE {dest_table} AS """ - + ctx.source_cte(False) - + """ + + ctx.source_cte(False) + + """ SELECT {cols} FROM ld_source """, - ) - .format( - dest_table=tid, - source_table=ctx.get_transform_table(count), - cols=sql.SQL("\n ,").join( - [sql.Identifier(v) for v in [*values, an.name]], + ).format( + dest_table=tid, + source_table=ctx.get_transform_table(count), + cols=sql.SQL("\n ,").join( + [sql.Identifier(v) for v in [*values, an.name]], + ), ), - ) - .as_string(), + ), ) stamped_values = [ @@ -132,23 +145,23 @@ def _expand_nonmarc( with ctx.conn.cursor() as cur: (tname, tid) = ctx.get_output_table(root.path) - created_tables.append(tname) - cur.execute( - sql.SQL( - """ + tables_to_create.append( + ( + tname, + sql.SQL( + """ CREATE TABLE {dest_table} AS """ - + ctx.source_cte(False) - + """ + + ctx.source_cte(False) + + """ SELECT {cols} FROM ld_source """, - ) - .format( - dest_table=tid, - source_table=new_source_table, - cols=sql.SQL("\n ,").join(stamped_values), - ) - .as_string(), + ).format( + dest_table=tid, + source_table=new_source_table, + cols=sql.SQL("\n ,").join(stamped_values), + ), + ), ) - return (count + 1 - initial_count, created_tables) + return (count + 1 - initial_count, tables_to_create) diff --git a/src/ldlite/database/_expansion/metadata.py b/src/ldlite/database/_expansion/metadata.py index 995b812..7fbc2ee 100644 --- a/src/ldlite/database/_expansion/metadata.py +++ b/src/ldlite/database/_expansion/metadata.py @@ -1,34 +1,14 @@ from __future__ import annotations -from dataclasses import dataclass +from abc import ABC, abstractmethod from typing import Literal from psycopg import sql -@dataclass -class Metadata: - prop: str | None - # array is technically a type - # but the metadata query returns inner type of the array - # the jtype_of function normalizes the names between pg and duckdb - json_type: Literal["string", "number", "object", "boolean"] - is_array: bool - is_uuid: bool - is_datetime: bool - is_float: bool - is_bigint: bool - - def __post_init__(self) -> None: - # Mixed json_type columns (which shouldn't really happen) - # get STRING_AGG'ed with a pipe delimeter. - # Fallback to the lowest common denominator in this case. - if "|" in self.json_type: - object.__setattr__(self, "json_type", "string") - - @property - def is_object(self) -> bool: - return self.json_type == "object" +class Metadata(ABC): + def __init__(self, prop: str | None): + self.prop = prop @property def snake(self) -> str: @@ -44,37 +24,118 @@ def snake(self) -> str: return snake + @property + @abstractmethod + def select_stmt(self) -> str: ... + def select_column( self, json_col: sql.Identifier, alias: str, ) -> sql.Composed: + return sql.SQL(self.select_stmt + " AS {alias}").format( + json_col=json_col, + prop=self.prop, + alias=sql.Identifier(alias), + ) + + +class ObjectMeta(Metadata): + @property + def select_stmt(self) -> str: + return "{json_col}" if self.prop is None else "{json_col}->{prop}" + + +class ArrayMeta(Metadata): + @property + def select_stmt(self) -> str: + return "{json_col}" if self.prop is None else "{json_col}->{prop}" + + @abstractmethod + def unwrap(self) -> ObjectMeta | TypedMeta: ... + + +class TypedMeta(Metadata): + def __init__( # noqa: PLR0913 + self, + prop: str | None, + json_type: Literal["string", "number", "boolean"], + other_json_type: Literal["string", "number", "boolean"], + is_uuid: bool, + is_datetime: bool, + is_float: bool, + is_bigint: bool, + ): + super().__init__(prop) + + mixed_type = json_type != other_json_type + self.json_type: Literal["string", "number", "boolean"] = ( + json_type if not mixed_type else "string" + ) + self.is_uuid = is_uuid and not mixed_type + self.is_datetime = is_datetime and not mixed_type + self.is_float = is_float and not mixed_type + self.is_bigint = is_bigint and not mixed_type + + @property + def select_stmt(self) -> str: # noqa: PLR0911 str_extract = ( "{json_col}->>{prop}" if self.prop is not None - else "ldlite_system.jself_string({json_col})" + else """TRIM(BOTH '"' FROM ({json_col})::text)""" ) - nullable_str_extract = f"NULLIF(NULLIF({str_extract}, ''), 'null')" - - if self.is_array or self.is_object: - stmt = "{json_col}" if self.prop is None else "{json_col}->{prop}" - elif self.json_type == "number" and self.is_float: - stmt = f"({str_extract})::numeric" - elif self.json_type == "number" and self.is_bigint: - stmt = f"({str_extract})::bigint" - elif self.json_type == "number": - stmt = f"({str_extract})::integer" - elif self.json_type == "boolean": - stmt = f"({nullable_str_extract})::bool" - elif self.json_type == "string" and self.is_uuid: - stmt = f"({nullable_str_extract})::uuid" - elif self.json_type == "string" and self.is_datetime: - stmt = f"({nullable_str_extract})::timestamptz" - else: - stmt = nullable_str_extract - - return sql.SQL(stmt + " AS {alias}").format( - json_col=json_col, - prop=self.prop, - alias=sql.Identifier(alias), + str_extract = f"NULLIF(NULLIF({str_extract}, ''), 'null')" + + if self.json_type == "number" and self.is_float: + return f"{str_extract}::numeric" + if self.json_type == "number" and self.is_bigint: + return f"{str_extract}::bigint" + if self.json_type == "number": + return f"{str_extract}::integer" + if self.json_type == "boolean": + return f"{str_extract}::bool" + if self.json_type == "string" and self.is_uuid: + return f"{str_extract}::uuid" + if self.json_type == "string" and self.is_datetime: + return f"{str_extract}::timestamptz" + + return str_extract + + +class MixedMeta(TypedMeta): + def __init__( + self, + prop: str | None, + ): + super().__init__(prop, "string", "string", False, False, False, False) + + +class ObjectArrayMeta(ObjectMeta, ArrayMeta): + def unwrap(self) -> ObjectMeta: + return ObjectMeta(None) + + +class MixedArrayMeta(MixedMeta, ArrayMeta): + @property + def select_stmt(self) -> str: + return "{json_col}" if self.prop is None else "{json_col}->{prop}" + + def unwrap(self) -> MixedMeta: + return MixedMeta(None) + + +class TypedArrayMeta(TypedMeta, ArrayMeta): + @property + def select_stmt(self) -> str: + return "{json_col}" if self.prop is None else "{json_col}->{prop}" + + def unwrap(self) -> TypedMeta: + return TypedMeta( + None, + self.json_type, + self.json_type, + self.is_uuid, + self.is_datetime, + self.is_float, + self.is_bigint, ) diff --git a/src/ldlite/database/_expansion/nodes.py b/src/ldlite/database/_expansion/nodes.py index 4f91027..32626b5 100644 --- a/src/ldlite/database/_expansion/nodes.py +++ b/src/ldlite/database/_expansion/nodes.py @@ -1,7 +1,6 @@ from __future__ import annotations from collections import deque -from math import floor from typing import TYPE_CHECKING, TypeVar, cast from psycopg import sql @@ -14,7 +13,16 @@ from .context import ExpandContext -from .metadata import Metadata +from .metadata import ( + ArrayMeta, + Metadata, + MixedArrayMeta, + MixedMeta, + ObjectArrayMeta, + ObjectMeta, + TypedArrayMeta, + TypedMeta, +) TNode = TypeVar("TNode", bound="ExpansionNode") @@ -38,9 +46,9 @@ def add(self, meta: Metadata) -> str: snake = meta.snake prefixed_name = self.prefix + snake - if meta.is_array: + if isinstance(meta, ArrayMeta): self.children.append(ArrayNode(prefixed_name, snake, self, meta)) - elif meta.is_object: + elif isinstance(meta, ObjectMeta): self.children.append(ObjectNode(prefixed_name, snake, self)) else: prefixed_name = self.prefix + snake @@ -132,37 +140,24 @@ def unnest( with ctx.conn.cursor() as cur: cur.execute( - sql.SQL("SELECT COUNT(*) FROM {table}") + sql.SQL("SELECT 1 FROM {table} LIMIT 1;") .format(table=source_table) .as_string(), ) - total = cast("tuple[int]", cur.fetchone())[0] - if total == 0: + if not cur.fetchone(): return False with ctx.conn.cursor() as cur: cur.execute( sql.SQL( """ -WITH - keys AS ( - SELECT - keys.ld_key AS k - ,ROW_NUMBER() OVER (PARTITION BY t.__id) AS idx - FROM {source_table} t, ldlite_system.jobject_keys(t.{json_col}) keys - WHERE {json_col} IS NOT NULL AND ldlite_system.jtype_of(t.{json_col}) = 'object' - ), - ordered_keys AS ( - SELECT - k - ,MAX(idx) idx - ,COUNT(idx) freq - FROM keys - GROUP BY k - ) -SELECT k -FROM ordered_keys -ORDER BY idx, freq DESC +SELECT k.ld_key +FROM + {source_table} t + ,jsonb_object_keys(t.{json_col}) WITH ORDINALITY k(ld_key, "ordinality") +WHERE t.{json_col} IS NOT NULL AND jsonb_typeof(t.{json_col}) = 'object' +GROUP BY k.ld_key +ORDER BY MAX(k.ordinality), COUNT(k.ordinality) """, ) .format(source_table=source_table, json_col=self.identifier) @@ -170,85 +165,145 @@ def unnest( ) props = [prop[0] for prop in cur.fetchall()] - prop_count = len(props) - ctx.scan_progress.total += prop_count + ctx.scan_progress.total += len(props) * 3 ctx.scan_progress.refresh() ctx.scan_progress.update(1) + metadata: list[Metadata] = [] for prop in props: with ctx.conn.cursor() as cur: cur.execute( sql.SQL( """ -WITH - values AS ( - SELECT {json_col}->$1 as ld_value - FROM {table} - ), - value_and_types AS ( - SELECT - ldlite_system.jtype_of(ld_value) AS json_type - ,ld_value - FROM values - WHERE NOT ldlite_system.jis_null(ld_value) - ), - array_values AS ( - SELECT - ldlite_system.jtype_of(a.ld_value) AS json_type - ,a.ld_value - FROM value_and_types v - CROSS JOIN LATERAL ( - SELECT s.ld_value - FROM ldlite_system.jexplode(v.ld_value) AS s - WHERE NOT ldlite_system.jis_null(s.ld_value) - LIMIT 3 - ) a - WHERE v.json_type = 'array' - ), - all_values AS ( - SELECT - json_type - ,ld_value - ,FALSE AS is_array - FROM value_and_types - WHERE json_type <> 'array' - UNION - SELECT - json_type - ,ld_value - ,TRUE AS is_array - FROM array_values - WHERE NOT ldlite_system.jis_null(ld_value) - ) SELECT - (SELECT STRING_AGG(DISTINCT json_type, '|') FROM all_values) AS json_type - ,(SELECT BOOL_AND(is_array) FROM all_values) AS is_array - ,NOT EXISTS - ( - SELECT 1 FROM all_values - WHERE json_type = 'string' AND NOT ldlite_system.jis_uuid(ld_value) - ) AS is_uuid - ,NOT EXISTS - ( - SELECT 1 FROM all_values - WHERE json_type = 'string' AND NOT ldlite_system.jis_datetime(ld_value) - ) AS is_datetime - ,EXISTS + BOOL_AND(json_type = 'array') AS only_array + ,BOOL_OR(json_type = 'array') AS some_array + ,BOOL_AND(json_type = 'object') AS only_object + ,BOOL_OR(json_type = 'object') AS some_object +FROM +( + SELECT jsonb_typeof(t.{json_col}->$1) AS json_type + FROM {table} t +) j +WHERE json_type <> 'null' +""", + ) + .format( + table=source_table, + json_col=self.identifier, + ) + .as_string(), + (prop,), + ) + (only_array, some_array, only_object, some_object) = cast( + "tuple[bool, bool, bool, bool]", + cur.fetchone(), + ) + + if (some_array and not only_array) or (some_object and not only_object): + metadata.append(MixedMeta(prop)) + ctx.scan_progress.update(3) + continue + + if only_object: + metadata.append(ObjectMeta(prop)) + ctx.scan_progress.total += 1 + ctx.scan_progress.update(3) + continue + + if only_array: + ctx.scan_progress.update(1) + cur.execute( + sql.SQL( + """ +SELECT + -- Technically arrays could be nested but I haven't seen any + BOOL_AND(json_type = 'object') AS only_object + ,BOOL_OR(json_type = 'object') AS some_object +FROM +( + SELECT a.json_type + FROM {table} t + CROSS JOIN LATERAL ( - SELECT 1 FROM all_values - WHERE json_type = 'number' AND ldlite_system.jis_float(ld_value) - ) AS is_float - ,EXISTS + SELECT jsonb_typeof(ld_value) AS json_type + FROM jsonb_array_elements(t.{json_col}->$1) a(ld_value) + WHERE jsonb_typeof(t.{json_col}->$1) = 'array' + ) a +) j +WHERE json_type <> 'null' +""", + ) + .format( + table=source_table, + json_col=self.identifier, + ) + .as_string(), + (prop,), + ) + (inner_only_object, inner_some_object) = cast( + "tuple[bool, bool]", + cur.fetchone(), + ) + + if inner_some_object and not inner_only_object: + metadata.append(MixedArrayMeta(prop)) + ctx.scan_progress.update(2) + continue + + if inner_only_object: + metadata.append(ObjectArrayMeta(prop)) + ctx.scan_progress.total += 1 + ctx.scan_progress.update(2) + continue + + ctx.scan_progress.update(1) + typed_from_sql = """ +FROM {table} t +CROSS JOIN LATERAL +( + SELECT * + FROM jsonb_array_elements(t.{json_col}->$1) a(ld_value) + WHERE jsonb_typeof(t.{json_col}->$1) = 'array' + LIMIT 3 +) j""" + else: + ctx.scan_progress.update(2) + typed_from_sql = """ +FROM (SELECT t.{json_col}->$1 AS ld_value FROM {table} t) j +""" + with ctx.conn.cursor() as cur: + cur.execute( + sql.SQL( + """ +SELECT + MIN(json_type) AS json_type + ,MAX(json_type) AS other_json_type + ,BOOL_AND(CASE WHEN json_type = 'string' THEN (ld_value)::text LIKE '"________-____-____-____-____________"' ELSE FALSE END) AS is_uuid + ,BOOL_AND(CASE WHEN json_type = 'string' THEN (ld_value)::text LIKE '"____-__-__T__:__:__.___%"' ELSE FALSE END) AS is_datetime + ,BOOL_OR(CASE WHEN json_type = 'number' THEN (ld_value)::numeric % 1 <> 0 ELSE FALSE END) AS is_float + ,BOOL_OR(CASE WHEN json_type = 'number' THEN (ld_value)::numeric > 2147483647 ELSE FALSE END) AS is_bigint +FROM +( + SELECT + ld_value + ,jsonb_typeof(ld_value) json_type """ # noqa: E501 + + typed_from_sql + + """ + WHERE ld_value IS NOT NULL +) i +WHERE + ld_value IS NOT NULL AND + json_type <> 'null' AND ( - SELECT 1 FROM all_values - WHERE json_type = 'number' AND ldlite_system.jis_bigint(ld_value) - ) AS is_bigint + json_type <> 'string' OR + (json_type = 'string' AND ld_value::text NOT IN ('"null"', '""')) + ) """, ) .format( table=source_table, json_col=self.identifier, - sample=sql.Literal(min(100, floor((100000 / total) * 100))), ) .as_string(), (prop,), @@ -256,21 +311,22 @@ def unnest( if (row := cur.fetchone()) is not None and all( c is not None for c in row ): - meta = Metadata(prop, *row) - create_columns.append( - meta.select_column(self.identifier, self.add(meta)), + metadata.append( + TypedArrayMeta(prop, *row) + if only_array + else TypedMeta(prop, *row), ) - if meta.is_object: - ctx.scan_progress.total += 1 - ctx.scan_progress.refresh() - ctx.scan_progress.update(1) + create_columns.extend( + [meta.select_column(self.identifier, self.add(meta)) for meta in metadata], + ) + with ctx.conn.cursor() as cur: cur.execute( sql.SQL( """ -CREATE TEMP TABLE {dest_table} ON COMMIT DROP AS +CREATE TEMP TABLE {dest_table} AS """ + source_cte + """ @@ -309,19 +365,15 @@ def __init__( name: str, path: str, parent: ExpansionNode | None, - meta: Metadata, + meta: ArrayMeta, values: list[str] | None = None, ): super().__init__(name, path, parent, values) - self.meta = Metadata( - None, - meta.json_type, - False, - meta.is_uuid, - meta.is_datetime, - meta.is_float, - meta.is_bigint, - ) + self.meta = meta.unwrap() + + @property + def is_object(self) -> bool: + return isinstance(self.meta, ObjectMeta) def explode( self, @@ -338,7 +390,7 @@ def explode( ), *[sql.Identifier(v) for v in self.carryover], sql.SQL( - "(ROW_NUMBER() OVER (PARTITION BY s.__id))::smallint AS {id_alias}", + """a."ordinality"::smallint AS {id_alias}""", ).format( id_alias=sql.Identifier(o_col), ), @@ -351,7 +403,7 @@ def explode( cur.execute( sql.SQL( """ -CREATE TEMP TABLE {dest_table} ON COMMIT DROP AS +CREATE TEMP TABLE {dest_table} AS """ + source_cte + """ @@ -359,15 +411,15 @@ def explode( {cols} FROM ld_source s - ,ldlite_system.jexplode({json_col}) a -WHERE NOT ldlite_system.jis_null({json_col}) + ,jsonb_array_elements(s.{json_col}) WITH ORDINALITY a(ld_value, "ordinality") +WHERE jsonb_typeof(s.{json_col}) = 'array' """, ) .format( source_table=source_table, dest_table=dest_table, cols=sql.SQL("\n ,").join(create_columns), - json_col=sql.Identifier("s", self.name), + json_col=sql.Identifier(self.name), ) .as_string(), ) diff --git a/src/ldlite/database/_postgres.py b/src/ldlite/database/_postgres.py index 9c7dd2a..88cbc42 100644 --- a/src/ldlite/database/_postgres.py +++ b/src/ldlite/database/_postgres.py @@ -1,6 +1,9 @@ -from collections.abc import Iterator +from __future__ import annotations + +from contextlib import contextmanager from datetime import datetime, timezone from itertools import count +from typing import TYPE_CHECKING import psycopg from psycopg import sql @@ -8,6 +11,9 @@ from ._prefix import Prefix from ._typed_database import TypedDatabase +if TYPE_CHECKING: + from collections.abc import Iterator + class PostgresDatabase(TypedDatabase[psycopg.Connection]): def __init__(self, dsn: str): @@ -15,9 +21,10 @@ def __init__(self, dsn: str): # RawCursor lets us use $1, $2, etc to use the # same sql between duckdb and postgres super().__init__( - lambda: psycopg.connect( + lambda transact: psycopg.connect( dsn, cursor_factory=psycopg.RawCursor, + autocommit=not transact, ), ) except psycopg.errors.UniqueViolation: @@ -30,81 +37,6 @@ def __init__(self, dsn: str): if str(e) != "tuple concurrently updated": raise - @staticmethod - def _setup_jfuncs(conn: psycopg.Connection) -> None: - with conn.cursor() as cur: - cur.execute( - r""" -CREATE OR REPLACE FUNCTION ldlite_system.jtype_of(j JSONB) RETURNS TEXT AS $$ -SELECT jsonb_typeof(j); -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION ldlite_system.jobject_keys(j JSONB) RETURNS TABLE (ld_key TEXT) AS $$ -SELECT jsonb_object_keys(j); -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_uuid(j JSONB) RETURNS BOOLEAN AS $$ -SELECT j::text ~* '^"[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}"$'; -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE -STRICT; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_datetime(j JSONB) RETURNS BOOLEAN AS $$ -SELECT j::text ~ '^"\d{4}-[01]\d-[0123]\dT[012]\d:[012345]\d:[012345]\d\.\d{3}(\+\d{2}:\d{2})?"$' -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE -STRICT; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_float(j JSONB) RETURNS BOOLEAN AS $$ -SELECT SCALE((j)::numeric) > 0 -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE -STRICT; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_bigint(j JSONB) RETURNS BOOLEAN AS $$ -SELECT (j)::numeric > 2147483647 -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE -STRICT; - -CREATE OR REPLACE FUNCTION ldlite_system.jis_null(j JSONB) RETURNS BOOLEAN AS $$ -SELECT j IS NULL OR j = 'null'::jsonb OR j #>> '{}' IN ('NULL', 'null', '', '{}', '[]') -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION ldlite_system.jexplode(j JSONB) RETURNS TABLE (ld_value JSONB) AS $$ -SELECT * FROM jsonb_array_elements(j); -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE; - - -CREATE OR REPLACE FUNCTION ldlite_system.jself_string(j JSONB) RETURNS TEXT AS $$ -SELECT j #>> '{}' -$$ -LANGUAGE sql -IMMUTABLE -PARALLEL SAFE; -""", # noqa: E501 - ) - @property def _default_schema(self) -> str: return "public" @@ -115,6 +47,11 @@ def _create_raw_table_sql(self) -> sql.SQL: "CREATE TABLE IF NOT EXISTS {table} (__id integer, jsonb jsonb);", ) + @contextmanager + def _begin(self, conn: psycopg.Connection) -> Iterator[None]: + with conn.transaction(): + yield + def ingest_records( self, prefix: str, @@ -123,7 +60,7 @@ def ingest_records( pfx = Prefix(prefix) download_started = datetime.now(timezone.utc) pkey = count(1) - with self._conn_factory() as conn: + with self._conn_factory(True) as conn: self._prepare_raw_table(conn, pfx) with ( diff --git a/src/ldlite/database/_typed_database.py b/src/ldlite/database/_typed_database.py index 742c966..6560c1b 100644 --- a/src/ldlite/database/_typed_database.py +++ b/src/ldlite/database/_typed_database.py @@ -2,7 +2,7 @@ from __future__ import annotations from abc import abstractmethod -from contextlib import closing +from contextlib import closing, contextmanager from datetime import datetime, timezone from typing import TYPE_CHECKING, Any, Generic, NoReturn, TypeVar, cast from uuid import uuid4 @@ -17,7 +17,7 @@ from ._prefix import Prefix if TYPE_CHECKING: - from collections.abc import Callable, Sequence + from collections.abc import Callable, Iterator, Sequence from typing import NoReturn import duckdb @@ -27,9 +27,9 @@ class TypedDatabase(Database, Generic[DB]): - def __init__(self, conn_factory: Callable[[], DB]): + def __init__(self, conn_factory: Callable[[bool], DB]): self._conn_factory = conn_factory - with closing(self._conn_factory()) as conn: + with closing(self._conn_factory(True)) as conn: with conn.cursor() as cur: cur.execute('CREATE SCHEMA IF NOT EXISTS "ldlite_system";') cur.execute(""" @@ -52,23 +52,22 @@ def __init__(self, conn_factory: Callable[[], DB]): ,"index_time" INTERVAL -- 12 );""") - self._setup_jfuncs(conn) conn.commit() - @staticmethod - @abstractmethod - def _setup_jfuncs(conn: DB) -> None: ... - @property @abstractmethod def _default_schema(self) -> str: ... + @contextmanager + def _begin(self, conn: DB) -> Iterator[None]: # noqa: ARG002 + yield + def drop_prefix( self, prefix: str, ) -> None: pfx = Prefix(prefix) - with closing(self._conn_factory()) as conn: + with closing(self._conn_factory(True)) as conn: self._drop_extracted_tables(conn, pfx) self._drop_raw_table(conn, pfx) conn.execute( @@ -84,7 +83,7 @@ def drop_raw_table( self, prefix: str, ) -> None: - with closing(self._conn_factory()) as conn: + with closing(self._conn_factory(True)) as conn: self._drop_raw_table(conn, Prefix(prefix)) conn.commit() @@ -104,7 +103,7 @@ def drop_extracted_tables( self, prefix: str, ) -> None: - with closing(self._conn_factory()) as conn: + with closing(self._conn_factory(True)) as conn: self._drop_extracted_tables(conn, Prefix(prefix)) conn.commit() @@ -206,17 +205,22 @@ def expand_prefix( ) -> list[str]: pfx = Prefix(prefix) transform_started = datetime.now(timezone.utc) - with closing(self._conn_factory()) as conn: - self._drop_extracted_tables(conn, pfx) - if json_depth < 1: + if json_depth < 1: + with closing(self._conn_factory(True)) as conn: + self._drop_extracted_tables(conn, pfx) + if not keep_raw: + self._drop_raw_table(conn, pfx) + self._transform_complete(conn, pfx, 0, transform_started) + conn.commit() return [] + with closing(self._conn_factory(False)) as conn: with conn.cursor() as cur: cur.execute( sql.SQL( """ -CREATE TEMP TABLE {dest_table} ON COMMIT DROP AS +CREATE TEMP TABLE {dest_table} AS """ + self.source_table_cte_stmt(keep_source=keep_raw) + """ @@ -230,10 +234,7 @@ def expand_prefix( .as_string(), ) - if not keep_raw: - self._drop_raw_table(conn, pfx) - - created_tables = expand_nonmarc( + tables_to_create = expand_nonmarc( "jsonb", ["__id"], ExpandContext( @@ -251,45 +252,52 @@ def expand_prefix( ), ) - with conn.cursor() as cur: - cur.execute( - sql.SQL( - """ + with self._begin(conn): + self._drop_extracted_tables(conn, pfx) + if not keep_raw: + self._drop_raw_table(conn, pfx) + with conn.cursor() as cur: + for table in tables_to_create: + cur.execute(table[1].as_string()) + + with conn.cursor() as cur: + cur.execute( + sql.SQL( + """ CREATE TABLE {catalog_table} ( table_name text ) """, - ) - .format(catalog_table=pfx.catalog_table.id) - .as_string(), - ) - if len(created_tables) > 0: - cur.executemany( - sql.SQL("INSERT INTO {catalog_table} VALUES ($1)") - .format( - catalog_table=pfx.catalog_table.id, ) + .format(catalog_table=pfx.catalog_table.id) .as_string(), - [(pfx.catalog_table_row(t),) for t in created_tables], ) + total = 0 + if len(tables_to_create) > 0: + cur.executemany( + sql.SQL("INSERT INTO {catalog_table} VALUES ($1)") + .format( + catalog_table=pfx.catalog_table.id, + ) + .as_string(), + [(pfx.catalog_table_row(t[0]),) for t in tables_to_create], + ) - with conn.cursor() as cur: - cur.execute( - sql.SQL("SELECT COUNT(*) FROM {table}") - .format(table=pfx.output_table("").id) - .as_string(), - ) - total = cast("tuple[int]", cur.fetchone())[0] + cur.execute( + sql.SQL("SELECT COUNT(*) FROM {table}") + .format(table=pfx.output_table("").id) + .as_string(), + ) + total = cast("tuple[int]", cur.fetchone())[0] - self._transform_complete(conn, pfx, total, transform_started) - conn.commit() + self._transform_complete(conn, pfx, total, transform_started) - return created_tables + return [t[0] for t in tables_to_create] def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> None: pfx = Prefix(prefix) index_started = datetime.now(timezone.utc) - with closing(self._conn_factory()) as conn: + with closing(self._conn_factory(False)) as conn: with closing(conn.cursor()) as cur: cur.execute( """ @@ -351,7 +359,7 @@ def prepare_history( path: str, query: str | None, ) -> None: - with closing(self._conn_factory()) as conn, closing(conn.cursor()) as cur: + with closing(self._conn_factory(True)) as conn, closing(conn.cursor()) as cur: cur.execute( """ INSERT INTO "ldlite_system"."load_history_v1" diff --git a/tests/test_expansion.py b/tests/test_expansion.py index 9fcd6bc..094dfa4 100644 --- a/tests/test_expansion.py +++ b/tests/test_expansion.py @@ -220,7 +220,7 @@ def case_null(assertion: tuple[str, str | None, str | None]) -> ExpansionTC: "all_null": null, "nullable_integer": 7, "nullable_numeric": 5.5, - "nullable_uuid": null, + "nullable_uuid": "null", "nullable_bool": false, "nullable_object": { "id": 5 }, "nullable_array": null, @@ -661,7 +661,7 @@ def case_json_depth() -> ExpansionTC: ), Assertion( """ -SELECT COUNT(DISTINCT DATA_TYPE), ANY_VALUE(DATA_TYPE) +SELECT COUNT(DISTINCT DATA_TYPE), MIN(DATA_TYPE) FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME IN ( 'depth2_obj__depth3_obj__depth4_obj' diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index 2ae7d24..ac43355 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -27,7 +27,7 @@ class JsonTC: assertion_params: tuple[Any, ...] -def case_jobject_keys() -> JsonTC: +def case_jsonb_object_keys() -> JsonTC: return JsonTC( """ {assertion} @@ -35,7 +35,7 @@ def case_jobject_keys() -> JsonTC: FROM (SELECT 'k1' jkey UNION SELECT 'k2' jkey) as e FULL OUTER JOIN ( SELECT k.ld_key as jkey - FROM j, ldlite_system.jobject_keys(j.jc->'obj') k + FROM j, jsonb_object_keys(j.jc->'obj') k(ld_key) ) as a USING (jkey) WHERE e.jkey IS NULL or a.jkey IS NULL) as q;""", @@ -59,10 +59,10 @@ def case_jobject_keys() -> JsonTC: ("na", "null"), ], ) -def case_jtype_of(p: tuple[Any, ...]) -> JsonTC: +def case_jsonb_typeof(p: tuple[Any, ...]) -> JsonTC: return JsonTC( """ -SELECT ldlite_system.jtype_of(jc->$1){assertion} +SELECT jsonb_typeof(jc->$1){assertion} FROM j;""", p[:1], """ = $2""", @@ -77,17 +77,17 @@ def case_jtype_of(p: tuple[Any, ...]) -> JsonTC: ("arr_num", [1, 2, 3]), ], ) -def case_jexplode(p: tuple[Any, ...]) -> JsonTC: +def case_jsonb_array_elements(p: tuple[Any, ...]) -> JsonTC: return JsonTC( """ {assertion} ( - SELECT a.ld_value FROM j, ldlite_system.jexplode(j.jc->$1) a + SELECT a.ld_value FROM j, jsonb_array_elements(j.jc->$1) AS a(ld_value) EXCEPT SELECT value::{jtype} FROM unnest($2::text[]) AS expect(value) UNION ALL SELECT value::{jtype} FROM unnest($2::text[]) AS expect(value) - EXCEPT SELECT a.ld_value FROM j, ldlite_system.jexplode(j.jc->$1) a -) + EXCEPT SELECT a.ld_value FROM j, jsonb_array_elements(j.jc->$1) AS a(ld_value) +) act """, p, """SELECT COUNT(1) = 0 FROM""", @@ -95,107 +95,6 @@ def case_jexplode(p: tuple[Any, ...]) -> JsonTC: ) -@parametrize( - p=[ - ("str", False), - ("str_empty", False), - ("num", False), - ("na_str1", False), - ("na_str2", False), - ("uuid_nof", False), - ("uuid", True), - ], -) -def case_jis_uuid(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """ -SELECT {assertion}ldlite_system.jis_uuid(jc->$1) -FROM j;""", - p[:1], - "" if (p[1]) else """ NOT """, - (), - ) - - -@parametrize( - p=[ - ("na", True), - ("obj_empty", True), - ("arr_zero", True), - ("na_str1", True), - ("na_str2", True), - ], -) -def case_jis_null(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """SELECT ldlite_system.jis_null(jc->$1){assertion} FROM j;""", - p[:1], - """= $2""", - p[1:], - ) - - -@parametrize( - p=[ - ("str", False), - ("str_empty", False), - ("num", False), - ("na_str1", False), - ("na_str2", False), - ("uuid_nof", False), - ("uuid", False), - ("dt", True), - ], -) -def case_jis_datetime(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """ -SELECT {assertion}ldlite_system.jis_datetime(jc->$1) -FROM j;""", - p[:1], - "" if (p[1]) else """ NOT """, - (), - ) - - -@parametrize( - p=[ - ("num", False), - ("float", True), - ("bigfloat", True), - ("bigint", False), - ], -) -def case_jis_float(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """ -SELECT {assertion}ldlite_system.jis_float(jc->$1) -FROM j;""", - p[:1], - "" if (p[1]) else """ NOT """, - (), - ) - - -@parametrize( - p=[ - ("num", False), - ("float", False), - ("bigfloat", True), - ("bigint", True), - ], -) -def case_jis_bigint(p: tuple[Any, ...]) -> JsonTC: - return JsonTC( - """ -SELECT {assertion}ldlite_system.jis_bigint(jc->$1) -FROM j;""", - p[:1], - "" if (p[1]) else """ NOT """, - (), - ) - - def _assert(conn: "dbapi.DBAPIConnection", jtype: str, tc: JsonTC) -> None: with closing(conn.cursor()) as cur: query = tc.query.format(assertion="", jtype=jtype) @@ -226,27 +125,16 @@ def _arrange(conn: "dbapi.DBAPIConnection") -> None: INSERT INTO j VALUES ( '{ "str": "str_val", - "str_empty": "", "num": 12, "float": 16.3, "bigint": 2147483648, "bigfloat": 2147483648.1, "bool": true, - "uuid": "5b285d03-5490-1111-8888-52b2003b475c", - "uuid_nof": "5b285d03-5490-FFFF-0000-52b2003b475c", "obj": {"k1": "v1", "k2": "v2"}, - "obj_some": {"k1": "v1", "k2": null}, - "obj_empty": {}, - "arr_zero": [], "arr_str": ["s1", "s2", "s3"], - "arr_str_some": ["s1", "s2", null], "arr_obj": [{"k1": "v1"}, {"k2": "v2"}], - "arr_obj_some": [{"k1": "v1"}, null], "arr_num": [1, 2, 3], - "dt": "2022-04-21T18:47:33.581+00:00", - "na": null, - "na_str1": "null", - "na_str2": "NULL" + "na": null }')""", ) diff --git a/tests/test_query.py b/tests/test_query.py index 8993e7d..a488bbf 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -561,15 +561,13 @@ def case_id_generation() -> QueryTC: ], expected_values={ "prefix__t__sub_objects": ( - ["__id", "id", "sub_objects__o"], + ["id", "sub_objects__o"], [ ( - "1", "b096504a-3d54-4664-9bf5-1b872466fd66", "1", ), ( - "2", "b096504a-3d54-4664-9bf5-1b872466fd66", "2", ), From 07b83f6e28bb50cb3c400236ba8ef675f891c52e Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Fri, 27 Mar 2026 09:10:11 -0400 Subject: [PATCH 21/25] Reduce data duplication and temp tables during transform (#72) I've learned a lot working on this new implementation and many of the initial assumptions and design choices I made broke down at the scale of the Inventory table. In trying to get the inventory table transforming more and more code was bolted to just barely make it work. Any given transform was one bad postgres query plan away from exploding the server. Before releasing the next version I'd like to make sure it is well-behaved when run by other people and actually maintainable so I can follow up with quick bug fixes. The biggest issues with the existing design were: The Carcinisation of the Nodes, Metadata, and Path/Name calculations Having to constantly create and drop temporary tables in order to try to keep disk usage under control Having a single query to find the type of a column, the type of the values if that column was an array, and more specialized type information like whether it was a uuid This combines all the various control structures into the Node hierarchy. This hierarchy is used to generate paths and names of various columns as well as storing the type information. It continues to be responsible for generating the correct SQL to expand/infer the structure itself. Instead of incrementally building the result tables through a series of temporary tables this switches to inferring as much information as possible from the origin jsonb column. For arrays temp tables save time/computation because the jsonb_array_elements only needs to be called once during the expansion. The information expanded into the new Array temp table is kept to a minimum and only the final create table statement copies in the "carryover" columns. This tames the disk usage spikes and simplifies the transformation logic by removing all the intermediate drop tables. We're now using jsonb_each for finding the keys and their type in one query. Finding the type of array elements and more specific types are now separate steps if necessary. This has greatly reduced the amount of time spent inferring type information and also eliminates the accidentally and unpredictable query plan explosions. --- .github/workflows/test.yaml | 9 +- src/ldlite/database/_duckdb.py | 11 +- src/ldlite/database/_expansion/__init__.py | 241 ++++------ src/ldlite/database/_expansion/context.py | 52 --- src/ldlite/database/_expansion/fixed_nodes.py | 181 ++++++++ src/ldlite/database/_expansion/metadata.py | 141 ------ src/ldlite/database/_expansion/node.py | 33 ++ src/ldlite/database/_expansion/nodes.py | 435 ------------------ .../database/_expansion/recursive_nodes.py | 387 ++++++++++++++++ src/ldlite/database/_postgres.py | 27 +- src/ldlite/database/_prefix.py | 4 +- src/ldlite/database/_typed_database.py | 118 ++--- tests/test_expansion.py | 7 +- tests/test_json_operators.py | 4 +- 14 files changed, 754 insertions(+), 896 deletions(-) delete mode 100644 src/ldlite/database/_expansion/context.py create mode 100644 src/ldlite/database/_expansion/fixed_nodes.py delete mode 100644 src/ldlite/database/_expansion/metadata.py create mode 100644 src/ldlite/database/_expansion/node.py delete mode 100644 src/ldlite/database/_expansion/nodes.py create mode 100644 src/ldlite/database/_expansion/recursive_nodes.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 410cdf6..dbbe015 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -25,7 +25,8 @@ jobs: - run: pdm install -G:all --lockfile pylock.toml # test - - run: pdm run test -k 'not test_srs' + #- run: pdm run test -k 'not test_srs' + - run: pdm run test test-minimal-deps: runs-on: ubuntu-latest @@ -41,7 +42,8 @@ jobs: - run: pdm install -G:all --lockfile pylock.minimal.toml # test - - run: pdm run test -k 'not test_srs' + #- run: pdm run test -k 'not test_srs' + - run: pdm run test test-maximal-deps: runs-on: ubuntu-latest @@ -57,4 +59,5 @@ jobs: - run: pdm install -G:all --lockfile pylock.maximal.toml # test - - run: pdm run test -k 'not test_srs' + #- run: pdm run test -k 'not test_srs' + - run: pdm run test diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index de0324d..f4268ea 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -41,13 +41,13 @@ def __init__(self, db: duckdb.DuckDBPyConnection) -> None: END ; -CREATE OR REPLACE FUNCTION jsonb_object_keys(j) AS TABLE - SELECT je.key as ld_key, id as "ordinality" FROM json_each(j) je ORDER BY je.id -; - CREATE OR REPLACE FUNCTION jsonb_array_elements(j) AS TABLE ( SELECT value as ld_value, rowid + 1 AS "ordinality" FROM main.json_each(j) ); + +CREATE OR REPLACE FUNCTION jsonb_each(j) AS TABLE ( + SELECT key, value, rowid AS "ordinality" FROM main.json_each(j) +) """, ) @@ -86,9 +86,6 @@ def ingest_records( return total - def source_table_cte_stmt(self, keep_source: bool) -> str: # noqa: ARG002 - return "WITH ld_source AS (SELECT * FROM {source_table})" - # DuckDB has some strong opinions about cursors that are different than postgres # https://github.com/duckdb/duckdb/issues/11018 diff --git a/src/ldlite/database/_expansion/__init__.py b/src/ldlite/database/_expansion/__init__.py index 0d1fe41..bb33ded 100644 --- a/src/ldlite/database/_expansion/__init__.py +++ b/src/ldlite/database/_expansion/__init__.py @@ -3,165 +3,94 @@ from collections import deque from typing import TYPE_CHECKING -from psycopg import sql +if TYPE_CHECKING: + from collections.abc import Callable, Iterator + from typing import NoReturn + + from psycopg import sql + from tqdm import tqdm + + +from .node import Conn, Node +from .recursive_nodes import ArrayNode, ObjectNode, RootNode + + +def _non_srs_statements( + conn: Conn, + source_table: sql.Identifier, + output_table: Callable[[str | None], tuple[str, sql.Identifier]], + json_depth: int, + scan_progress: tqdm[NoReturn], +) -> Iterator[tuple[str, sql.Composed]]: + # Here be dragons! The nodes have inner state manipulations + # that violate the space/time continuum: + # * o.load_columns + # * a.make_temp + # * t.specify_type + # These all are expected to be called before generating the sql + # as they load/prepare database information. + # Because building up to the transformation statements takes a long time + # we're doing all that work up front to keep the time that + # a transaction is opened to a minimum (which is a leaky abstraction). + scan_progress.total = scan_progress.total if scan_progress.total is not None else 1 + + root = RootNode(source_table, output_table) + onodes: deque[ObjectNode] = deque([root]) + while onodes: + o = onodes.popleft() + + if o.depth >= json_depth: + o.make_jsonb() + scan_progress.update(1) + continue -from .nodes import ArrayNode, ObjectNode + o.load_columns(conn) + scan_progress.total += len(o.direct(Node)) + scan_progress.update(1) -if TYPE_CHECKING: - from .context import ExpandContext + onodes.extend(o.direct(ObjectNode)) + anodes = deque(o.direct(ArrayNode)) + while anodes: + a = anodes.popleft() + + if a.depth >= json_depth: + a.make_jsonb() + scan_progress.update(1) + continue + + if n := a.make_temp(conn): + if isinstance(n, ObjectNode): + onodes.append(n) + if isinstance(n, ArrayNode): + anodes.append(n) + scan_progress.total += 1 + else: + a.unparent() + scan_progress.update(1) -def expand_nonmarc( - root_name: str, - root_values: list[str], - ctx: ExpandContext, + for t in root.typed_nodes(): + t.specify_type(conn) + scan_progress.update(1) + + yield root.create_statement + for a in root.descendents(ArrayNode): + yield a.create_statement + + +def non_srs_statements( + conn: Conn, + source_table: sql.Identifier, + output_table: Callable[[str | None], tuple[str, sql.Identifier]], + json_depth: int, + scan_progress: tqdm[NoReturn], ) -> list[tuple[str, sql.Composed]]: - (_, tables_to_create) = _expand_nonmarc( - ObjectNode(root_name, "", None, root_values), - 0, - ctx, + return list( + _non_srs_statements( + conn, + source_table, + output_table, + json_depth, + scan_progress, + ), ) - return tables_to_create - - -def _expand_nonmarc( # noqa: PLR0915 - root: ObjectNode, - count: int, - ctx: ExpandContext, -) -> tuple[int, list[tuple[str, sql.Composed]]]: - ctx.scan_progress.total = (ctx.scan_progress.total or 0) + 1 - ctx.scan_progress.refresh() - ctx.transform_progress.total = (ctx.transform_progress.total or 0) + 1 - ctx.transform_progress.refresh() - initial_count = count - ctx.preprocess(ctx.conn, ctx.source_table, [root.identifier]) - has_rows = root.unnest( - ctx, - ctx.source_table, - ctx.get_transform_table(count), - ctx.source_cte(False), - ) - ctx.transform_progress.update(1) - if not has_rows: - return (0, []) - - with ctx.conn.cursor() as cur: - cur.execute( - sql.SQL("DROP TABLE {previous_table}") - .format(previous_table=ctx.source_table) - .as_string(), - ) - - expand_children_of = deque([root]) - while expand_children_of: - on = expand_children_of.popleft() - if ctx.transform_progress: - ctx.transform_progress.total += len(on.object_children) - ctx.transform_progress.refresh() - for c in on.object_children: - if len(c.parents) >= ctx.json_depth: - if c.parent is not None: - c.parent.values.append(c.name) - continue - ctx.preprocess(ctx.conn, ctx.get_transform_table(count), [c.identifier]) - c.unnest( - ctx, - ctx.get_transform_table(count), - ctx.get_transform_table(count + 1), - ctx.source_cte(False), - ) - with ctx.conn.cursor() as cur: - cur.execute( - sql.SQL("DROP TABLE {previous_table}") - .format(previous_table=ctx.get_transform_table(count)) - .as_string(), - ) - expand_children_of.append(c) - count += 1 - ctx.transform_progress.update(1) - - tables_to_create = [] - - new_source_table = ctx.get_transform_table(count) - arrays = root.descendents_oftype(ArrayNode) - ctx.transform_progress.total += len(arrays) - ctx.transform_progress.refresh() - ctx.preprocess(ctx.conn, new_source_table, [a.identifier for a in arrays]) - for an in arrays: - if len(an.parents) >= ctx.json_depth: - continue - values = an.explode( - ctx.conn, - new_source_table, - ctx.get_transform_table(count + 1), - ctx.source_cte(True), - ) - count += 1 - ctx.transform_progress.update(1) - - if an.is_object: - (sub_index, array_tables) = _expand_nonmarc( - ObjectNode( - an.name, - an.name, - None, - values, - ), - count + 1, - ctx.array_context( - ctx.get_transform_table(count), - ctx.json_depth - len(an.parents), - ), - ) - count += sub_index - tables_to_create.extend(array_tables) - else: - with ctx.conn.cursor() as cur: - (tname, tid) = ctx.get_output_table(an.name) - tables_to_create.append( - ( - tname, - sql.SQL( - """ -CREATE TABLE {dest_table} AS -""" - + ctx.source_cte(False) - + """ -SELECT {cols} FROM ld_source -""", - ).format( - dest_table=tid, - source_table=ctx.get_transform_table(count), - cols=sql.SQL("\n ,").join( - [sql.Identifier(v) for v in [*values, an.name]], - ), - ), - ), - ) - - stamped_values = [ - sql.Identifier(v) for n in root.descendents if n not in arrays for v in n.values - ] - - with ctx.conn.cursor() as cur: - (tname, tid) = ctx.get_output_table(root.path) - tables_to_create.append( - ( - tname, - sql.SQL( - """ -CREATE TABLE {dest_table} AS -""" - + ctx.source_cte(False) - + """ -SELECT {cols} FROM ld_source -""", - ).format( - dest_table=tid, - source_table=new_source_table, - cols=sql.SQL("\n ,").join(stamped_values), - ), - ), - ) - - return (count + 1 - initial_count, tables_to_create) diff --git a/src/ldlite/database/_expansion/context.py b/src/ldlite/database/_expansion/context.py deleted file mode 100644 index 7b9e29a..0000000 --- a/src/ldlite/database/_expansion/context.py +++ /dev/null @@ -1,52 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass -from typing import TYPE_CHECKING, NoReturn - -if TYPE_CHECKING: - from collections.abc import Callable - - import duckdb - import psycopg - from psycopg import sql - from tqdm import tqdm - - -@dataclass -class ExpandContext: - conn: duckdb.DuckDBPyConnection | psycopg.Connection - source_table: sql.Identifier - json_depth: int - get_transform_table: Callable[[int], sql.Identifier] - get_output_table: Callable[[str], tuple[str, sql.Identifier]] - # This is necessary for Analyzing the table in pg before querying it - # I don't love how this is implemented - preprocess: Callable[ - [ - duckdb.DuckDBPyConnection | psycopg.Connection, - sql.Identifier, - list[sql.Identifier], - ], - None, - ] - # source_cte will go away when DuckDB implements CTAS RETURNING - source_cte: Callable[[bool], str] - scan_progress: tqdm[NoReturn] - transform_progress: tqdm[NoReturn] - - def array_context( - self, - new_source_table: sql.Identifier, - new_json_depth: int, - ) -> ExpandContext: - return ExpandContext( - self.conn, - new_source_table, - new_json_depth, - self.get_transform_table, - self.get_output_table, - self.preprocess, - self.source_cte, - self.scan_progress, - self.transform_progress, - ) diff --git a/src/ldlite/database/_expansion/fixed_nodes.py b/src/ldlite/database/_expansion/fixed_nodes.py new file mode 100644 index 0000000..3dbb505 --- /dev/null +++ b/src/ldlite/database/_expansion/fixed_nodes.py @@ -0,0 +1,181 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Literal + +from psycopg import sql + +if TYPE_CHECKING: + from typing import TypeAlias + + +from .node import Conn, Node + +JsonType: TypeAlias = Literal["array", "object", "string", "number", "boolean", "jsonb"] + + +class FixedValueNode(Node): + def __init__( + self, + source: sql.Identifier, + prop: str | None, + path: sql.Composable, + prefix: str, + ): + super().__init__(source, prop) + + self.path = path + self.prefix = prefix + + @property + def alias(self) -> str: + if len(self.prefix) == 0: + return self.snake_prop or "" + return self.prefix + ( + ("__" + self.snake_prop) if self.snake_prop is not None else "" + ) + + @property + def stmt(self) -> sql.Composable: + # this should be abstract but Python can't use ABCs as a generic + return sql.SQL("") + + +class TypedNode(FixedValueNode): + def __init__( + self, + source: sql.Identifier, + prop: str | None, + path: sql.Composable, + prefix: str, + json_types: tuple[JsonType, JsonType], + ): + super().__init__(source, prop, path, prefix) + + self.is_mixed = json_types[0] != json_types[1] + self.json_type: JsonType = "string" if self.is_mixed else json_types[0] + self.is_uuid = False + self.is_datetime = False + self.is_float = False + self.is_bigint = False + + @property + def json_string(self) -> sql.Composable: + if self.prop is None: + str_extract = ( + sql.SQL("""TRIM(BOTH '"' FROM (""") + self.path + sql.SQL(")::text)") + ) + else: + str_extract = self.path + sql.SQL("->>") + sql.Literal(self.prop) + + return sql.SQL("NULLIF(NULLIF(") + str_extract + sql.SQL(", ''), 'null')") + + @property + def stmt(self) -> sql.Composable: + type_extract: sql.Composable + if self.json_type == "jsonb": + type_extract = self.path + elif self.json_type == "number" and self.is_float: + type_extract = self.json_string + sql.SQL("::numeric") + elif self.json_type == "number" and self.is_bigint: + type_extract = self.json_string + sql.SQL("::bigint") + elif self.json_type == "number": + type_extract = self.json_string + sql.SQL("::integer") + elif self.json_type == "boolean": + type_extract = self.json_string + sql.SQL("::bool") + elif self.json_type == "string" and self.is_uuid: + type_extract = self.json_string + sql.SQL("::uuid") + elif self.json_type == "string" and self.is_datetime: + type_extract = self.json_string + sql.SQL("::timestamptz") + else: + type_extract = self.json_string + + return type_extract + sql.SQL(" AS ") + sql.Identifier(self.alias) + + def specify_type(self, conn: Conn) -> None: + if self.is_mixed or self.json_type not in ["string", "number"]: + return + + cte = ( + sql.SQL(""" +WITH string_values AS MATERIALIZED ( + SELECT """) + + self.json_string + + sql.SQL(""" AS string_value + FROM {source} +)""").format(source=self.source) + ) + + if self.json_type == "string": + with conn.cursor() as cur: + specify = cte + sql.SQL(""" +SELECT + NOT EXISTS( + SELECT 1 FROM string_values + WHERE + string_value IS NOT NULL AND + string_value NOT LIKE '________-____-____-____-____________' + ) AS is_uuid + ,NOT EXISTS( + SELECT 1 FROM string_values + WHERE + string_value IS NOT NULL AND + ( + string_value NOT LIKE '____-__-__T__:__:__.___' AND + string_value NOT LIKE '____-__-__T__:__:__.___+__:__' + ) + ) AS is_uuid;""") + + cur.execute(specify.as_string()) + if row := cur.fetchone(): + (self.is_uuid, self.is_datetime) = row + + if self.json_type == "number": + with conn.cursor() as cur: + specify = cte + sql.SQL(""" +SELECT + EXISTS( + SELECT 1 FROM string_values + WHERE + string_value IS NOT NULL AND + string_value::numeric % 1 <> 0 + ) AS is_float + ,EXISTS( + SELECT 1 FROM string_values + WHERE + string_value IS NOT NULL AND + string_value::numeric > 2147483647 + ) AS is_bigint;""") + + cur.execute(specify.as_string()) + if row := cur.fetchone(): + (self.is_float, self.is_bigint) = row + + +class OrdinalNode(FixedValueNode): + def __init__( + self, + source: sql.Identifier, + path: sql.Composable, + prefix: str, + ): + super().__init__(source, None, path, prefix) + + @property + def alias(self) -> str: + return self.prefix + "__o" + + @property + def stmt(self) -> sql.Composable: + return sql.Identifier("a", "__o") + sql.SQL(" AS {alias}").format( + alias=sql.Identifier(self.alias), + ) + + +class JsonbNode(TypedNode): + def __init__( + self, + source: sql.Identifier, + path: sql.Composable, + prefix: str, + ): + super().__init__(source, None, path, prefix, ("jsonb", "jsonb")) diff --git a/src/ldlite/database/_expansion/metadata.py b/src/ldlite/database/_expansion/metadata.py deleted file mode 100644 index 7fbc2ee..0000000 --- a/src/ldlite/database/_expansion/metadata.py +++ /dev/null @@ -1,141 +0,0 @@ -from __future__ import annotations - -from abc import ABC, abstractmethod -from typing import Literal - -from psycopg import sql - - -class Metadata(ABC): - def __init__(self, prop: str | None): - self.prop = prop - - @property - def snake(self) -> str: - if self.prop is None: - # this doesn't really come up in practice - return "$" - - snake = "".join("_" + c.lower() if c.isupper() else c for c in self.prop) - - # there's also sorts of weird edge cases here that don't come up in practice - if (naked := self.prop.lstrip("_")) and len(naked) > 0 and naked[0].isupper(): - snake = snake.removeprefix("_") - - return snake - - @property - @abstractmethod - def select_stmt(self) -> str: ... - - def select_column( - self, - json_col: sql.Identifier, - alias: str, - ) -> sql.Composed: - return sql.SQL(self.select_stmt + " AS {alias}").format( - json_col=json_col, - prop=self.prop, - alias=sql.Identifier(alias), - ) - - -class ObjectMeta(Metadata): - @property - def select_stmt(self) -> str: - return "{json_col}" if self.prop is None else "{json_col}->{prop}" - - -class ArrayMeta(Metadata): - @property - def select_stmt(self) -> str: - return "{json_col}" if self.prop is None else "{json_col}->{prop}" - - @abstractmethod - def unwrap(self) -> ObjectMeta | TypedMeta: ... - - -class TypedMeta(Metadata): - def __init__( # noqa: PLR0913 - self, - prop: str | None, - json_type: Literal["string", "number", "boolean"], - other_json_type: Literal["string", "number", "boolean"], - is_uuid: bool, - is_datetime: bool, - is_float: bool, - is_bigint: bool, - ): - super().__init__(prop) - - mixed_type = json_type != other_json_type - self.json_type: Literal["string", "number", "boolean"] = ( - json_type if not mixed_type else "string" - ) - self.is_uuid = is_uuid and not mixed_type - self.is_datetime = is_datetime and not mixed_type - self.is_float = is_float and not mixed_type - self.is_bigint = is_bigint and not mixed_type - - @property - def select_stmt(self) -> str: # noqa: PLR0911 - str_extract = ( - "{json_col}->>{prop}" - if self.prop is not None - else """TRIM(BOTH '"' FROM ({json_col})::text)""" - ) - str_extract = f"NULLIF(NULLIF({str_extract}, ''), 'null')" - - if self.json_type == "number" and self.is_float: - return f"{str_extract}::numeric" - if self.json_type == "number" and self.is_bigint: - return f"{str_extract}::bigint" - if self.json_type == "number": - return f"{str_extract}::integer" - if self.json_type == "boolean": - return f"{str_extract}::bool" - if self.json_type == "string" and self.is_uuid: - return f"{str_extract}::uuid" - if self.json_type == "string" and self.is_datetime: - return f"{str_extract}::timestamptz" - - return str_extract - - -class MixedMeta(TypedMeta): - def __init__( - self, - prop: str | None, - ): - super().__init__(prop, "string", "string", False, False, False, False) - - -class ObjectArrayMeta(ObjectMeta, ArrayMeta): - def unwrap(self) -> ObjectMeta: - return ObjectMeta(None) - - -class MixedArrayMeta(MixedMeta, ArrayMeta): - @property - def select_stmt(self) -> str: - return "{json_col}" if self.prop is None else "{json_col}->{prop}" - - def unwrap(self) -> MixedMeta: - return MixedMeta(None) - - -class TypedArrayMeta(TypedMeta, ArrayMeta): - @property - def select_stmt(self) -> str: - return "{json_col}" if self.prop is None else "{json_col}->{prop}" - - def unwrap(self) -> TypedMeta: - return TypedMeta( - None, - self.json_type, - self.json_type, - self.is_uuid, - self.is_datetime, - self.is_float, - self.is_bigint, - ) diff --git a/src/ldlite/database/_expansion/node.py b/src/ldlite/database/_expansion/node.py new file mode 100644 index 0000000..eb7d6be --- /dev/null +++ b/src/ldlite/database/_expansion/node.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import duckdb +import psycopg + +if TYPE_CHECKING: + from typing import TypeAlias + + from psycopg import sql + +Conn: TypeAlias = duckdb.DuckDBPyConnection | psycopg.Connection + + +class Node: + def __init__(self, source: sql.Identifier, prop: str | None): + self.source = source + self.prop = prop + self.snake_prop: str | None = None + + if self.prop is not None: + self.snake_prop = "".join( + "_" + c.lower() if c.isupper() else c for c in self.prop + ) + + # there's also sorts of weird edge cases here that don't come up in practice + if ( + (naked := self.prop.lstrip("_")) + and len(naked) > 0 + and naked[0].isupper() + ): + self.snake_prop = self.snake_prop.removeprefix("_") diff --git a/src/ldlite/database/_expansion/nodes.py b/src/ldlite/database/_expansion/nodes.py deleted file mode 100644 index 32626b5..0000000 --- a/src/ldlite/database/_expansion/nodes.py +++ /dev/null @@ -1,435 +0,0 @@ -from __future__ import annotations - -from collections import deque -from typing import TYPE_CHECKING, TypeVar, cast - -from psycopg import sql - -if TYPE_CHECKING: - from collections.abc import Iterator - - import duckdb - import psycopg - - from .context import ExpandContext - -from .metadata import ( - ArrayMeta, - Metadata, - MixedArrayMeta, - MixedMeta, - ObjectArrayMeta, - ObjectMeta, - TypedArrayMeta, - TypedMeta, -) - -TNode = TypeVar("TNode", bound="ExpansionNode") - - -class ExpansionNode: - def __init__( - self, - name: str, - path: str, - parent: ExpansionNode | None, - values: list[str] | None = None, - ): - self.name = name - self.path = path - self.identifier = sql.Identifier(name) - self.parent = parent - self.values: list[str] = values or [] - self.children: list[ExpansionNode] = [] - - def add(self, meta: Metadata) -> str: - snake = meta.snake - prefixed_name = self.prefix + snake - - if isinstance(meta, ArrayMeta): - self.children.append(ArrayNode(prefixed_name, snake, self, meta)) - elif isinstance(meta, ObjectMeta): - self.children.append(ObjectNode(prefixed_name, snake, self)) - else: - prefixed_name = self.prefix + snake - self.values.append(prefixed_name) - - return prefixed_name - - def _parents(self) -> Iterator[ExpansionNode]: - n = self - while n.parent is not None: - yield n.parent - n = n.parent - - @property - def parents(self) -> list[ExpansionNode]: - return list(self._parents()) - - @property - def prefix(self) -> str: - if len(self.parents) == 0 and len(self.path) == 0: - return "" - - return ( - "__".join( - [*[p.path for p in self.parents if len(p.path) != 0], self.path], - ) - + "__" - ) - - @property - def root(self) -> ExpansionNode: - if self.parent is None: - return self - - root = [p for p in self.parents if p.parent is None] - return root[0] - - def _descendents(self, cls: type[TNode]) -> Iterator[TNode]: - to_visit = deque([self]) - while to_visit: - n = to_visit.pop() - if isinstance(n, cls): - yield n - - to_visit.extend(n.children) - - @property - def descendents(self) -> list[ExpansionNode]: - return list(self._descendents(ExpansionNode)) - - def descendents_oftype(self, cls: type[TNode]) -> list[TNode]: - return list(self._descendents(cls)) - - def __str__(self) -> str: - return "->".join([n.name for n in reversed([self, *self.parents])]) - - -class ObjectNode(ExpansionNode): - def __init__( - self, - name: str, - path: str, - parent: ExpansionNode | None, - values: list[str] | None = None, - ): - super().__init__(name, path, parent, values) - self.unnested = False - - def _object_children(self) -> Iterator[ObjectNode]: - for c in self.children: - if isinstance(c, ObjectNode): - yield c - - @property - def object_children(self) -> list[ObjectNode]: - return list(self._object_children()) - - def unnest( - self, - ctx: ExpandContext, - source_table: sql.Identifier, - dest_table: sql.Identifier, - source_cte: str, - ) -> bool: - self.unnested = True - create_columns: list[sql.Composable] = [ - sql.Identifier(v) for v in self.carryover - ] - - with ctx.conn.cursor() as cur: - cur.execute( - sql.SQL("SELECT 1 FROM {table} LIMIT 1;") - .format(table=source_table) - .as_string(), - ) - if not cur.fetchone(): - return False - - with ctx.conn.cursor() as cur: - cur.execute( - sql.SQL( - """ -SELECT k.ld_key -FROM - {source_table} t - ,jsonb_object_keys(t.{json_col}) WITH ORDINALITY k(ld_key, "ordinality") -WHERE t.{json_col} IS NOT NULL AND jsonb_typeof(t.{json_col}) = 'object' -GROUP BY k.ld_key -ORDER BY MAX(k.ordinality), COUNT(k.ordinality) -""", - ) - .format(source_table=source_table, json_col=self.identifier) - .as_string(), - ) - props = [prop[0] for prop in cur.fetchall()] - - ctx.scan_progress.total += len(props) * 3 - ctx.scan_progress.refresh() - ctx.scan_progress.update(1) - - metadata: list[Metadata] = [] - for prop in props: - with ctx.conn.cursor() as cur: - cur.execute( - sql.SQL( - """ -SELECT - BOOL_AND(json_type = 'array') AS only_array - ,BOOL_OR(json_type = 'array') AS some_array - ,BOOL_AND(json_type = 'object') AS only_object - ,BOOL_OR(json_type = 'object') AS some_object -FROM -( - SELECT jsonb_typeof(t.{json_col}->$1) AS json_type - FROM {table} t -) j -WHERE json_type <> 'null' -""", - ) - .format( - table=source_table, - json_col=self.identifier, - ) - .as_string(), - (prop,), - ) - (only_array, some_array, only_object, some_object) = cast( - "tuple[bool, bool, bool, bool]", - cur.fetchone(), - ) - - if (some_array and not only_array) or (some_object and not only_object): - metadata.append(MixedMeta(prop)) - ctx.scan_progress.update(3) - continue - - if only_object: - metadata.append(ObjectMeta(prop)) - ctx.scan_progress.total += 1 - ctx.scan_progress.update(3) - continue - - if only_array: - ctx.scan_progress.update(1) - cur.execute( - sql.SQL( - """ -SELECT - -- Technically arrays could be nested but I haven't seen any - BOOL_AND(json_type = 'object') AS only_object - ,BOOL_OR(json_type = 'object') AS some_object -FROM -( - SELECT a.json_type - FROM {table} t - CROSS JOIN LATERAL - ( - SELECT jsonb_typeof(ld_value) AS json_type - FROM jsonb_array_elements(t.{json_col}->$1) a(ld_value) - WHERE jsonb_typeof(t.{json_col}->$1) = 'array' - ) a -) j -WHERE json_type <> 'null' -""", - ) - .format( - table=source_table, - json_col=self.identifier, - ) - .as_string(), - (prop,), - ) - (inner_only_object, inner_some_object) = cast( - "tuple[bool, bool]", - cur.fetchone(), - ) - - if inner_some_object and not inner_only_object: - metadata.append(MixedArrayMeta(prop)) - ctx.scan_progress.update(2) - continue - - if inner_only_object: - metadata.append(ObjectArrayMeta(prop)) - ctx.scan_progress.total += 1 - ctx.scan_progress.update(2) - continue - - ctx.scan_progress.update(1) - typed_from_sql = """ -FROM {table} t -CROSS JOIN LATERAL -( - SELECT * - FROM jsonb_array_elements(t.{json_col}->$1) a(ld_value) - WHERE jsonb_typeof(t.{json_col}->$1) = 'array' - LIMIT 3 -) j""" - else: - ctx.scan_progress.update(2) - typed_from_sql = """ -FROM (SELECT t.{json_col}->$1 AS ld_value FROM {table} t) j -""" - with ctx.conn.cursor() as cur: - cur.execute( - sql.SQL( - """ -SELECT - MIN(json_type) AS json_type - ,MAX(json_type) AS other_json_type - ,BOOL_AND(CASE WHEN json_type = 'string' THEN (ld_value)::text LIKE '"________-____-____-____-____________"' ELSE FALSE END) AS is_uuid - ,BOOL_AND(CASE WHEN json_type = 'string' THEN (ld_value)::text LIKE '"____-__-__T__:__:__.___%"' ELSE FALSE END) AS is_datetime - ,BOOL_OR(CASE WHEN json_type = 'number' THEN (ld_value)::numeric % 1 <> 0 ELSE FALSE END) AS is_float - ,BOOL_OR(CASE WHEN json_type = 'number' THEN (ld_value)::numeric > 2147483647 ELSE FALSE END) AS is_bigint -FROM -( - SELECT - ld_value - ,jsonb_typeof(ld_value) json_type """ # noqa: E501 - + typed_from_sql - + """ - WHERE ld_value IS NOT NULL -) i -WHERE - ld_value IS NOT NULL AND - json_type <> 'null' AND - ( - json_type <> 'string' OR - (json_type = 'string' AND ld_value::text NOT IN ('"null"', '""')) - ) -""", - ) - .format( - table=source_table, - json_col=self.identifier, - ) - .as_string(), - (prop,), - ) - if (row := cur.fetchone()) is not None and all( - c is not None for c in row - ): - metadata.append( - TypedArrayMeta(prop, *row) - if only_array - else TypedMeta(prop, *row), - ) - ctx.scan_progress.update(1) - - create_columns.extend( - [meta.select_column(self.identifier, self.add(meta)) for meta in metadata], - ) - - with ctx.conn.cursor() as cur: - cur.execute( - sql.SQL( - """ -CREATE TEMP TABLE {dest_table} AS -""" - + source_cte - + """ -SELECT - {cols} -FROM ld_source -""", - ) - .format( - source_table=source_table, - dest_table=dest_table, - json_col=self.identifier, - cols=sql.SQL("\n ,").join(create_columns), - ) - .as_string(), - ) - - return True - - def _carryover(self) -> Iterator[str]: - for n in self.root.descendents: - if isinstance(n, ObjectNode) and not n.unnested and n.name != "jsonb": - yield n.name - if isinstance(n, ArrayNode): - yield n.name - yield from n.values - - @property - def carryover(self) -> list[str]: - return list(self._carryover()) - - -class ArrayNode(ExpansionNode): - def __init__( - self, - name: str, - path: str, - parent: ExpansionNode | None, - meta: ArrayMeta, - values: list[str] | None = None, - ): - super().__init__(name, path, parent, values) - self.meta = meta.unwrap() - - @property - def is_object(self) -> bool: - return isinstance(self.meta, ObjectMeta) - - def explode( - self, - conn: duckdb.DuckDBPyConnection | psycopg.Connection, - source_table: sql.Identifier, - dest_table: sql.Identifier, - source_cte: str, - ) -> list[str]: - with conn.cursor() as cur: - o_col = self.name + "__o" - create_columns: list[sql.Composable] = [ - sql.SQL( - "(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)))::integer AS __id", - ), - *[sql.Identifier(v) for v in self.carryover], - sql.SQL( - """a."ordinality"::smallint AS {id_alias}""", - ).format( - id_alias=sql.Identifier(o_col), - ), - self.meta.select_column( - sql.Identifier("a", "ld_value"), - self.name, - ), - ] - - cur.execute( - sql.SQL( - """ -CREATE TEMP TABLE {dest_table} AS -""" - + source_cte - + """ -SELECT - {cols} -FROM - ld_source s - ,jsonb_array_elements(s.{json_col}) WITH ORDINALITY a(ld_value, "ordinality") -WHERE jsonb_typeof(s.{json_col}) = 'array' -""", - ) - .format( - source_table=source_table, - dest_table=dest_table, - cols=sql.SQL("\n ,").join(create_columns), - json_col=sql.Identifier(self.name), - ) - .as_string(), - ) - - return ["__id", *self.carryover, o_col] - - def _carryover(self) -> Iterator[str]: - for n in reversed(self.parents): - yield from [v for v in n.values if v not in ("__id", "jsonb")] - - @property - def carryover(self) -> list[str]: - return list(self._carryover()) diff --git a/src/ldlite/database/_expansion/recursive_nodes.py b/src/ldlite/database/_expansion/recursive_nodes.py new file mode 100644 index 0000000..c5faf26 --- /dev/null +++ b/src/ldlite/database/_expansion/recursive_nodes.py @@ -0,0 +1,387 @@ +from __future__ import annotations + +from abc import ABC, abstractmethod +from collections import deque +from typing import TYPE_CHECKING, TypeVar, cast +from uuid import uuid4 + +from psycopg import sql + +if TYPE_CHECKING: + from collections.abc import Callable, Iterator + + +from .fixed_nodes import FixedValueNode, JsonbNode, JsonType, OrdinalNode, TypedNode +from .node import Conn, Node + +TNode = TypeVar("TNode", bound="Node") +TRode = TypeVar("TRode", bound="RecursiveNode") + + +class RecursiveNode(Node): + def __init__( + self, + source: sql.Identifier, + prop: str | None, + column: sql.Identifier, + parent: RecursiveNode | None, + ): + super().__init__(source, prop) + + self.parent = parent + self.column = column + self._children: list[Node] = [] + + def _parents(self) -> Iterator[RecursiveNode]: + p = self.parent + while p is not None: + yield p + p = p.parent + + @property + def parents(self) -> list[RecursiveNode]: + return list(self._parents()) + + @property + def table_parent(self) -> RecursiveNode: + for p in self.parents: + if isinstance(p, (ArrayNode, RootNode)): + return p + + # There's "always" a root node + return None # type: ignore[return-value] + + @property + def depth(self) -> int: + depth = 0 + prev = None + for p in self.parents: + # arrays of objects only count for a single level of depth + if not (isinstance(p, ObjectNode) and isinstance(prev, ArrayNode)): + depth += 1 + prev = p + + return depth + + def replace(self, original: Node, replacement: Node | None) -> None: + if replacement is None: + self._children.remove(original) + return + + self._children = [(replacement if n == original else n) for n in self._children] + + def unparent(self) -> None: + cast("RecursiveNode", self.parent).replace(self, None) + + def make_jsonb(self) -> None: + cast("RecursiveNode", self.parent).replace( + self, + JsonbNode(self.source, self.path, self.prefix), + ) + + @property + def path(self) -> sql.Composable: + prop_accessor: sql.Composable + if self.prop is None: + prop_accessor = sql.SQL("") + else: + prop_accessor = sql.SQL("->") + sql.Literal(self.prop) + + path: list[str] = [] + for p in self.parents: + if isinstance(p, (ArrayNode, RootNode)): + break + if p.prop is not None: + path.append(p.prop) + + if len(path) == 0: + return self.column + prop_accessor + + return ( + self.column + + sql.SQL("->") + + sql.SQL("->").join([sql.Literal(p) for p in reversed(path)]) + + prop_accessor + ) + + @property + def prefix(self) -> str: + if len(self.parents) == 0 or isinstance(self.parents[0], RootNode): + return self.snake_prop or "" + + return "__".join( + [p.snake_prop for p in reversed(self.parents) if p.snake_prop is not None], + ) + (("__" + self.snake_prop) if self.snake_prop is not None else "") + + def _direct(self, cls: type[TNode]) -> Iterator[TNode]: + yield from [n for n in self._children if isinstance(n, cls)] + + def direct(self, cls: type[TNode]) -> list[TNode]: + return list(self._direct(cls)) + + def _descendents( + self, + cls: type[TRode], + to_cls: type[TRode] | None = None, + ) -> Iterator[TRode]: + to_visit = deque(self.direct(RecursiveNode)) + while to_visit: + n = to_visit.pop() + if isinstance(n, cls): + yield n + + if to_cls is not None and isinstance(n, to_cls): + continue + + to_visit.extend(n.direct(RecursiveNode)) + + def descendents( + self, + cls: type[TRode], + to_cls: type[TRode] | None = None, + ) -> list[TRode]: + return list(self._descendents(cls, to_cls)) + + def _typed_nodes(self) -> Iterator[TypedNode]: + yield from self.direct(TypedNode) + for n in self._descendents(RecursiveNode): + yield from n.direct(TypedNode) + + def typed_nodes(self) -> list[TypedNode]: + return list(self._typed_nodes()) + + +class ObjectNode(RecursiveNode): + def load_columns(self, conn: Conn) -> None: + with conn.cursor() as cur: + key_discovery = ( + sql.SQL(""" +SELECT + json_key + ,MIN(json_type) AS json_type + ,MAX(json_type) AS other_json_type +FROM +( + SELECT + k."key" AS json_key + ,jsonb_typeof(k."value") AS json_type + ,k.ord + FROM + ( + SELECT """) + + self.path + + sql.SQL(""" AS ld_value FROM {source_table} + ) j + CROSS JOIN LATERAL jsonb_each(j.ld_value) WITH ORDINALITY k("key", "value", ord) + WHERE jsonb_typeof(j.ld_value) = 'object' +) key_discovery +WHERE json_type <> 'null' +GROUP BY json_key +ORDER BY MAX(ord), COUNT(*); +""").format(source_table=self.source) + ) + + cur.execute(key_discovery.as_string()) + for row in cur.fetchall(): + (key, jt, ojt) = cast("tuple[str, JsonType, JsonType]", row) + if jt == "array" and ojt == "array": + anode = ArrayNode(self.source, key, self.column, self) + self._children.append(anode) + elif jt == "object" and ojt == "object": + onode = ObjectNode(self.source, key, self.column, self) + self._children.append(onode) + else: + tnode = TypedNode( + self.source, + key, + self.path, + self.prefix, + (jt, ojt), + ) + self._children.append(tnode) + + +class StampableTable(ABC): + @property + @abstractmethod + def create_statement(self) -> tuple[str, sql.Composed]: ... + + +class RootNode(ObjectNode, StampableTable): + def __init__( + self, + source: sql.Identifier, + get_output_table: Callable[[str | None], tuple[str, sql.Identifier]], + ): + super().__init__( + source, + None, + sql.Identifier("jsonb"), + None, + ) + self.get_output_table = get_output_table + + @property + def create_statement(self) -> tuple[str, sql.Composed]: + (output_table_name, output_table) = self.get_output_table(None) + + return ( + output_table_name, + sql.SQL(""" +CREATE TABLE {output_table} AS +SELECT + """).format(output_table=output_table) + + sql.SQL("\n ,").join( + [ + sql.Identifier("__id"), + *[t.stmt for t in self.direct(TypedNode)], + *[ + t.stmt + for o in self.descendents(ObjectNode, ArrayNode) + for t in o.direct(TypedNode) + ], + ], + ) + + sql.SQL(""" +FROM {source_table}; +ANALYZE {output_table} (__id);""").format( + source_table=self.source, + output_table=output_table, + ), + ) + + +class ArrayNode(RecursiveNode, StampableTable): + def __init__( + self, + source: sql.Identifier, + prop: str | None, + column: sql.Identifier, + parent: RecursiveNode | None, + ): + super().__init__(source, prop, column, parent) + self.temp = sql.Identifier(str(uuid4()).split("-")[0]) + + def make_temp(self, conn: Conn) -> Node | None: + with conn.cursor() as cur: + expansion = ( + sql.SQL(""" +CREATE TEMPORARY TABLE {temp} AS +SELECT + __id AS p__id + ,(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)))::integer AS __id + ,ord::smallint AS __o + ,array_jsonb + ,json_type +FROM ( + SELECT + j.__id + ,a."value" AS array_jsonb + ,jsonb_typeof(a."value") AS json_type + ,a.ord + FROM + ( + SELECT """).format(temp=self.temp) + + self.path + + sql.SQL(""" AS ld_value, __id FROM {source} + ) j + CROSS JOIN LATERAL jsonb_array_elements(j.ld_value) WITH ORDINALITY a("value", ord) + WHERE jsonb_typeof(j.ld_value) = 'array' +) expansion +WHERE json_type <> 'null'; +ANALYZE {temp} (p__id, array_jsonb, json_type); +""").format(source=self.source, temp=self.temp) + ) + cur.execute(expansion.as_string()) + + type_discovery = sql.SQL(""" +SELECT + MIN(json_type) AS json_type + ,MAX(json_type) AS other_json_type +FROM {temp}""").format(temp=self.temp) + + cur.execute(type_discovery.as_string()) + self._children.append(OrdinalNode(self.temp, self.path, self.prefix)) + if row := cur.fetchone(): + (jt, ojt) = cast("tuple[JsonType, JsonType]", row) + node: Node + if jt == "array" and ojt == "array": + node = ArrayNode( + self.temp, + None, + sql.Identifier("array_jsonb"), + self, + ) + elif jt == "object" and ojt == "object": + node = ObjectNode( + self.temp, + None, + sql.Identifier("array_jsonb"), + self, + ) + else: + node = TypedNode( + self.temp, + None, + sql.Identifier("array_jsonb"), + self.prefix, + (jt, ojt), + ) + self._children.append(node) + return node + + return None + + @property + def create_statement(self) -> tuple[str, sql.Composed]: + table_parent: RecursiveNode = self + parents: list[RecursiveNode] = [] + for p in self.parents: + if table_parent == self and isinstance(p, (RootNode, ArrayNode)): + table_parent = p + parents.append(p) + + root = cast("RootNode", parents[-1]) + (output_table_name, output_table) = root.get_output_table(self.prefix) + if not isinstance(table_parent, ArrayNode): + (_, parent_table) = root.get_output_table(None) + else: + (_, parent_table) = root.get_output_table(table_parent.prefix) + + return ( + output_table_name, + ( + sql.SQL( + """ +CREATE TABLE {output_table} AS +SELECT + """, + ).format(output_table=output_table) + + sql.SQL("\n ,").join( + [ + sql.Identifier("a", "__id"), + *[ + sql.Identifier("p", t.alias) + for p in reversed(parents) + for t in p.direct(FixedValueNode) + ], + *[t.stmt for t in self.direct(FixedValueNode)], + *[ + t.stmt + for o in self.descendents(ObjectNode, ArrayNode) + for t in o.direct(TypedNode) + ], + ], + ) + + sql.SQL(""" +FROM {source_table} a +JOIN {parent_table} p ON + a.p__id = p.__id; +ANALYZE {output_table} (__id); +""").format( + source_table=self.temp, + parent_table=parent_table, + output_table=output_table, + ) + ), + ) diff --git a/src/ldlite/database/_postgres.py b/src/ldlite/database/_postgres.py index 88cbc42..93ca50c 100644 --- a/src/ldlite/database/_postgres.py +++ b/src/ldlite/database/_postgres.py @@ -80,30 +80,13 @@ def ingest_records( rb.extend(r) copy.write_row((next(pkey).to_bytes(4, "big"), rb)) + with conn.cursor() as cur: + cur.execute( + sql.SQL("ANALYZE {table} (jsonb);").format(table=pfx.raw_table.id), + ) + total = next(pkey) - 1 self._download_complete(conn, pfx, total, download_started) conn.commit() return next(pkey) - 1 - - def preprocess_source_table( - self, - conn: psycopg.Connection, - table_name: sql.Identifier, - column_names: list[sql.Identifier], - ) -> None: - if len(column_names) == 0: - return - - with conn.cursor() as cur: - cur.execute( - sql.SQL("ANALYZE {table_name} ({column_name})").format( - table_name=table_name, - column_name=sql.SQL(",").join(column_names), - ), - ) - - def source_table_cte_stmt(self, keep_source: bool) -> str: - if keep_source: - return "WITH ld_source AS (SELECT * FROM {source_table})" - return "WITH ld_source AS (DELETE FROM {source_table} RETURNING *)" diff --git a/src/ldlite/database/_prefix.py b/src/ldlite/database/_prefix.py index a93dd81..456083e 100644 --- a/src/ldlite/database/_prefix.py +++ b/src/ldlite/database/_prefix.py @@ -34,9 +34,9 @@ def raw_table(self) -> PrefixedTable: def _output_table(self) -> str: return self._prefix + "__t" - def output_table(self, prefix: str) -> PrefixedTable: + def output_table(self, prefix: str | None) -> PrefixedTable: return self._prefixed_table( - self._output_table + ("" if len(prefix) == 0 else "__" + prefix), + self._output_table + ("" if prefix is None else "__" + prefix), ) @property diff --git a/src/ldlite/database/_typed_database.py b/src/ldlite/database/_typed_database.py index 6560c1b..41b10e6 100644 --- a/src/ldlite/database/_typed_database.py +++ b/src/ldlite/database/_typed_database.py @@ -1,4 +1,3 @@ -# pyright: reportArgumentType=false from __future__ import annotations from abc import abstractmethod @@ -12,8 +11,7 @@ from tqdm import tqdm from . import Database -from ._expansion import expand_nonmarc -from ._expansion.context import ExpandContext +from ._expansion import non_srs_statements from ._prefix import Prefix if TYPE_CHECKING: @@ -182,19 +180,6 @@ def _prepare_raw_table( ).as_string(), ) - def preprocess_source_table( - self, - conn: DB, - table_name: sql.Identifier, - column_names: list[sql.Identifier], - ) -> None: ... - - # TODO: Refactor this to use DELETE RETURNING when DuckDb resolves - # https://github.com/duckdb/duckdb/issues/3417 - # Only postgres supports it which is why we have an abstraction here - @abstractmethod - def source_table_cte_stmt(self, keep_source: bool) -> str: ... - def expand_prefix( self, prefix: str, @@ -216,83 +201,67 @@ def expand_prefix( return [] with closing(self._conn_factory(False)) as conn: - with conn.cursor() as cur: - cur.execute( - sql.SQL( - """ -CREATE TEMP TABLE {dest_table} AS -""" - + self.source_table_cte_stmt(keep_source=keep_raw) - + """ -SELECT * from ld_source; -""", - ) - .format( - dest_table=pfx.origin_table, - source_table=pfx.raw_table.id, - ) - .as_string(), - ) + tables_to_create = non_srs_statements( + conn, + pfx.raw_table[1], + pfx.output_table, + json_depth, + scan_progress + if scan_progress is not None + else tqdm(disable=True, total=0), + ) - tables_to_create = expand_nonmarc( - "jsonb", - ["__id"], - ExpandContext( - conn, - pfx.origin_table, - json_depth, - pfx.transform_table, - pfx.output_table, - self.preprocess_source_table, # type: ignore [arg-type] - self.source_table_cte_stmt, - scan_progress if scan_progress is not None else tqdm(disable=True), - transform_progress - if transform_progress is not None - else tqdm(disable=True), - ), + transform_progress = ( + transform_progress + if transform_progress is not None + else tqdm(disable=True, total=0) + ) + transform_progress.total = ( + ( + transform_progress.total + if transform_progress.total is not None + else 0 + ) + + len(tables_to_create) + + 1 ) + transform_progress.update(1) with self._begin(conn): self._drop_extracted_tables(conn, pfx) + with conn.cursor() as cur: + for _, table in tables_to_create: + cur.execute(table.as_string()) + transform_progress.update(1) + if not keep_raw: self._drop_raw_table(conn, pfx) - with conn.cursor() as cur: - for table in tables_to_create: - cur.execute(table[1].as_string()) + total = 0 with conn.cursor() as cur: - cur.execute( - sql.SQL( - """ -CREATE TABLE {catalog_table} ( - table_name text -) -""", - ) - .format(catalog_table=pfx.catalog_table.id) - .as_string(), - ) - total = 0 + create_catalog = sql.SQL( + """CREATE TABLE {catalog_table} (table_name text)""", + ).format(catalog_table=pfx.catalog_table.id) + cur.execute(create_catalog.as_string()) if len(tables_to_create) > 0: + insert_catalog = sql.SQL( + "INSERT INTO {catalog_table} VALUES ($1)", + ).format(catalog_table=pfx.catalog_table.id) cur.executemany( - sql.SQL("INSERT INTO {catalog_table} VALUES ($1)") - .format( - catalog_table=pfx.catalog_table.id, - ) - .as_string(), + insert_catalog.as_string(), [(pfx.catalog_table_row(t[0]),) for t in tables_to_create], ) - cur.execute( - sql.SQL("SELECT COUNT(*) FROM {table}") - .format(table=pfx.output_table("").id) - .as_string(), + count = sql.SQL("SELECT COUNT(*) FROM {table}").format( + table=pfx.output_table(None).id, ) + cur.execute(count.as_string()) total = cast("tuple[int]", cur.fetchone())[0] + transform_progress.update(1) self._transform_complete(conn, pfx, total, transform_started) - return [t[0] for t in tables_to_create] + return [pfx.catalog_table_row(t[0]) for t in tables_to_create] def index_prefix(self, prefix: str, progress: tqdm[NoReturn] | None = None) -> None: pfx = Prefix(prefix) @@ -422,6 +391,7 @@ def _transform_complete( "final_rowcount" = $2 ,"transform_complete" = $3 ,"transform_time" = $4 + ,"index_time" = NULL ,"data_refresh_start" = "load_start" ,"data_refresh_end" = "download_complete" WHERE "table_prefix" = $1 diff --git a/tests/test_expansion.py b/tests/test_expansion.py index 094dfa4..9efed25 100644 --- a/tests/test_expansion.py +++ b/tests/test_expansion.py @@ -52,6 +52,7 @@ def case_typed_columns() -> ExpansionTC: "timestamptz": "2028-01-23T00:00:00.000+00:00", "integer": 1, "numeric": 1.2, + "bigint": 1774374169585, "text": "value", "boolean": false, "uuid": "88888888-8888-1888-8888-888888888888" @@ -60,9 +61,10 @@ def case_typed_columns() -> ExpansionTC: b""" { "id": "id2", - "timestamptz": "2025-06-20T17:37:58.675+00:00", + "timestamptz": "2025-06-20T17:37:58.675", "integer": 2, - "numeric": 2.3, + "numeric": 2, + "bigint": 2, "text": "00000000-0000-1000-A000-000000000000", "boolean": false, "uuid": "11111111-1111-1111-8111-111111111111" @@ -82,6 +84,7 @@ def case_typed_columns() -> ExpansionTC: for a in [ ("integer", "integer", "INTEGER"), ("numeric", "numeric", "DECIMAL(18,3)"), + ("bigint", "bigint", "BIGINT"), ("text", "text", "VARCHAR"), ("uuid", "uuid", "UUID"), ("boolean", "boolean", "BOOLEAN"), diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index ac43355..75a2672 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -27,7 +27,7 @@ class JsonTC: assertion_params: tuple[Any, ...] -def case_jsonb_object_keys() -> JsonTC: +def case_jsonb_each() -> JsonTC: return JsonTC( """ {assertion} @@ -35,7 +35,7 @@ def case_jsonb_object_keys() -> JsonTC: FROM (SELECT 'k1' jkey UNION SELECT 'k2' jkey) as e FULL OUTER JOIN ( SELECT k.ld_key as jkey - FROM j, jsonb_object_keys(j.jc->'obj') k(ld_key) + FROM j, jsonb_each(j.jc->'obj') k(ld_key) ) as a USING (jkey) WHERE e.jkey IS NULL or a.jkey IS NULL) as q;""", From b7c6800c253ac5e0d95a32784ce1cb5684e60fd1 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Mon, 30 Mar 2026 09:50:07 -0400 Subject: [PATCH 22/25] Replace export_csv and select custom code with native functionality (#73) When LDLite was first released there weren't reliable ways to export or display data. duckdb's newer releases make it really easy and can replace the existing code. There are no longer specific tests for the csv format, they are exported however duckdb formats them. --- pyproject.toml | 8 +- src/ldlite/__init__.py | 73 ++++++--- src/ldlite/_csv.py | 88 ----------- src/ldlite/_select.py | 163 -------------------- tests/export_csv_samples/basic.csv | 2 - tests/export_csv_samples/datatypes.csv | 2 - tests/export_csv_samples/escaped_chars.csv | 5 - tests/export_csv_samples/sorting.csv | 4 - tests/test___init__.py | 57 ++++++- tests/test_export_csv.py | 171 --------------------- 10 files changed, 115 insertions(+), 458 deletions(-) delete mode 100644 src/ldlite/_csv.py delete mode 100644 src/ldlite/_select.py delete mode 100644 tests/export_csv_samples/basic.csv delete mode 100644 tests/export_csv_samples/datatypes.csv delete mode 100644 tests/export_csv_samples/escaped_chars.csv delete mode 100644 tests/export_csv_samples/sorting.csv delete mode 100644 tests/test_export_csv.py diff --git a/pyproject.toml b/pyproject.toml index cf1f86a..11b2da9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ pydocstyle.convention = "google" [tool.ruff.lint.per-file-ignores] "examples/*" = ["D", "INP001", "T201", "S106", "ERA001", "PERF203"] "tests/*" = ["D", "S", "INP001", "N813", "PLC0415"] -"src/ldlite/{_csv.py,_jsonx.py,_select.py}" = ["S608"] +"src/ldlite/{_jsonx.py,_select.py}" = ["S608"] "src/ldlite/__init__.py" = ["T201"] [tool.ruff.lint.flake8-annotations] mypy-init-return = true @@ -65,6 +65,12 @@ mypy-init-return = true [tool.coverage.run] branch = true include = ["src/**"] +omit = [ + "src/ldlite/__init__.py", + "src/ldlite/_jsonx.py", + "src/ldlite/_sqlx.py", + "src/ldlite/_camelcase.py", +] [tool.pdm] distribution = true diff --git a/src/ldlite/__init__.py b/src/ldlite/__init__.py index e6cd1f8..f875489 100644 --- a/src/ldlite/__init__.py +++ b/src/ldlite/__init__.py @@ -40,15 +40,13 @@ import duckdb import psycopg from httpx_folio.auth import FolioParams +from psycopg import sql from tqdm import tqdm -from ._csv import to_csv from ._folio import FolioClient from ._jsonx import Attr, transform_json -from ._select import select from ._sqlx import ( DBType, - as_postgres, autocommit, sqlid, ) @@ -148,6 +146,7 @@ def connect_db_postgresql(self, dsn: str) -> psycopg.Connection: from .database._postgres import PostgresDatabase # noqa: PLC0415 self.dbtype = DBType.POSTGRES + self._dsn = dsn db = psycopg.connect(dsn) self.db = cast("dbapi.DBAPIConnection", db) self._database = PostgresDatabase(dsn) @@ -501,16 +500,32 @@ def select( self._check_db() return - f = sys.stdout - if self._verbose: - print("ldlite: reading from table: " + table, file=sys.stderr) - autocommit(self.db, self.dbtype, False) - try: - select(self.db, self.dbtype, table, columns, limit, f) - if (pgdb := as_postgres(self.db, self.dbtype)) is not None: - pgdb.rollback() - finally: - autocommit(self.db, self.dbtype, True) + if self.dbtype == DBType.POSTGRES: + duck = duckdb.connect() + duck.sql("INSTALL postgres;") + duck.sql("LOAD postgres;") + duck.sql(f"ATTACH '{self._dsn}' AS pg (TYPE postgres)") + if len(prefix := table.split(".")) == 1: + table_id = sql.Identifier("pg", "public", prefix[0]) + else: + table_id = sql.Identifier("pg", *prefix) + else: + duck = cast("duckdb.DuckDBPyConnection", self.db.cursor()) + table_id = sql.Identifier(*table.split(".")) + + cols = ( + sql.SQL("*") + if columns is None + else sql.SQL(",").join([sql.Identifier(c) for c in columns]) + ) + export = sql.SQL("SELECT {cols} FROM {table}").format( + table=table_id, + cols=cols, + ) + ( + sql.SQL("LIMIT ") + sql.Literal(limit) if limit is not None else sql.SQL("") + ) + print(export.as_string()) + duck.sql(export.as_string()).show() def export_csv(self, filename: str, table: str, header: bool = True) -> None: """Export a table in the reporting database to a CSV file. @@ -529,13 +544,31 @@ def export_csv(self, filename: str, table: str, header: bool = True) -> None: self._check_db() return - autocommit(self.db, self.dbtype, False) - try: - to_csv(self.db, self.dbtype, table, filename, header) - if (pgdb := as_postgres(self.db, self.dbtype)) is not None: - pgdb.rollback() - finally: - autocommit(self.db, self.dbtype, True) + if self.dbtype == DBType.POSTGRES: + duck = duckdb.connect() + duck.sql("INSTALL postgres;") + duck.sql("LOAD postgres;") + duck.sql(f"ATTACH '{self._dsn}' AS pg (TYPE postgres)") + if len(prefix := table.split(".")) == 1: + table_id = sql.Identifier("pg", "public", prefix[0]) + else: + table_id = sql.Identifier("pg", *prefix) + else: + duck = cast("duckdb.DuckDBPyConnection", self.db.cursor()) + table_id = sql.Identifier(*table.split(".")) + + print(type(filename)) + export = ( + sql.SQL("COPY (SELECT * FROM {table}) TO {file} WITH ").format( + table=table_id, + file=sql.Literal(filename), + ) + + sql.SQL("(HEADER, DELIMITER ',')") + if header + else sql.SQL("(DELIMETER ',')") + ) + print(export.as_string()) + duck.execute(export.as_string()) def to_csv(self) -> NoReturn: # pragma: nocover """Deprecated; use export_csv().""" diff --git a/src/ldlite/_csv.py b/src/ldlite/_csv.py deleted file mode 100644 index b8e7ae9..0000000 --- a/src/ldlite/_csv.py +++ /dev/null @@ -1,88 +0,0 @@ -from pathlib import Path -from typing import TYPE_CHECKING - -from ._sqlx import DBType, server_cursor, sqlid - -if TYPE_CHECKING: - from _typeshed import dbapi - - -def _escape_csv(field: str) -> str: - b = "" - for f in field: - if f == '"': - b += '""' - else: - b += f - return b - - -def to_csv( - db: "dbapi.DBAPIConnection", - dbtype: DBType, - table: str, - filename: str, - header: bool, -) -> None: - # Read attributes - attrs: list[tuple[str, dbapi.DBAPITypeCode]] = [("__id", "NUMBER")] - - cur = server_cursor(db, dbtype) - try: - cur.execute("SELECT * FROM " + sqlid(table) + " LIMIT 1") - cur.fetchall() - if cur.description is not None: - t_attrs = [(a[0], a[1]) for a in cur.description[1:]] - attrs.extend(sorted(t_attrs, key=lambda a: a[0])) - finally: - cur.close() - - # Write data - cur = server_cursor(db, dbtype) - try: - cols = ",".join([sqlid(a[0]) for a in attrs]) - cur.execute( - "SELECT " - + cols - + " FROM " - + sqlid(table) - + " ORDER BY " - + ",".join([str(i + 2) for i in range(len(attrs[1:]))]), - ) - fn = Path(filename if "." in filename else filename + ".csv") - with fn.open("w") as f: - if header: - print(",".join(['"' + a[0] + '"' for a in attrs]), file=f) - while True: - row = cur.fetchone() - if row is None: - break - s = "" - for i, data in enumerate(row): - d = "" if data is None else data - if i != 0: - s += "," - if attrs[i][1] in [ - "INTEGER", - "NUMBER", - "DECIMAL(18,3)", - "bigint", - "integer", - "numeric", - 20, - 23, - 1700, - ]: - s += str(d).rstrip("0").rstrip(".") - elif attrs[i][1] in [ - "boolean", - "bool", - 16, - ]: - s += str(bool(d)) - - else: - s += '"' + _escape_csv(str(d)) + '"' - print(s, file=f) - finally: - cur.close() diff --git a/src/ldlite/_select.py b/src/ldlite/_select.py deleted file mode 100644 index ad7ce5a..0000000 --- a/src/ldlite/_select.py +++ /dev/null @@ -1,163 +0,0 @@ -import sys -from collections.abc import Sequence -from typing import TYPE_CHECKING, TextIO - -from ._sqlx import DBType, server_cursor, sqlid - -if TYPE_CHECKING: - from _typeshed import dbapi - - -def _format_attr(attr: tuple[str, "dbapi.DBAPITypeCode"], width: int) -> str: - s = "" - a = attr[0] - len_a = len(a) - shift_left = 1 if (len_a % 2 == 1 and width % 2 == 0 and len_a < width) else 0 - start = int(width / 2) - int(len_a / 2) - shift_left - for _ in range(start): - s += " " - s += a - for _ in range(width - start - len_a): - s += " " - return s - - -def _maxlen(lines: list[str]) -> int: - m = 0 - for s in lines: - m = max(m, len(s)) - return m - - -def _rstrip_lines(lines: list[str]) -> list[str]: - return [s.rstrip() for s in lines] - - -def _format_value(value: list[str], dtype: "dbapi.DBAPITypeCode") -> list[str]: - if len(value) > 1: - return value - if dtype in {"bool", 16}: - return ["t"] if value[0] == "True" else ["f"] - return value - - -def _format_row( - row: Sequence[str], - attrs: list[tuple[str, "dbapi.DBAPITypeCode"]], - width: list[int], -) -> str: - s = "" - # Count number of lines - rowlines = [] - maxlen = [] - maxlines = 1 - for i, data in enumerate(row): - lines = [""] - if data is not None: - lines = _format_value(_rstrip_lines(str(data).splitlines()), attrs[i][1]) - maxlen.append(_maxlen(lines)) - rowlines.append(lines) - lines_len = len(lines) - maxlines = max(maxlines, lines_len) - # Write lines - for i in range(maxlines): - for j, lines in enumerate(rowlines): - lines_i = lines[i] if i < len(lines) else "" - s += " " if j == 0 else "| " - if attrs[j][1] == "NUMBER" or attrs[j][1] == 20 or attrs[j][1] == 23: - start = width[j] - len(lines_i) - else: - start = 0 - for _ in range(start): - s += " " - s += lines_i - for _ in range(width[j] - start - len(lines_i)): - s += " " - s += " " - s += "\n" - return s - - -def select( # noqa: C901, PLR0912, PLR0913, PLR0915 - db: "dbapi.DBAPIConnection", - dbtype: DBType, - table: str, - columns: list[str] | None, - limit: int | None, - file: TextIO = sys.stdout, -) -> None: - if columns is None or columns == []: - colspec = "*" - else: - colspec = ",".join([sqlid(c) for c in columns]) - # Get attributes - attrs: list[tuple[str, dbapi.DBAPITypeCode]] = [] - width: list[int] = [] - cur = db.cursor() - try: - cur.execute("SELECT " + colspec + " FROM " + sqlid(table) + " LIMIT 1") - if cur.description is not None: - for a in cur.description: - attrs.append((a[0], a[1])) - width.append(len(a[0])) - finally: - cur.close() - # Scan - cur = server_cursor(db, dbtype) - try: - cur.execute( - "SELECT " - + ",".join([sqlid(a[0]) for a in attrs]) - + " FROM " - + sqlid(table), - ) - while True: - row = cur.fetchone() - if row is None: - break - for i, v in enumerate(row): - lines = [""] - if v is not None: - lines = str(v).splitlines() - for _, ln in enumerate(lines): - width[i] = max(width[i], len(ln.rstrip())) - finally: - cur.close() - cur = server_cursor(db, dbtype) - try: - q = "SELECT " + ",".join([sqlid(a[0]) for a in attrs]) + " FROM " + sqlid(table) - if limit is not None: - q += " LIMIT " + str(limit) - cur.execute(q) - # Attribute names - s = "" - for i, v in enumerate(attrs): - s += " " if i == 0 else "| " - s += _format_attr(v, width[i]) - s += " " - print(s, file=file) - # Header bar - s = "" - for i in range(len(attrs)): - s += "" if i == 0 else "+" - s += "-" - for _ in range(width[i]): - s += "-" - s += "-" - print(s, file=file) - # Data rows - row_i = 0 - while True: - row = cur.fetchone() - if row is None: - break - s = _format_row(row, attrs, width) - print(s, end="", file=file) - row_i += 1 - print( - "(" + str(row_i) + " " + ("row" if row_i == 1 else "rows") + ")", - file=file, - ) - print(file=file) - finally: - cur.close() diff --git a/tests/export_csv_samples/basic.csv b/tests/export_csv_samples/basic.csv deleted file mode 100644 index c9d54c3..0000000 --- a/tests/export_csv_samples/basic.csv +++ /dev/null @@ -1,2 +0,0 @@ -"__id","id","val" -1,"id","value" diff --git a/tests/export_csv_samples/datatypes.csv b/tests/export_csv_samples/datatypes.csv deleted file mode 100644 index de4bb68..0000000 --- a/tests/export_csv_samples/datatypes.csv +++ /dev/null @@ -1,2 +0,0 @@ -"__id","boolean","id","integer","numeric","string","uuid" -1,True,"id",1,1.1,"string","6a31a12a-9570-405c-af20-6abf2992859c" diff --git a/tests/export_csv_samples/escaped_chars.csv b/tests/export_csv_samples/escaped_chars.csv deleted file mode 100644 index d271ee6..0000000 --- a/tests/export_csv_samples/escaped_chars.csv +++ /dev/null @@ -1,5 +0,0 @@ -"__id","comma","double_quote","id","new_line","single_quote" -1,"Double, double toil and trouble","Cry ""Havoc!"" a horse","id","To be -or not -to be","Cry 'Havoc!' a horse" -2,"Z","Z","id","Z","Z" diff --git a/tests/export_csv_samples/sorting.csv b/tests/export_csv_samples/sorting.csv deleted file mode 100644 index a53d693..0000000 --- a/tests/export_csv_samples/sorting.csv +++ /dev/null @@ -1,4 +0,0 @@ -"__id","a","b","c","id" -3,"Z","X","Y","id" -2,"ZZ","XX","Y","id" -1,"ZZ","XX","YY","id" diff --git a/tests/test___init__.py b/tests/test___init__.py index e19eb19..fc73a76 100644 --- a/tests/test___init__.py +++ b/tests/test___init__.py @@ -1,11 +1,18 @@ +from __future__ import annotations + from dataclasses import astuple, dataclass -from typing import cast +from typing import TYPE_CHECKING, cast +from uuid import uuid4 import httpx import pytest -from httpx_folio.auth import FolioParams from pytest_cases import parametrize_with_cases +if TYPE_CHECKING: + from collections.abc import Callable + + from httpx_folio.auth import FolioParams + @dataclass(frozen=True) class FolioConnectionCase: @@ -104,6 +111,52 @@ def test_ok(self, folio_params: tuple[bool, FolioParams]) -> None: ld.query(table="g", path="/groups") ld.select(table="g__t") + def test_ok_postgres( + self, + folio_params: tuple[bool, FolioParams], + pg_dsn: None | Callable[[str], str], + ) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + from ldlite import LDLite as uut + + ld = uut() + ld.connect_folio(*astuple(folio_params[1])) + ld.connect_db_postgresql(pg_dsn(str(uuid4()).split("-")[0])) + ld.query(table="g", path="/groups") + ld.select(table="g__t") + + def test_ok_export_csv( + self, + folio_params: tuple[bool, FolioParams], + tmpdir: str, + ) -> None: + from ldlite import LDLite as uut + + ld = uut() + ld.connect_folio(*astuple(folio_params[1])) + ld.connect_db() + ld.query(table="g", path="/groups") + ld.export_csv(str(tmpdir + "/g.csv"), "g__t") + + def test_ok_export_csv_postgres( + self, + folio_params: tuple[bool, FolioParams], + pg_dsn: None | Callable[[str], str], + tmpdir: str, + ) -> None: + if pg_dsn is None: + pytest.skip("Specify the pg host using --pg-host to run") + + from ldlite import LDLite as uut + + ld = uut() + ld.connect_folio(*astuple(folio_params[1])) + ld.connect_db_postgresql(pg_dsn(str(uuid4()).split("-")[0])) + ld.query(table="g", path="/groups") + ld.export_csv(str(tmpdir + "/g.csv"), "g__t") + def test_no_connect_folio(self) -> None: from ldlite import LDLite as uut diff --git a/tests/test_export_csv.py b/tests/test_export_csv.py deleted file mode 100644 index 55aaae2..0000000 --- a/tests/test_export_csv.py +++ /dev/null @@ -1,171 +0,0 @@ -from collections.abc import Callable -from dataclasses import dataclass -from difflib import unified_diff -from pathlib import Path -from typing import TYPE_CHECKING -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from pytest_cases import parametrize_with_cases - -from .mock_response_case import Call, MockedResponseTestCase - -if TYPE_CHECKING: - import ldlite - -_SAMPLE_PATH = Path() / "tests" / "export_csv_samples" - - -@dataclass(frozen=True) -class ExportCsvTC(MockedResponseTestCase): - expected_csvs: list[tuple[str, Path]] - - -def case_basic() -> ExportCsvTC: - return ExportCsvTC( - Call("prefix", returns={"purchaseOrders": [{"id": "id", "val": "value"}]}), - expected_csvs=[("prefix__t", _SAMPLE_PATH / "basic.csv")], - ) - - -def case_datatypes() -> ExportCsvTC: - return ExportCsvTC( - Call( - "prefix", - returns={ - "purchaseOrders": [ - { - "id": "id", - "string": "string", - "integer": 1, - "numeric": 1.1, - "boolean": True, - "uuid": "6a31a12a-9570-405c-af20-6abf2992859c", - }, - ], - }, - ), - expected_csvs=[("prefix__t", _SAMPLE_PATH / "datatypes.csv")], - ) - - -def case_escaped_chars() -> ExportCsvTC: - return ExportCsvTC( - Call( - "prefix", - returns={ - "purchaseOrders": [ - { - "id": "id", - "comma": "Double, double toil and trouble", - "doubleQuote": 'Cry "Havoc!" a horse', - "newLine": """To be -or not -to be""", - "singleQuote": "Cry 'Havoc!' a horse", - }, - { - "id": "id", - "comma": "Z", - "doubleQuote": "Z", - "newLine": "Z", - "singleQuote": "Z", - }, - ], - }, - ), - expected_csvs=[("prefix__t", _SAMPLE_PATH / "escaped_chars.csv")], - ) - - -def case_sorting() -> ExportCsvTC: - return ExportCsvTC( - Call( - "prefix", - returns={ - "purchaseOrders": [ - {"id": "id", "C": "YY", "B": "XX", "A": "ZZ"}, - {"id": "id", "C": "Y", "B": "XX", "A": "ZZ"}, - {"id": "id", "C": "Y", "B": "X", "A": "Z"}, - ], - }, - ), - expected_csvs=[("prefix__t", _SAMPLE_PATH / "sorting.csv")], - ) - - -def _arrange( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: ExportCsvTC, -) -> "ldlite.LDLite": - from ldlite import LDLite - - uut = LDLite() - tc.patch_request_get(uut, httpx_post_mock, client_get_mock) - uut.connect_folio("https://doesnt.matter", "", "", "") - return uut - - -def _act(uut: "ldlite.LDLite", tc: ExportCsvTC) -> None: - for call in tc.calls_list: - uut.query(table=call.prefix, path="/patched") - - -def _assert( - uut: "ldlite.LDLite", - tc: ExportCsvTC, - tmpdir: str, -) -> None: - for table, expected in tc.expected_csvs: - actual = (Path(tmpdir) / table).with_suffix(".csv") - - uut.export_csv(str(actual), table) - - with expected.open("r") as f: - expected_lines = f.readlines() - with actual.open("r") as f: - actual_lines = f.readlines() - - diff = list(unified_diff(expected_lines, actual_lines)) - if len(diff) > 0: - pytest.fail("".join(diff)) - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=".") -def test_duckdb( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - tc: ExportCsvTC, - tmpdir: str, -) -> None: - uut = _arrange(client_get_mock, httpx_post_mock, tc) - dsn = f":memory:{tc.db}" - uut.connect_db(dsn) - - _act(uut, tc) - _assert(uut, tc, tmpdir) - - -@mock.patch("httpx_folio.auth.httpx.post") -@mock.patch("httpx_folio.factories.httpx.Client.get") -@parametrize_with_cases("tc", cases=".") -def test_postgres( - client_get_mock: MagicMock, - httpx_post_mock: MagicMock, - pg_dsn: None | Callable[[str], str], - tc: ExportCsvTC, - tmpdir: str, -) -> None: - if pg_dsn is None: - pytest.skip("Specify the pg host using --pg-host to run") - - uut = _arrange(client_get_mock, httpx_post_mock, tc) - dsn = pg_dsn(tc.db) - uut.connect_db_postgresql(dsn) - - _act(uut, tc) - _assert(uut, tc, tmpdir) From bbb9577df56fbffe28003c63d477257253517b05 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Wed, 1 Apr 2026 11:14:13 -0400 Subject: [PATCH 23/25] Update changelog, migrating, and readme (#74) --- CHANGELOG.md | 28 +++++++++++++++++++ MIGRATING.md | 67 +++++++++++++++++++++++++++++++++++++++++++-- README.md | 76 ++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 155 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 871a049..85db87a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,34 @@ Please see [MIGRATING.md](./MIGRATING.md) for information on breaking changes. ### Removed +## [4.0.0] - April + +### Fixed +* Invalid UTF8 strings when transforming json +* Logging raw table name when keep_raw=False + +### Added +* Support for python 3.14 and duckdb 1.14+ +* ldlite_system.load_history_v1 table which tracks useful information about data loads +* Generated columns are now indexed when using duckdb + +### Changed +* [Possibly Breaking] Expanding json now utilizes SQL instead of python +* [Possibly Breaking] Columns have more accurate types + * text -> timestamptz + * numeric -> numeric or bigint or integer +* [Breaking] The connect_db_postgres method now returns a psycopg3 connection +* [Possibly Breaking] `select` method uses duckdb's `show` method +* [Possibly Breaking] `export_csv` method uses duckdb's `COPY TO output.csv` + +### Removed +* [Breaking] Support for dependency versions less than the new minimum version + * Postgres - 14 + * Python - 3.10 + * Duckdb - 1.3 +* [Breaking] experimental_connect_sqlite +* [Breaking] export_excel and to_xlsx + ## [3.2.1] - November 2025 ### Fixed diff --git a/MIGRATING.md b/MIGRATING.md index 3c5454c..151c04c 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -14,6 +14,71 @@ If you'd like support or assistance upgrading please feel free to reach out to l ## Latest Major Release +### 4.0.0 - The "I can't believe that actually worked" Release + +This release is the culmination of much theorizing, experimenting, and testing. +It's impossible to convey how excited I am to finally make this release public! + +Until now, LDLite expanded the dowloaded JSON row by row using Python. +This worked well enough for small tables but performance really broke down for the largest tables. +For example, it took 6 hours each night to transform Five College's Circulation records and over 34 hours each weekend to transform our Instance records. + +4.0.0 has completely rebuilt the transformation logic to utilize SQL native json processing and set-operations. +The transform time is on average 95% faster, for example Circulation now takes 8 minutes and Instances take 1.5 hours. +While performance is not a "feature" in and of itself this change allows for more frequent loads and fresher data. + +Another positive to come from the rebuild is that the transformation code is no longer a scary black box. +Better data type inference has been a common request which was always "technically" possible but difficult to implement and test. +The new transformation logic includes more accurate datatype detection and high-performance conversion in SQL. + +_Another_ positive is that the data is now replaced transactionally. +If LDLite fails to download or transform the existing data will remain in place (freshness can be checked in the ldlite_system.load_history_v1 table). + +SQLite support had to be removed to make this rebuild possible as it wasn't possible to write SQL compatible with all three of postgres, sqlite, and duckdb. +Postgres 14+ and duckdb 1.14+ are now required as they contain features necessary for the rebuild. +These will be supported as long as they are maintained by their respective projects. +One side effect of increasing the minimum duckdb version is that the `select` and `export_csv` methods can now use the built-in functionality. +You will see a change to the output format of both of these methods. + +While not a breaking change, there is one new feature to call out in more detail. +You'll find a new `ldlite_system` schema with a table `load_history_v1` that records runtime information about each load performed. +Please see the README.md file for more documentation on this new table. + +The minimum supported python version is now 3.10, this has been increased from python 3.9 (which became end of life in October 2025). +LDLite will stop supporting python 3.10 when it becames end of life itself in October 2026. + +Lastly, `export_excel` has been removed. + +##### Steps to upgrade from 3.X.X +Please refer to the [official python docs](https://docs.python.org/release/3.10.20/using/index.html) for guidance on installing at least python 3.10. +You can use `python3 --version` to check which version you have currently installed. + +This new release places more load on the Postgres server and less on the server running python. +One "trick" previously used to speed up transformation was to start 4-6 ldlite processes in parallel. +This is no longer necessary and may place too much load on the postgres server if multiple tables are being transformed at once. +If you have the ability, reallocating resources (especially cpu) to the Postgres server is recommended. +The `work_mem` and `max_parallel_workers_per_gather` settings are also worth looking at. +Because of the transactional replacement, you will need enough free disk space on postgres to store an extra copy of the largest tables. +This is probably Instances, for Five Colleges our Instances are ~50gb and require ~80gb of free disk space to transform. + +If you have any issues with the new transform you can pass the `use_legacy_transform` parameter to the query method. +This parameter will stop working in a future major release of LDLite. + +For the most part, the datatype changes should not be breaking but there are scenarios where it can be +* Using `TO_TIMESTAMP(metadata_updated_date, 'YYYY-MM-DDTHH24:MI:SS.MS+OF')` instead of `metadata_updated_date::timestamptz` +* Filtering dates as if they were text + * `WHERE metadata_updated_date LIKE '2026%'` will need to become `WHERE EXTRACT(YEAR FROM metadata_updated_date) = 2026` +* Dividing integer columns by integers + * `request_queue_size / 5` will need to become `request_queue_size::numeric / 5` + +If you were using experimental_connect_sqlite, switch to duckdb and connect_db. +Recent releases of DuckDB are much more stable than in the past when sqlite was provided an alternative. + +If you need excel support you can use the [XlsxWriter python library](https://xlsxwriter.readthedocs.io/). +LDLite can still export csvs using the export_csv method which are openable in excel. + +## Previous Major Releases + ### 3.0.0 - The Prep for Takeoff Release The good: LDLite has been running unchanged in production for multiple years! @@ -38,8 +103,6 @@ When you install ldlite 3.0.0 some of your transient dependencies might automati If you rely on pandas without having a direct dependency on it you may have to re-install it. Please make sure that any code using ldlite as a dependency is tested. -## Previous Major Releases - ### 2.0.0 - The Sunflower Release All deprecated methods on the LDLite object related to okapi are removed. diff --git a/README.md b/README.md index 4a20a4d..5549d36 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,10 @@ provides basic LDP functions without requiring the server to be installed. LDLite supports two modes of usage. -* Ad-hoc uses a local DuckDB to enable downloading small amounts of data and querying using sql. -* Server uses a persistent postgres server and managed cron server to download large amounts of data for analytic processing and reporting. +* Server mode uses a persistent postgres server and managed cron server to download large amounts of data for analytic processing and reporting. +* Ad-hoc mode uses a local DuckDB database to enable downloading small amounts of data and querying using sql. + +Check out the [migration guide](./MIGRATING.md) for more information about major version upgrades. ### Usage with a persistent postgres server @@ -27,21 +29,10 @@ It is recommended to install the `psycopg[c]` package for optimal reliability an To install LDLite or upgrade to the latest version: ```bash -$ python -m pip install --upgrade ldlite +$ python -m pip install --upgrade psycopg[binary] ldlite ``` (On some systems it might be `python3` rather than `python`.) -If you encounter the error `ImportError: no pq wrapper available.` you can either -* Run `python -m pip install psycopg[binary]` -* Ensure the libpq package is installed for your operating system - -Check out the [migration guide](./MIGRATING.md) for more information about major version upgrades. - -*Optional* If you intend to use the `connect_db_postgres()` method install the binary provider: -``` -$ python -m pip install --upgrade psycopg[binary] -``` - To extract and transform data: ```python @@ -99,6 +90,63 @@ Features * Storing the data in an existing LDP database if available * Runs on Windows, macOS, and Linux. +ldlite_system.load_history_v1 +------------- + +Starting with ldlite 4.0 useful information is stored during the loading process. +This table can be exposed directly to end users but it can be overwhelming. +A more useful view of this table can be exposed instead. +```sql +CREATE VIEW public.load_history_dashboard AS +SELECT + table_prefix + ,folio_path + ,COALESCE(query_text, 'cql.allRecords=1') AS query_text + ,final_rowcount AS rowcount + ,pg_size_pretty(SUM(t.table_size)) AS total_size + ,TO_CHAR(data_refresh_start AT TIME ZONE 'America/New_York', 'YYYY/MM/DD HH:MI AM') AS has_all_changes_before + ,TO_CHAR(data_refresh_end AT TIME ZONE 'America/New_York', 'YYYY/MM/DD HH:MI AM') AS has_no_changes_after + ,EXTRACT(EPOCH FROM data_refresh_end) AS refresh_sort + ,SUM(t.table_size) AS size_sort +FROM ldlite_system.load_history_v1 h +CROSS JOIN LATERAL +( + SELECT pg_total_relation_size(t."table_schema" || '.' || t."table_name") AS table_size + FROM INFORMATION_SCHEMA.TABLES t + WHERE + ( + h.table_prefix LIKE '%.%' AND + t.table_schema = SPLIT_PART(h.table_prefix, '.', 1) AND + t.table_name LIKE (SPLIT_PART(h.table_prefix, '.', -1) || '%') + ) OR + ( + h.table_prefix NOT LIKE '%.%' AND + t.table_name LIKE (h.table_prefix || '%') + ) +) t +WHERE final_rowcount IS NOT NULL +GROUP BY 1, 2, 3, 4, 6, 7, 8 +ORDER BY 8 DESC +``` + +When a load starts the table_prefix, folio_path, query_text, and load_start columns are set. +Any existing loads with the same table_prefix will have these values overwritten. + +The download will transactionally replace the existing raw table and set the rowcount and download_complete columns. + +The transformation will transactionally replace the expanded tables. If it fails the existing tables will be retained. +At the end of transformation the final_rowcount and transform_complete columns are set in the same transaction. + +The data_refresh_start and data_refresh_end times require special attention. +These columns get updated when the transformation transaction is committed and represent when the download started and ended. +* Any changes in FOLIO made before data_refresh_start will be reflected in the expanded tables. +* Any changes in FOLIO made after data_refresh_end will not be reflected in the expanded tables. +* Changes made to FOLIO in between the start and end _may_ be reflected :smile_cat:/:scream_cat:. + +Because of the transactional nature, it is very possible to have newer data in the raw table than in the resulting expanded tables. +This can happen during the transformation stage or if the transformation stage fails. +This is indicated by having the data_refresh_start and data_refresh_end columns not match the load_start and download_complete columns. + More examples ------------- From 39bc47b1ce2e864e467d7fd25a2d7d3102ad0d2c Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Wed, 1 Apr 2026 15:15:59 +0000 Subject: [PATCH 24/25] Bump version to 4.0.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 11b2da9..26f791d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "pdm.backend" [project] name = "ldlite" -version = "3.2.1" +version = "4.0.0" description = "Lightweight analytics tool for FOLIO services" authors = [ { name = "Katherine Bargar", email = "kbargar@fivecolleges.edu" }, From da50d09f21a3068bc0703d8ca5d646ab68c36f03 Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Mon, 30 Mar 2026 13:47:04 +0000 Subject: [PATCH 25/25] Utilize scale for finding floats like 10.0 --- src/ldlite/database/_duckdb.py | 9 +++- src/ldlite/database/_expansion/fixed_nodes.py | 2 +- tests/test_json_operators.py | 52 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/ldlite/database/_duckdb.py b/src/ldlite/database/_duckdb.py index f4268ea..4a1c68f 100644 --- a/src/ldlite/database/_duckdb.py +++ b/src/ldlite/database/_duckdb.py @@ -47,7 +47,14 @@ def __init__(self, db: duckdb.DuckDBPyConnection) -> None: CREATE OR REPLACE FUNCTION jsonb_each(j) AS TABLE ( SELECT key, value, rowid AS "ordinality" FROM main.json_each(j) -) +); + +CREATE OR REPLACE FUNCTION scale(n) AS ( + CASE + WHEN n = n::bigint THEN 0 + ELSE 1 + END +); """, ) diff --git a/src/ldlite/database/_expansion/fixed_nodes.py b/src/ldlite/database/_expansion/fixed_nodes.py index 3dbb505..7758a8f 100644 --- a/src/ldlite/database/_expansion/fixed_nodes.py +++ b/src/ldlite/database/_expansion/fixed_nodes.py @@ -137,7 +137,7 @@ def specify_type(self, conn: Conn) -> None: SELECT 1 FROM string_values WHERE string_value IS NOT NULL AND - string_value::numeric % 1 <> 0 + SCALE(string_value::numeric) > 0 ) AS is_float ,EXISTS( SELECT 1 FROM string_values diff --git a/tests/test_json_operators.py b/tests/test_json_operators.py index 75a2672..686b8f5 100644 --- a/tests/test_json_operators.py +++ b/tests/test_json_operators.py @@ -70,6 +70,57 @@ def case_jsonb_typeof(p: tuple[Any, ...]) -> JsonTC: ) +@parametrize( + p=[ + ("1", False), + ("1.2", True), + ("0.03", True), + ], +) +def case_scale(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT (SCALE($1::numeric){assertion}) +FROM j;""", + p[:1], + """ > 0) = $2 AND (TRUE""", + p[1:], + ) + + +@parametrize( + p=[ + ("10.0", True), + ], +) +def case_whole_scale_postgres(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT (SCALE($1::numeric){assertion}) +FROM j;""", + p[:1], + """ > 0) = $2 AND (TRUE""", + p[1:], + ) + + +# duckdb has no problems casting 10.0 to an integer +@parametrize( + p=[ + ("10.0", False), + ], +) +def case_whole_scale_duckdb(p: tuple[Any, ...]) -> JsonTC: + return JsonTC( + """ +SELECT (SCALE($1::numeric){assertion}) +FROM j;""", + p[:1], + """ > 0) = $2 AND (TRUE""", + p[1:], + ) + + @parametrize( p=[ ("arr_str", ['"s1"', '"s2"', '"s3"']), @@ -127,6 +178,7 @@ def _arrange(conn: "dbapi.DBAPIConnection") -> None: "str": "str_val", "num": 12, "float": 16.3, + "evenfloat": 10.0, "bigint": 2147483648, "bigfloat": 2147483648.1, "bool": true,