diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6fd0448..41150bd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: verbose: true files: ^db\.py|README\.md$ - - rev: v0.5.5 + - rev: v0.6.1 repo: https://github.com/astral-sh/ruff-pre-commit hooks: - id: ruff diff --git a/README.md b/README.md index e0d8af2..627bcce 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,11 @@ PDM and Poetry plugin to sync your pre-commit versions with your lockfile and au ## Features -- 🔁 Sync pre-commit versions with your lockfile +- 🔁 Sync pre-commit versions (including `additional_dependencies`) with your lockfile - ⏩ Run every time you run the lockfile is updated, not as a pre-commit hook - 🔄 Install pre-commit hooks automatically, no need to run `pre-commit install` manually - 💫 Preserve your pre-commit config file formatting -- 🍃 Lightweight, only depends on [strictyaml](https://pypi.org/project/strictyaml/) +- 🍃 Lightweight, only depends on [strictyaml](https://pypi.org/project/strictyaml/) and [packaging](https://pypi.org/project/packaging/) ## Supported versions @@ -163,13 +163,15 @@ Feel free to open an issue or a PR if you have any idea, or if you want to help! - [ ] Create a more verbose command - [ ] Add support for other lockfiles / project managers (pipenv, flit, hatch, etc.) - [ ] Expose a pre-commit hook to sync the lockfile -- [ ] Support nested params for some repos? Like mypy types +- [x] Support nested `additional_dependencies`, (ie. mypy types) - [ ] Support reading DB from a Python module? - [ ] Support reordering DB inputs (file/global config/python module/cli)? - [ ] Test using SSH/file dependencies? - [ ] Check ref existence before writing? - [ ] New feature to convert from pre-commit online to local? - [ ] Warning if pre-commit CI auto update is also set? +- [ ] Support automatic repository URL update (from legacy aliased repositories) + ## Inspiration diff --git a/pdm.lock b/pdm.lock index e34843e..8ed68c5 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev", "pdm", "poetry", "testtox"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:5167531d46e4595b957439daa527d33fdf442880c2a31a2cec9d389b48ec36a5" +content_hash = "sha256:705fad710411ae682de6161b37377ec61d4f41443efd2f946c6dadde9987eda3" [[metadata.targets]] requires_python = ">=3.9" @@ -89,13 +89,13 @@ files = [ [[package]] name = "cachetools" -version = "5.4.0" +version = "5.5.0" requires_python = ">=3.7" summary = "Extensible memoizing collections and decorators" groups = ["dev"] files = [ - {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, - {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] @@ -111,7 +111,7 @@ files = [ [[package]] name = "cffi" -version = "1.16.0" +version = "1.17.0" requires_python = ">=3.8" summary = "Foreign Function Interface for Python calling C code." groups = ["poetry"] @@ -120,50 +120,65 @@ dependencies = [ "pycparser", ] files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, + {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, + {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, + {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, + {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, + {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, + {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, + {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, + {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, + {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, + {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, + {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, ] [[package]] @@ -287,109 +302,149 @@ files = [ [[package]] name = "coverage" -version = "7.6.0" +version = "7.6.1" requires_python = ">=3.8" summary = "Code coverage measurement for Python" groups = ["dev", "testtox"] files = [ - {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, - {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, - {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, - {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, - {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, - {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, - {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, - {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, - {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, - {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, - {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, - {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, ] [[package]] name = "coverage" -version = "7.6.0" +version = "7.6.1" extras = ["toml"] requires_python = ">=3.8" summary = "Code coverage measurement for Python" groups = ["dev", "testtox"] dependencies = [ - "coverage==7.6.0", + "coverage==7.6.1", "tomli; python_full_version <= \"3.11.0a6\"", ] files = [ - {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, - {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, - {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, - {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, - {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, - {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, - {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, - {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, - {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, - {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, - {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, - {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, ] [[package]] @@ -782,13 +837,13 @@ files = [ [[package]] name = "more-itertools" -version = "10.3.0" +version = "10.4.0" requires_python = ">=3.8" summary = "More routines for operating on iterables, beyond itertools" groups = ["poetry"] files = [ - {file = "more-itertools-10.3.0.tar.gz", hash = "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463"}, - {file = "more_itertools-10.3.0-py3-none-any.whl", hash = "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320"}, + {file = "more-itertools-10.4.0.tar.gz", hash = "sha256:fe0e63c4ab068eac62410ab05cccca2dc71ec44ba8ef29916a0090df061cf923"}, + {file = "more_itertools-10.4.0-py3-none-any.whl", hash = "sha256:0f7d9f83a0a8dcfa8a2694a770590d98a67ea943e3d9f5298309a484758c4e27"}, ] [[package]] @@ -908,7 +963,7 @@ name = "packaging" version = "24.1" requires_python = ">=3.8" summary = "Core utilities for Python packages" -groups = ["dev", "pdm", "poetry", "testtox"] +groups = ["default", "dev", "pdm", "poetry", "testtox"] files = [ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, @@ -916,18 +971,18 @@ files = [ [[package]] name = "pbs-installer" -version = "2024.4.24" +version = "2024.8.14" requires_python = ">=3.8" summary = "Installer for Python Build Standalone" groups = ["pdm"] files = [ - {file = "pbs_installer-2024.4.24-py3-none-any.whl", hash = "sha256:f8291f0231003d279d0de8fde88fa87b7c6d7fabc2671235113cf67513ff74f5"}, - {file = "pbs_installer-2024.4.24.tar.gz", hash = "sha256:19224733068b0ffa39b53afbb61544bee8ecb9503e7222ba034f07b9913e2c1c"}, + {file = "pbs_installer-2024.8.14-py3-none-any.whl", hash = "sha256:9ec0c1e689fc956823d45952eb0879c303f411d8f9f315b06ef57138cc794285"}, + {file = "pbs_installer-2024.8.14.tar.gz", hash = "sha256:40144b21f04e90c73f1b79601e139d56d540356630fe473842ea439a59dffaee"}, ] [[package]] name = "pdm" -version = "2.17.3" +version = "2.18.1" requires_python = ">=3.8" summary = "A modern Python package and dependency manager supporting the latest PEP standards" groups = ["pdm"] @@ -953,12 +1008,12 @@ dependencies = [ "tomli>=1.1.0; python_version < \"3.11\"", "tomlkit<1,>=0.11.1", "truststore; python_version >= \"3.10\"", - "unearth>=0.16.0", + "unearth>=0.17.0", "virtualenv>=20", ] files = [ - {file = "pdm-2.17.3-py3-none-any.whl", hash = "sha256:3cc0fab468d68ce9c52ce1f2f2270ecb5396b23f17be4ac048ca901be88b15f1"}, - {file = "pdm-2.17.3.tar.gz", hash = "sha256:f49220f225ec71258cbf7148b14a76caeac612745bedab67f9062398ea56a7a5"}, + {file = "pdm-2.18.1-py3-none-any.whl", hash = "sha256:6a86b9a6fbe071dc26f266006ac8d688e8d16e5115ee115135713af95a860c0a"}, + {file = "pdm-2.18.1.tar.gz", hash = "sha256:acef692477a7190731ee7c1f626e97516eeb7473e4eeeeede4fef2bf0fb743ee"}, ] [[package]] @@ -1222,137 +1277,166 @@ files = [ [[package]] name = "pywin32-ctypes" -version = "0.2.2" +version = "0.2.3" requires_python = ">=3.6" summary = "A (partial) reimplementation of pywin32 using ctypes/cffi" groups = ["poetry"] marker = "sys_platform == \"win32\"" files = [ - {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"}, - {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"}, + {file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"}, + {file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"}, ] [[package]] name = "pyyaml" -version = "6.0.1" -requires_python = ">=3.6" +version = "6.0.2" +requires_python = ">=3.8" summary = "YAML parser and emitter for Python" groups = ["dev", "testtox"] files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] name = "rapidfuzz" -version = "3.9.5" +version = "3.9.6" requires_python = ">=3.8" summary = "rapid fuzzy string matching" groups = ["poetry"] files = [ - {file = "rapidfuzz-3.9.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7659058863d84a2c36c5a76c28bc8713d33eab03e677e67260d9e1cca43fc3bb"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:802a018776bd3cb7c5d23ba38ebbb1663a9f742be1d58e73b62d8c7cace6e607"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da71e8fdb0d1a21f4b58b2c84bcbc2b89a472c073c5f7bdb9339f4cb3122c0e3"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9433cb12731167b358fbcff9828d2294429986a03222031f6d14308eb643c77"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e33e1d185206730b916b3e7d9bce1941c65b2a1488cdd0457ae21be385a7912"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:758719e9613c47a274768f1926460955223fe0a03e7eda264f2b78b1b97a4743"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7981cc6240d01d4480795d758ea2ee748257771f68127d630045e58fe1b5545a"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b6cdca86120c3f9aa069f8d4e1c5422e92f833d705d719a2ba7082412f4c933b"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ffa533acb1a9dcb6e26c4467fdc1347995fb168ec9f794b97545f6b72dee733c"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:13eeaeb0d5fe00fa99336f73fb5ab65c46109c7121cf87659b9601908b8b6178"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d7b1922b1403ccb3583218e8cd931b08e04c5442ca03dbaf6ea4fcf574ee2b24"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b0189f691cea4dc9fe074ea6b97da30a91d0882fa69724b4b34b51d2c1983473"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-win32.whl", hash = "sha256:72e466e5de12a327a09ed6d0116f024759b5146b335645c32241da84134a7f34"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:345011cfcafaa3674c46673baad67d2394eb58285530d8333e65c3c9a143b4f4"}, - {file = "rapidfuzz-3.9.5-cp310-cp310-win_arm64.whl", hash = "sha256:5dc19c8222475e4f7f528b94d2fa28e7979355c5cf7c6e73902d2abb2be96522"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c741972d64031535cfd76d89cf47259e590e822353be57ec2f5d56758c98296"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7452d079800cf70a7314f73044f03cbcbd90a651d9dec39443d2a8a2b63ab53"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f06f163a0341bad162e972590b73e17f9cea2ed8ee27b193875ccbc3dd6eca2f"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:529e2cf441746bd492f6c36a38bf9fa6a418df95b9c003f8e92a55d8a979bd9c"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9811a741aa1350ad36689d675ded8b34e423e68b396bd30bff751a9c582f586e"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e36c4640a789b8c922b69a548968939d1c0433fa7aac83cb08e1334d4e5d7de"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53fb2f32f14c921d2f673c5b7cd58d4cc626c574a28c0791f283880d8e57022c"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:031806eb035a6f09f4ff23b9d971d50b30b5e93aa3ee620c920bee1dc32827e7"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f6dbe1df0b9334e3cf07445d810c81734ae23d137b5efc69e1d676ff55691351"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:24345826b50aafcea26e2e4be5c103d96fe9d7fc549ac9190641300290958f3b"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bfd3b66ee1f0ebb40c672a7a7e5bda00fb763fa9bca082058084175151f8e685"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a6f1df5b0e602e94199cccb5e241bbc2319644003e34f077741ebf48aea7ed1a"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-win32.whl", hash = "sha256:f080d6709f51a8335e73826b96af9b4e3657631eca6c69e1ac501868dcc84b7f"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:bf9ed6988da6a2c1f8df367cb5d6be26a3d8543646c8eba79741ac9e764fbc59"}, - {file = "rapidfuzz-3.9.5-cp311-cp311-win_arm64.whl", hash = "sha256:599714790dfac0a23a473134e6677d0a103690a4e21ba189cfc826e322cdc8d5"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9729852038fb2de096e249899f8a9bee90fb1f92e10b6ccc539d5bb798c703bc"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9dc39435476fb3b3b3c24ab2c08c726056b2b487aa7ee450aee698b808c808ac"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6ceea632b0eb97dac54411c29feb190054e91fd0571f585b56e4a9159c55ab0"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cadd66e6ef9901909dc1b11db91048f1bf4613ba7d773386f922e28b1e1df4da"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63e34fb3586431589a5e1cd7fc61c6f057576c6c6804c1c673bac3de0516dee7"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:181073256faec68e6b8ab3329a36cfa1360f7906aa70d9aee4a39cb70889f73f"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8419c18bbbd67058ca1312f35acda2e4e4592650f105cfd166569a2ebccd01f1"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191d1057cca56641f7b919fe712cb7e48cd226342e097a78136127f8bde32caa"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fe5a11eefd0ae90d32d9ff706a894498b4efb4b0c263ad9d1e6401050863504d"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b024d9d69bb83e125adee4162991f2764f16acc3fb1ed0f0fc1ad5aeb7e394"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d5a34b8388ae99bdbd5a3646f45ac318f4c870105bdbe42a2f4c85e5b347761"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e09abc0d397019bba61c8e6dfe2ec863d4dfb1762f51c9197ce0af5d5fd9adb"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-win32.whl", hash = "sha256:e3c4be3057472c79ba6f4eab35daa9f12908cb697c472d05fbbd47949a87aec6"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:0d9fdb74df87018dd4146f3d00df9fca2c27f060936a9e8d3015e7bfb9cb69e4"}, - {file = "rapidfuzz-3.9.5-cp312-cp312-win_arm64.whl", hash = "sha256:491d3d425b5fe3f61f3b9a70abfd498ce9139d94956db7a8551e537e017c0e57"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14587df847d0d50bd10cde0a198b5d64eedb7484c72b825f5c2ead6e6ff16eee"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fd94d952299ec73ea63a0fa4b699a2750785b6bb82aa56fd886d9023b86f90ab"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:733bf3d7876bf6d8167e6436f99d6ea16a218ec2c8eb9da6048f20b9cc8733e2"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb28f2b7173ed3678b4630b0c8b21503087d1cd082bae200dc2519ca38b26686"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a4c8a2c5ae4b133fec6b5db1af9a4126ffa6eca18a558fe5b6ab8e330d3d78"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5feb75e905281e5c669e21c98d594acc3b222a8694d9342f17df988766d83748"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d047b01637a31d9bf776b66438f574fd1db856ad14cf296c1f48bb6bef8a5aff"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9e0a656274ac75ec24499a06c0bc5eee67bcd8276c6061da7c05d549f1b1a61"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:16c982dd3cdd33cf4aac91027a263a081d1a8050dc33a27470367a391a8d1576"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:9a0c878d0980508e90e973a9cbfb591acc370085f2301c6aacadbd8362d52a36"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1d9bcfec5efd55b6268328cccd12956d833582d8da6385231a5c6c6201a1156a"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8171fc6e4645e636161a9ef5b44b20605adbefe23cd990b68d72cae0b9c12509"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-win32.whl", hash = "sha256:35088e759b083398ab3c4154517476e116653b7403604677af9a894179f1042f"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:6d8cc7e6e5c6fbcacdfe3cf7a86b60dcaf216216d86e6879ff52d488e5b11e27"}, - {file = "rapidfuzz-3.9.5-cp39-cp39-win_arm64.whl", hash = "sha256:506547889f18db0acca787ffb9f287757cbfe9f0fadddd4e07c64ce0bd924e13"}, - {file = "rapidfuzz-3.9.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f4e0122603af2119579e9f94e172c6e460860fdcdb713164332c1951c13df999"}, - {file = "rapidfuzz-3.9.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:e46cd486289d1d8e3dab779c725f5dde77b286185d32e7b874bfc3d161e3a927"}, - {file = "rapidfuzz-3.9.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e2c0c8bbe4f4525009e3ad9b94a39cdff5d6378233e754d0b13c29cdfaa75fc"}, - {file = "rapidfuzz-3.9.5-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb47513a17c935f6ee606dcae0ea9d20a3fb0fe9ca597758472ea08be62dc54"}, - {file = "rapidfuzz-3.9.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:976ed1105a76935b6a4d2bbc7d577be1b97b43997bcec2f29a0ab48ff6f5d6b1"}, - {file = "rapidfuzz-3.9.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9cf2028edb9ccd21d1d5aaacef2fe3e14bee4343df1c2c0f7373ef6e81013bef"}, - {file = "rapidfuzz-3.9.5-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2b17ecc17322b659962234799e90054e420911b8ca510a7869c2f4419f9f3ecb"}, - {file = "rapidfuzz-3.9.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f3e037b9ec621dec0157d81566e7d47a91405e379335cf8f4ed3c20d61db91d8"}, - {file = "rapidfuzz-3.9.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c4d1ba2647c8d2a82313c4dde332de750c936b94f016308339e762c2e5e53d"}, - {file = "rapidfuzz-3.9.5-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:876e663b11d9067e1096ea76a2de87227c7b513aff2b60667b20417da74183e4"}, - {file = "rapidfuzz-3.9.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adee55488490375c1604b878fbc1eb1a51fe5e6f5bd05047df2f8c6505a48728"}, - {file = "rapidfuzz-3.9.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:abb1ac683671000bd4ec215a494aba687d75a198db72188408154a19ea313ff4"}, - {file = "rapidfuzz-3.9.5.tar.gz", hash = "sha256:257f2406a671371bafd99a2a2c57f991783446bc2176b93a83d1d833e35d36df"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7ed0d0b9c85720f0ae33ac5efc8dc3f60c1489dad5c29d735fbdf2f66f0431f"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f3deff6ab7017ed21b9aec5874a07ad13e6b2a688af055837f88b743c7bfd947"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3f9fc060160507b2704f7d1491bd58453d69689b580cbc85289335b14fe8ca"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e86c2b3827fa6169ad6e7d4b790ce02a20acefb8b78d92fa4249589bbc7a2c"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f982e1aafb4bd8207a5e073b1efef9e68a984e91330e1bbf364f9ed157ed83f0"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9196a51d0ec5eaaaf5bca54a85b7b1e666fc944c332f68e6427503af9fb8c49e"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb5a514064e02585b1cc09da2fe406a6dc1a7e5f3e92dd4f27c53e5f1465ec81"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e3a4244f65dbc3580b1275480118c3763f9dc29fc3dd96610560cb5e140a4d4a"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f6ebb910a702e41641e1e1dada3843bc11ba9107a33c98daef6945a885a40a07"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:624fbe96115fb39addafa288d583b5493bc76dab1d34d0ebba9987d6871afdf9"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1c59f1c1507b7a557cf3c410c76e91f097460da7d97e51c985343798e9df7a3c"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f6f0256cb27b6a0fb2e1918477d1b56473cd04acfa245376a342e7c15806a396"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-win32.whl", hash = "sha256:24d473d00d23a30a85802b502b417a7f5126019c3beec91a6739fe7b95388b24"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:248f6d2612e661e2b5f9a22bbd5862a1600e720da7bb6ad8a55bb1548cdfa423"}, + {file = "rapidfuzz-3.9.6-cp310-cp310-win_arm64.whl", hash = "sha256:e03fdf0e74f346ed7e798135df5f2a0fb8d6b96582b00ebef202dcf2171e1d1d"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:52e4675f642fbc85632f691b67115a243cd4d2a47bdcc4a3d9a79e784518ff97"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1f93a2f13038700bd245b927c46a2017db3dcd4d4ff94687d74b5123689b873b"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b70500bca460264b8141d8040caee22e9cf0418c5388104ff0c73fb69ee28f"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1e037fb89f714a220f68f902fc6300ab7a33349f3ce8ffae668c3b3a40b0b06"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6792f66d59b86ccfad5e247f2912e255c85c575789acdbad8e7f561412ffed8a"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68d9cffe710b67f1969cf996983608cee4490521d96ea91d16bd7ea5dc80ea98"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63daaeeea76da17fa0bbe7fb05cba8ed8064bb1a0edf8360636557f8b6511961"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d214e063bffa13e3b771520b74f674b22d309b5720d4df9918ff3e0c0f037720"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ed443a2062460f44c0346cb9d269b586496b808c2419bbd6057f54061c9b9c75"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5b0c9b227ee0076fb2d58301c505bb837a290ae99ee628beacdb719f0626d749"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:82c9722b7dfaa71e8b61f8c89fed0482567fb69178e139fe4151fc71ed7df782"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c18897c95c0a288347e29537b63608a8f63a5c3cb6da258ac46fcf89155e723e"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-win32.whl", hash = "sha256:3e910cf08944da381159587709daaad9e59d8ff7bca1f788d15928f3c3d49c2a"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:59c4a61fab676d37329fc3a671618a461bfeef53a4d0b8b12e3bc24a14e166f8"}, + {file = "rapidfuzz-3.9.6-cp311-cp311-win_arm64.whl", hash = "sha256:8b4afea244102332973377fddbe54ce844d0916e1c67a5123432291717f32ffa"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:70591b28b218fff351b88cdd7f2359a01a71f9f7f5a2e465ce3715ed4b3c422b"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee2d8355c7343c631a03e57540ea06e8717c19ecf5ff64ea07e0498f7f161457"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:708fb675de0f47b9635d1cc6fbbf80d52cb710d0a1abbfae5c84c46e3abbddc3"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d66c247c2d3bb7a9b60567c395a15a929d0ebcc5f4ceedb55bfa202c38c6e0c"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15146301b32e6e3d2b7e8146db1a26747919d8b13690c7f83a4cb5dc111b3a08"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7a03da59b6c7c97e657dd5cd4bcaab5fe4a2affd8193958d6f4d938bee36679"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d2c2fe19e392dbc22695b6c3b2510527e2b774647e79936bbde49db7742d6f1"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:91aaee4c94cb45930684f583ffc4e7c01a52b46610971cede33586cf8a04a12e"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3f5702828c10768f9281180a7ff8597da1e5002803e1304e9519dd0f06d79a85"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ccd1763b608fb4629a0b08f00b3c099d6395e67c14e619f6341b2c8429c2f310"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc7a0d4b2cb166bc46d02c8c9f7551cde8e2f3c9789df3827309433ee9771163"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7496f53d40560a58964207b52586783633f371683834a8f719d6d965d223a2eb"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-win32.whl", hash = "sha256:5eb1a9272ca71bc72be5415c2fa8448a6302ea4578e181bb7da9db855b367df0"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-win_amd64.whl", hash = "sha256:0d21fc3c0ca507a1180152a6dbd129ebaef48facde3f943db5c1055b6e6be56a"}, + {file = "rapidfuzz-3.9.6-cp312-cp312-win_arm64.whl", hash = "sha256:43bb27a57c29dc5fa754496ba6a1a508480d21ae99ac0d19597646c16407e9f3"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:83a5ac6547a9d6eedaa212975cb8f2ce2aa07e6e30833b40e54a52b9f9999aa4"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:10f06139142ecde67078ebc9a745965446132b998f9feebffd71acdf218acfcc"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74720c3f24597f76c7c3e2c4abdff55f1664f4766ff5b28aeaa689f8ffba5fab"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2bce52b5c150878e558a0418c2b637fb3dbb6eb38e4eb27d24aa839920483e"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1611199f178793ca9a060c99b284e11f6d7d124998191f1cace9a0245334d219"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0308b2ad161daf502908a6e21a57c78ded0258eba9a8f5e2545e2dafca312507"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eda91832201b86e3b70835f91522587725bec329ec68f2f7faf5124091e5ca7"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ece873c093aedd87fc07c2a7e333d52e458dc177016afa1edaf157e82b6914d8"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d97d3c9d209d5c30172baea5966f2129e8a198fec4a1aeb2f92abb6e82a2edb1"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6c4550d0db4931f5ebe9f0678916d1b06f06f5a99ba0b8a48b9457fd8959a7d4"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b6b8dd4af6324fc325d9483bec75ecf9be33e590928c9202d408e4eafff6a0a6"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16122ae448bc89e2bea9d81ce6cb0f751e4e07da39bd1e70b95cae2493857853"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-win32.whl", hash = "sha256:71cc168c305a4445109cd0d4925406f6e66bcb48fde99a1835387c58af4ecfe9"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-win_amd64.whl", hash = "sha256:59ee78f2ecd53fef8454909cda7400fe2cfcd820f62b8a5d4dfe930102268054"}, + {file = "rapidfuzz-3.9.6-cp313-cp313-win_arm64.whl", hash = "sha256:58b4ce83f223605c358ae37e7a2d19a41b96aa65b1fede99cc664c9053af89ac"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:efa674b407424553024522159296690d99d6e6b1192cafe99ca84592faff16b4"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0b40ff76ee19b03ebf10a0a87938f86814996a822786c41c3312d251b7927849"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16a6c7997cb5927ced6f617122eb116ba514ec6b6f60f4803e7925ef55158891"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3f42504bdc8d770987fc3d99964766d42b2a03e4d5b0f891decdd256236bae0"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9462aa2be9f60b540c19a083471fdf28e7cf6434f068b631525b5e6251b35e"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1629698e68f47609a73bf9e73a6da3a4cac20bc710529215cbdf111ab603665b"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68bc7621843d8e9a7fd1b1a32729465bf94b47b6fb307d906da168413331f8d6"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c6254c50f15bc2fcc33cb93a95a81b702d9e6590f432a7f7822b8c7aba9ae288"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:7e535a114fa575bc143e175e4ca386a467ec8c42909eff500f5f0f13dc84e3e0"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d50acc0e9d67e4ba7a004a14c42d1b1e8b6ca1c515692746f4f8e7948c673167"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fa742ec60bec53c5a211632cf1d31b9eb5a3c80f1371a46a23ac25a1fa2ab209"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c256fa95d29cbe5aa717db790b231a9a5b49e5983d50dc9df29d364a1db5e35b"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-win32.whl", hash = "sha256:89acbf728b764421036c173a10ada436ecca22999851cdc01d0aa904c70d362d"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:c608fcba8b14d86c04cb56b203fed31a96e8a1ebb4ce99e7b70313c5bf8cf497"}, + {file = "rapidfuzz-3.9.6-cp39-cp39-win_arm64.whl", hash = "sha256:d41c00ded0e22e9dba88ff23ebe0dc9d2a5f21ba2f88e185ea7374461e61daa9"}, + {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a65c2f63218ea2dedd56fc56361035e189ca123bd9c9ce63a9bef6f99540d681"}, + {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:680dc78a5f889d3b89f74824b89fe357f49f88ad10d2c121e9c3ad37bac1e4eb"}, + {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8ca862927a0b05bd825e46ddf82d0724ea44b07d898ef639386530bf9b40f15"}, + {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2116fa1fbff21fa52cd46f3cfcb1e193ba1d65d81f8b6e123193451cd3d6c15e"}, + {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dcb7d9afd740370a897c15da61d3d57a8d54738d7c764a99cedb5f746d6a003"}, + {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1a5bd6401bb489e14cbb5981c378d53ede850b7cc84b2464cad606149cc4e17d"}, + {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9e53c72d08f0e9c6e4a369e52df5971f311305b4487690c62e8dd0846770260c"}, + {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a0cb157162f0cdd62e538c7bd298ff669847fc43a96422811d5ab933f4c16c3a"}, + {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bb5ff2bd48132ed5e7fbb8f619885facb2e023759f2519a448b2c18afe07e5d"}, + {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6dc37f601865e8407e3a8037ffbc3afe0b0f837b2146f7632bd29d087385babe"}, + {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a657eee4b94668faf1fa2703bdd803654303f7e468eb9ba10a664d867ed9e779"}, + {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:51be6ab5b1d5bb32abd39718f2a5e3835502e026a8272d139ead295c224a6f5e"}, + {file = "rapidfuzz-3.9.6.tar.gz", hash = "sha256:5cf2a7d621e4515fee84722e93563bf77ff2cbe832a77a48b81f88f9e23b9e8d"}, ] [[package]] @@ -1414,29 +1498,29 @@ files = [ [[package]] name = "ruff" -version = "0.5.5" +version = "0.6.1" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.5.5-py3-none-linux_armv6l.whl", hash = "sha256:605d589ec35d1da9213a9d4d7e7a9c761d90bba78fc8790d1c5e65026c1b9eaf"}, - {file = "ruff-0.5.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00817603822a3e42b80f7c3298c8269e09f889ee94640cd1fc7f9329788d7bf8"}, - {file = "ruff-0.5.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:187a60f555e9f865a2ff2c6984b9afeffa7158ba6e1eab56cb830404c942b0f3"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe26fc46fa8c6e0ae3f47ddccfbb136253c831c3289bba044befe68f467bfb16"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad25dd9c5faac95c8e9efb13e15803cd8bbf7f4600645a60ffe17c73f60779b"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f70737c157d7edf749bcb952d13854e8f745cec695a01bdc6e29c29c288fc36e"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:cfd7de17cef6ab559e9f5ab859f0d3296393bc78f69030967ca4d87a541b97a0"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a09b43e02f76ac0145f86a08e045e2ea452066f7ba064fd6b0cdccb486f7c3e7"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0b856cb19c60cd40198be5d8d4b556228e3dcd545b4f423d1ad812bfdca5884"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3687d002f911e8a5faf977e619a034d159a8373514a587249cc00f211c67a091"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ac9dc814e510436e30d0ba535f435a7f3dc97f895f844f5b3f347ec8c228a523"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:af9bdf6c389b5add40d89b201425b531e0a5cceb3cfdcc69f04d3d531c6be74f"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d40a8533ed545390ef8315b8e25c4bb85739b90bd0f3fe1280a29ae364cc55d8"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cab904683bf9e2ecbbe9ff235bfe056f0eba754d0168ad5407832928d579e7ab"}, - {file = "ruff-0.5.5-py3-none-win32.whl", hash = "sha256:696f18463b47a94575db635ebb4c178188645636f05e934fdf361b74edf1bb2d"}, - {file = "ruff-0.5.5-py3-none-win_amd64.whl", hash = "sha256:50f36d77f52d4c9c2f1361ccbfbd09099a1b2ea5d2b2222c586ab08885cf3445"}, - {file = "ruff-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3191317d967af701f1b73a31ed5788795936e423b7acce82a2b63e26eb3e89d6"}, - {file = "ruff-0.5.5.tar.gz", hash = "sha256:cc5516bdb4858d972fbc31d246bdb390eab8df1a26e2353be2dbc0c2d7f5421a"}, + {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, + {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, + {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, + {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, + {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, + {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, + {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, ] [[package]] @@ -1526,23 +1610,23 @@ files = [ [[package]] name = "tomlkit" -version = "0.13.0" +version = "0.13.2" requires_python = ">=3.8" summary = "Style preserving TOML library" groups = ["pdm", "poetry"] files = [ - {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, - {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] [[package]] name = "tox" -version = "4.16.0" +version = "4.18.0" requires_python = ">=3.8" summary = "tox is a generic virtualenv management and test command line tool" groups = ["dev"] dependencies = [ - "cachetools>=5.3.3", + "cachetools>=5.4", "chardet>=5.2", "colorama>=0.4.6", "filelock>=3.15.4", @@ -1554,8 +1638,8 @@ dependencies = [ "virtualenv>=20.26.3", ] files = [ - {file = "tox-4.16.0-py3-none-any.whl", hash = "sha256:61e101061b977b46cf00093d4319438055290ad0009f84497a07bf2d2d7a06d0"}, - {file = "tox-4.16.0.tar.gz", hash = "sha256:43499656f9949edb681c0f907f86fbfee98677af9919d8b11ae5ad77cb800748"}, + {file = "tox-4.18.0-py3-none-any.whl", hash = "sha256:0a457400cf70615dc0627eb70d293e80cd95d8ce174bb40ac011011f0c03a249"}, + {file = "tox-4.18.0.tar.gz", hash = "sha256:5dfa1cab9f146becd6e351333a82f9e0ade374451630ba65ee54584624c27b58"}, ] [[package]] @@ -1589,20 +1673,20 @@ files = [ [[package]] name = "tox-uv" -version = "1.11.0" +version = "1.11.2" requires_python = ">=3.8" summary = "Integration of uv with tox." groups = ["dev"] dependencies = [ "importlib-resources>=6.4; python_version < \"3.9\"", - "packaging>=24", - "tox<5,>=4.15", + "packaging>=24.1", + "tox<5,>=4.18", "typing-extensions>=4.12.2; python_version < \"3.10\"", - "uv<1,>=0.2.5", + "uv<1,>=0.2.35", ] files = [ - {file = "tox_uv-1.11.0-py3-none-any.whl", hash = "sha256:22c9d36fdc65f8a2a4001174aa02017bb82dde9ef88a243a4a2f4241c9fe1e78"}, - {file = "tox_uv-1.11.0.tar.gz", hash = "sha256:00c6193af6b4ae567a21a98eb7540673e1a8709902e0266c3c9a627758250215"}, + {file = "tox_uv-1.11.2-py3-none-any.whl", hash = "sha256:7f8f1737b3277e1cddcb5b89fcc5931d04923562c940ae60f29e140908566df2"}, + {file = "tox_uv-1.11.2.tar.gz", hash = "sha256:a7aded5c3fb69f055b523357988c1055bb573e91bfd7ecfb9b5233ebcab5d10b"}, ] [[package]] @@ -1629,13 +1713,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20240724" +version = "6.0.12.20240808" requires_python = ">=3.8" summary = "Typing stubs for PyYAML" groups = ["dev"] files = [ - {file = "types-PyYAML-6.0.12.20240724.tar.gz", hash = "sha256:cf7b31ae67e0c5b2919c703d2affc415485099d3fe6666a6912f040fd05cb67f"}, - {file = "types_PyYAML-6.0.12.20240724-py3-none-any.whl", hash = "sha256:e5becec598f3aa3a2ddf671de4a75fa1c6856fbf73b2840286c9d50fae2d5d48"}, + {file = "types-PyYAML-6.0.12.20240808.tar.gz", hash = "sha256:b8f76ddbd7f65440a8bda5526a9607e4c7a322dc2f8e1a8c405644f9a6f4b9af"}, + {file = "types_PyYAML-6.0.12.20240808-py3-none-any.whl", hash = "sha256:deda34c5c655265fc517b546c902aa6eed2ef8d3e921e4765fe606fe2afe8d35"}, ] [[package]] @@ -1651,7 +1735,7 @@ files = [ [[package]] name = "unearth" -version = "0.16.1" +version = "0.17.0" requires_python = ">=3.8" summary = "A utility to fetch and download python packages" groups = ["pdm"] @@ -1660,8 +1744,8 @@ dependencies = [ "packaging>=20", ] files = [ - {file = "unearth-0.16.1-py3-none-any.whl", hash = "sha256:5a598ac1a3f185144fadc9de47f1043bff805c36118ffc40f81ef98ff22e8e37"}, - {file = "unearth-0.16.1.tar.gz", hash = "sha256:988a43418fa0b78aeb628a15f6a3b02152c1787f63fe6d254c7f4e2ccf8db0a7"}, + {file = "unearth-0.17.0-py3-none-any.whl", hash = "sha256:81c2f1fad5bb0065371df221934c3cae22dc7526c9606ec83fb3405c3acfd5e6"}, + {file = "unearth-0.17.0.tar.gz", hash = "sha256:771ca270fec8bea262774a0b1ce2752739056e65234434028eceaf466cbba0b6"}, ] [[package]] @@ -1677,29 +1761,29 @@ files = [ [[package]] name = "uv" -version = "0.2.32" +version = "0.2.37" requires_python = ">=3.8" summary = "An extremely fast Python package installer and resolver, written in Rust." groups = ["dev"] files = [ - {file = "uv-0.2.32-py3-none-linux_armv6l.whl", hash = "sha256:37d6b4a23792e4b9bd148d0696a678a14eb987e7d027ec94533ed053e9515192"}, - {file = "uv-0.2.32-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:71bb1f302d5ee1741f99fddbde3b2d62ea3838260c34b112a3468451cac73b1b"}, - {file = "uv-0.2.32-py3-none-macosx_11_0_arm64.whl", hash = "sha256:127f3009abf342b3f189eeddd3719db0ff9c0aa43f3c5faeb76d5a963de3c23c"}, - {file = "uv-0.2.32-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:862ed5fe4eebe782e00b9ba6f220c82d710ad2c765e7db5550ccad162301c81e"}, - {file = "uv-0.2.32-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e86fabae3553c02ed715b2ccdfb19ed5f5e98470cac33e5078cfb4911b33d7fd"}, - {file = "uv-0.2.32-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b173f71252a504b7d62e84262ed29a46db77de3689faf34c499d2463e59c6dc"}, - {file = "uv-0.2.32-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:907049dfa1341ad36928fedc3df2187bc0f419a743023b5ee0e3a21c14bd191e"}, - {file = "uv-0.2.32-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a168943ead36a262b883971d8e1d9aa2a11842f5d997a1fd1a14d50cb49aeb20"}, - {file = "uv-0.2.32-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dfbd0eda969c1cb1d1dd601172e667f4724ef7de0d72bc1d6cb79d8a56a4660"}, - {file = "uv-0.2.32-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7621b7cac2b41fbba42735c34bb914ef340e30116e3524daea333e870e6f5f1c"}, - {file = "uv-0.2.32-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:195b5eade2b0866ab1a84accc2c3ddb2b73d7902f7274c49016afd08c28ddf3e"}, - {file = "uv-0.2.32-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:fa45c91f3955f8229c3a817a064e85d88cd1f1944e1161ddd7acb913f4e547dc"}, - {file = "uv-0.2.32-py3-none-musllinux_1_1_i686.whl", hash = "sha256:089f5d082d745ad40ed8c7bff9d551db942fd13ca85e7dc1c6ef47d67365b4c0"}, - {file = "uv-0.2.32-py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:045f90cbc4df9117e845234fd73029ff0696701e0d831e1ac2a7f17ecc2d09c4"}, - {file = "uv-0.2.32-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a0379a57603731927c8ce74ee4a4c7876765fc86c5c28f7c0f8ea019b61e4838"}, - {file = "uv-0.2.32-py3-none-win32.whl", hash = "sha256:dbec58b12b9e96871c947a255a51c015387fb90c403b956bc723f489a11c6320"}, - {file = "uv-0.2.32-py3-none-win_amd64.whl", hash = "sha256:389e0e32718fbbadf9b710fb0e2a27b539a7879466c32669f95f1172940c76fc"}, - {file = "uv-0.2.32.tar.gz", hash = "sha256:90e4889b26a4624c42f460e284dcd20400d0ef577058d346b6a5da2f3ab4db4f"}, + {file = "uv-0.2.37-py3-none-linux_armv6l.whl", hash = "sha256:541670c863de680dbc355c0c5829e52d282f6f98ca742ae76dc8fe61d182e813"}, + {file = "uv-0.2.37-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bcb2ec826ae4fa9f8cac90e1289c1961aa3220b95b314426038f54278237de8a"}, + {file = "uv-0.2.37-py3-none-macosx_11_0_arm64.whl", hash = "sha256:99d4f0f510c5aa807ef1141fd8cb31f25fb53587dadacb0e28e4f51eaca6f0ad"}, + {file = "uv-0.2.37-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:6fb5a27816115e99a2463736054db5e0ebb84d9ebf38ccf71c4c7b253e945234"}, + {file = "uv-0.2.37-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3bd4d5a36fef0d81985eb15b5533f29d7f0e2c2c31d8b485703855b73ad0d8fd"}, + {file = "uv-0.2.37-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d80e51ab8e30ccc8ab1bbbe1a823d07cd0a7ec7c18d03dd61c6d19f0e191e1f4"}, + {file = "uv-0.2.37-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8a2221baf510fa3bc3f428cfa43ebae8635b7b313946c7092a586f88362ebfe2"}, + {file = "uv-0.2.37-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ae005ad344f6839ef503d05c94838b4137fa69c4bdc35340fb3b0297a7282e2"}, + {file = "uv-0.2.37-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aad8389672c7905559a7fbd8f7271a3512d4e4b3b8510334a27fbd3a4141d6dd"}, + {file = "uv-0.2.37-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6d6748da729a7c11aed34733bc9884ae6a9adc289dc09f33da36dd2a1f14bcb"}, + {file = "uv-0.2.37-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:8c75851a3e6c236ce8279d9470cfca08f0d9b1d87b610beaf22028fcf3125ded"}, + {file = "uv-0.2.37-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:72eb6b7f01d79bd758b438de0281f3e4c9af6005860cabcf4743fc7752f61022"}, + {file = "uv-0.2.37-py3-none-musllinux_1_1_i686.whl", hash = "sha256:7fdf403b48a430f6c42773190971f55efe235f326ce9f785ca5fae5aa20e3c8a"}, + {file = "uv-0.2.37-py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:80b704aa0547196e249dfa6fee6027dd53b26e804f2f7b222ce1a24113d71fce"}, + {file = "uv-0.2.37-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0d7c06dab6aa5212646a1f2a7ca8117ea15879fc0867507af19007cf0ffd8e63"}, + {file = "uv-0.2.37-py3-none-win32.whl", hash = "sha256:7a61aec56e4a7e6b0ef924905006c16da23e8f91d2dd8d740ca7ea76400a0316"}, + {file = "uv-0.2.37-py3-none-win_amd64.whl", hash = "sha256:3e0d79c8786e9e904320d72d2ee84c77004c1d241c272fbcb3bd768040e8e292"}, + {file = "uv-0.2.37.tar.gz", hash = "sha256:40b409f276b4c027fd16070bd9568e981db9d6cf3b7e8b443d06972dbef79c30"}, ] [[package]] @@ -1779,12 +1863,12 @@ files = [ [[package]] name = "zipp" -version = "3.19.2" +version = "3.20.0" requires_python = ">=3.8" summary = "Backport of pathlib-compatible object wrapper for zip files" groups = ["pdm", "poetry"] marker = "python_version < \"3.12\"" files = [ - {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, - {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, + {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, + {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, ] diff --git a/pyproject.toml b/pyproject.toml index e212d92..bc9d7e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ dynamic = [ "version", ] dependencies = [ + "packaging>=24.1", "strictyaml>=1.7.3", "tomli>=2; python_version<'3.11'", "typing-extensions; python_version<'3.10'", @@ -63,6 +64,8 @@ lint-mypy = { cmd = "mypy src", help = "Run mypy type checker" } # XXX(dugab): run mypy on tests as well lint-ruff = { cmd = "ruff check .", help = "Run ruff linter" } test-cov = { cmd = "pytest --junitxml=junit/test-results.xml --cov --cov-report=xml --cov-report=html --cov-report=term-missing", help = "Run tests with coverage" } +test-all = { cmd = "tox", help = "Test against all supported versions" } +test = { cmd = "pytest", help = "Run the test suite" } [tool.pdm.dev-dependencies] dev = [ diff --git a/src/sync_pre_commit_lock/__init__.py b/src/sync_pre_commit_lock/__init__.py index c7f96cf..48aed78 100644 --- a/src/sync_pre_commit_lock/__init__.py +++ b/src/sync_pre_commit_lock/__init__.py @@ -36,5 +36,5 @@ def error(self, msg: str) -> None: def success(self, msg: str) -> None: raise NotImplementedError - def list_updated_packages(self, packages: dict[str, tuple[PreCommitRepo, str]]) -> None: + def list_updated_packages(self, packages: dict[str, tuple[PreCommitRepo, PreCommitRepo]]) -> None: raise NotImplementedError diff --git a/src/sync_pre_commit_lock/actions/sync_hooks.py b/src/sync_pre_commit_lock/actions/sync_hooks.py index 18fc350..3ec6c50 100644 --- a/src/sync_pre_commit_lock/actions/sync_hooks.py +++ b/src/sync_pre_commit_lock/actions/sync_hooks.py @@ -1,9 +1,13 @@ from __future__ import annotations -from typing import TYPE_CHECKING, NamedTuple +from functools import cached_property +from typing import TYPE_CHECKING, NamedTuple, Sequence -from sync_pre_commit_lock.db import DEPENDENCY_MAPPING, REPOSITORY_ALIASES, PackageRepoMapping, RepoInfo -from sync_pre_commit_lock.pre_commit_config import PreCommitHookConfig, PreCommitRepo +from packaging.requirements import InvalidRequirement, Requirement +from packaging.utils import canonicalize_name + +from sync_pre_commit_lock.db import DEPENDENCY_MAPPING, REPOSITORY_ALIASES, PackageRepoMapping +from sync_pre_commit_lock.pre_commit_config import PreCommitHook, PreCommitHookConfig, PreCommitRepo if TYPE_CHECKING: from pathlib import Path @@ -17,6 +21,9 @@ class GenericLockedPackage(NamedTuple): version: str # Add original data here? + def __str__(self) -> str: + return f"{self.name}=={self.version}" + class SyncPreCommitHooksVersion: def __init__( @@ -49,21 +56,22 @@ def execute(self) -> None: self.printer.error(f"Invalid pre-commit config file: {self.pre_commit_config_file_path}: {e}") return - mapping, mapping_reverse_by_url = self.build_mapping() # XXX We should have the list of packages mapped, but already up to date and print it - to_fix, in_sync = self.analyze_repos(pre_commit_config_data.repos_normalized, mapping, mapping_reverse_by_url) + to_fix, in_sync = self.analyze_repos(pre_commit_config_data.repos_normalized) if len(to_fix) == 0 and len(in_sync) == 0: self.printer.info("No pre-commit hook detected that matches a locked package.") return if len(to_fix) == 0: - packages_str = ", ".join(f"{mapping_reverse_by_url[repo.repo]} ({rev})" for repo, rev in in_sync.items()) + packages_str = ", ".join( + f"{self.mapping_reverse_by_url[repo.repo]} ({rev})" for repo, rev in in_sync.items() + ) self.printer.info(f"All pre-commit hooks are already up to date with the lockfile: {packages_str}") return self.printer.info("Detected pre-commit hooks that can be updated to match the lockfile:") self.printer.list_updated_packages( - {mapping_reverse_by_url[repo.repo]: (repo, new_ver) for repo, new_ver in to_fix.items()} + {self.mapping_reverse_by_url[repo.repo]: (repo, new_ver) for repo, new_ver in to_fix.items()} ) if self.dry_run: @@ -72,12 +80,43 @@ def execute(self) -> None: pre_commit_config_data.update_pre_commit_repo_versions(to_fix) self.printer.success(f"Pre-commit hooks have been updated in {self.pre_commit_config_file_path.name}!") + @cached_property + def mapping(self) -> PackageRepoMapping: + return {**DEPENDENCY_MAPPING, **self.plugin_config.dependency_mapping} + + @cached_property + def mapping_reverse_by_url(self) -> dict[str, str]: + """Merge the default mapping with the user-provided mapping. Also build a reverse mapping by URL.""" + mapping_reverse_by_url = {repo["repo"]: lib_name for lib_name, repo in self.mapping.items()} + for canonical_name, aliases in REPOSITORY_ALIASES.items(): + if canonical_name in mapping_reverse_by_url: + for alias in aliases: + mapping_reverse_by_url[alias] = mapping_reverse_by_url[canonical_name] + # XXX Allow override / extend of aliases + return mapping_reverse_by_url + def get_pre_commit_repo_new_version( self, pre_commit_config_repo: PreCommitRepo, - mapping_db_repo_info: RepoInfo, - locked_package: GenericLockedPackage, ) -> str | None: + dependency = self.mapping[self.mapping_reverse_by_url[pre_commit_config_repo.repo]] + dependency_name = self.mapping_reverse_by_url[pre_commit_config_repo.repo] + locked_package = self.locked_packages.get(dependency_name) + + if not locked_package: + self.printer.debug( + f"Pre-commit hook {pre_commit_config_repo.repo} has a mapping to Python package `{dependency_name}`, " + "but was not found in the lockfile" + ) + return None + + if "+" in locked_package.version: + self.printer.debug( + f"Pre-commit hook {pre_commit_config_repo.repo} has a mapping to Python package `{dependency_name}`, " + f"but is skipped because the locked version `{locked_package.version}` contaims a `+`, " + "which is a local version identifier." + ) + return None if locked_package.name in self.plugin_config.ignore: self.printer.debug(f"Ignoring {locked_package.name} from configuration.") return None @@ -85,7 +124,7 @@ def get_pre_commit_repo_new_version( self.printer.debug( f"Found mapping between pre-commit hook `{pre_commit_config_repo.repo}` and locked package `{locked_package.name}`." ) - formatted_rev = mapping_db_repo_info["rev"].replace("${rev}", str(locked_package.version)) + formatted_rev = dependency["rev"].replace("${rev}", str(locked_package.version)) if formatted_rev != pre_commit_config_repo.rev: self.printer.debug( f"Pre-commit hook {pre_commit_config_repo.repo} and locked package {locked_package.name} have different versions:\n" @@ -99,52 +138,48 @@ def get_pre_commit_repo_new_version( ) return None - def build_mapping(self) -> tuple[PackageRepoMapping, dict[str, str]]: - """Merge the default mapping with the user-provided mapping. Also build a reverse mapping by URL.""" - mapping: PackageRepoMapping = {**DEPENDENCY_MAPPING, **self.plugin_config.dependency_mapping} - mapping_reverse_by_url = {repo["repo"]: lib_name for lib_name, repo in mapping.items()} - for canonical_name, aliases in REPOSITORY_ALIASES.items(): - for alias in aliases: - mapping_reverse_by_url[alias] = mapping_reverse_by_url[canonical_name] - # XXX Allow override / extend of aliases - return mapping, mapping_reverse_by_url + def get_pre_commit_repo_new_hooks(self, hooks: Sequence[PreCommitHook]) -> Sequence[PreCommitHook]: + return [self.get_pre_commit_repo_new_hook(hook) for hook in hooks] + + def get_pre_commit_repo_new_hook(self, hook: PreCommitHook) -> PreCommitHook: + return PreCommitHook( + hook.id, [self.get_pre_commit_repo_hook_new_dependency(dep) for dep in hook.additional_dependencies] + ) + + def get_pre_commit_repo_hook_new_dependency(self, dependency: str) -> str: + if "+" in dependency: + self.printer.debug(f"Additional dependency {dependency} is a local version. Ignoring.") + return dependency + try: + requirement = Requirement(dependency) + except InvalidRequirement: + self.printer.debug(f"Invalid additional dependency {dependency}. Ignoring.") + return dependency + normalized_name = canonicalize_name(requirement.name) + if not (locked_version := self.locked_packages.get(normalized_name)): + self.printer.debug(f"Additional dependency {dependency} not found in the lockfile. Ignoring.") + return dependency + return str(locked_version).replace(normalized_name, requirement.name) def analyze_repos( self, pre_commit_repos: set[PreCommitRepo], - mapping: PackageRepoMapping, - mapping_reverse_by_url: dict[str, str], - ) -> tuple[dict[PreCommitRepo, str], dict[PreCommitRepo, str]]: - to_fix: dict[PreCommitRepo, str] = {} - in_sync: dict[PreCommitRepo, str] = {} + ) -> tuple[dict[PreCommitRepo, PreCommitRepo], dict[PreCommitRepo, PreCommitRepo]]: + to_fix: dict[PreCommitRepo, PreCommitRepo] = {} + in_sync: dict[PreCommitRepo, PreCommitRepo] = {} for pre_commit_repo in pre_commit_repos: - if pre_commit_repo.repo not in mapping_reverse_by_url: + if pre_commit_repo.repo not in self.mapping_reverse_by_url: self.printer.debug(f"Pre-commit hook {pre_commit_repo.repo} not found in the DB mapping") continue - dependency = mapping[mapping_reverse_by_url[pre_commit_repo.repo]] - dependency_name = mapping_reverse_by_url[pre_commit_repo.repo] - dependency_locked = self.locked_packages.get(dependency_name) - - if not dependency_locked: - self.printer.debug( - f"Pre-commit hook {pre_commit_repo.repo} has a mapping to Python package `{dependency_name}`, " - "but was not found in the lockfile" - ) - continue - - if "+" in dependency_locked.version: - self.printer.debug( - f"Pre-commit hook {pre_commit_repo.repo} has a mapping to Python package `{dependency_name}`, " - f"but is skipped because the locked version `{dependency_locked.version}` contaims a `+`, " - "which is a local version identifier." - ) - continue - - new_ver = self.get_pre_commit_repo_new_version(pre_commit_repo, dependency, dependency_locked) - if new_ver: - to_fix[pre_commit_repo] = new_ver + new_repo = PreCommitRepo( + repo=pre_commit_repo.repo, + rev=self.get_pre_commit_repo_new_version(pre_commit_repo) or pre_commit_repo.rev, + hooks=self.get_pre_commit_repo_new_hooks(pre_commit_repo.hooks), + ) + if new_repo != pre_commit_repo: + to_fix[pre_commit_repo] = new_repo else: - in_sync[pre_commit_repo] = dependency_locked.version + in_sync[pre_commit_repo] = pre_commit_repo return to_fix, in_sync diff --git a/src/sync_pre_commit_lock/pdm_plugin.py b/src/sync_pre_commit_lock/pdm_plugin.py index 9d2c661..609a4f6 100644 --- a/src/sync_pre_commit_lock/pdm_plugin.py +++ b/src/sync_pre_commit_lock/pdm_plugin.py @@ -3,6 +3,7 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Any, ClassVar, Union +from packaging.requirements import Requirement from pdm import termui from pdm.__version__ import __version__ as pdm_version from pdm.cli.commands.base import BaseCommand @@ -29,7 +30,7 @@ from pdm.project import Project from pdm.termui import UI - from sync_pre_commit_lock.pre_commit_config import PreCommitRepo + from sync_pre_commit_lock.pre_commit_config import PreCommitHook, PreCommitRepo class PDMPrinter(Printer): @@ -61,23 +62,59 @@ def success(self, msg: str) -> None: def _format_repo_url(self, repo_url: str, package_name: str) -> str: return repo_url.replace(package_name, f"[cyan][bold]{package_name}[/bold][/cyan]") - def list_updated_packages(self, packages: dict[str, tuple[PreCommitRepo, str]]) -> None: + def list_updated_packages(self, packages: dict[str, tuple[PreCommitRepo, PreCommitRepo]]) -> None: """ Args: packages: Dict of package name -> (repo, new_rev) """ self.ui.display_columns( - [ - ( - "[info]" + self.plugin_prefix + "[/info]" + " " + self.success_list_token, - "[info]" + self._format_repo_url(repo[0].repo, package) + "[/info]", - " ", - "[error]" + repo[0].rev + "[/error]", - "[info]" + "->" + "[/info]", - "[green]" + repo[1] + "[/green]", - ) - for package, repo in packages.items() - ] + [row for package, (old, new) in packages.items() for row in self._format_repo(package, old, new)] + ) + + def _format_repo(self, package: str, old: PreCommitRepo, new: PreCommitRepo) -> Sequence[Sequence[str]]: + new_version = new.rev != old.rev + repo = ( + f"[info]{self.plugin_prefix}[/info] {self.success_list_token}", + f"[info]{self._format_repo_url(old.repo, package)}[/info]", + " ", + f"[error]{old.rev}[/error]" if new_version else "", + "[info]->[/info]" if new_version else "", + f"[green]{new.rev}[/green]" if new_version else "", + ) + nb_hooks = len(old.hooks) + hooks = [ + row + for idx, (old_hook, new_hook) in enumerate(zip(old.hooks, new.hooks)) + for row in self._format_hook(old_hook, new_hook, idx + 1 == nb_hooks) + ] + return [repo, *hooks] if hooks else [repo] + + def _format_hook(self, old: PreCommitHook, new: PreCommitHook, last: bool) -> Sequence[Sequence[str]]: + if not (nb_deps := len(old.additional_dependencies)): + return [] + hook = ( + f"[info]{self.plugin_prefix}[/info]", + f"{'└' if last else '├'} [cyan][bold]{old.id}[/bold][/cyan]", + "", + "", + "", + ) + dependencies = [ + self._format_additional_dependency(old_dep, new_dep, " " if last else "│", idx + 1 == nb_deps) + for idx, (old_dep, new_dep) in enumerate(zip(old.additional_dependencies, new.additional_dependencies)) + ] + return (hook, *dependencies) + + def _format_additional_dependency(self, old: str, new: str, prefix: str, last: bool) -> Sequence[str]: + old_req = Requirement(old) + new_req = Requirement(new) + return ( + f"[info]{self.plugin_prefix}[/info]", + f"{prefix} {'└' if last else '├'} [cyan][bold]{old_req.name}[/bold][/cyan]", + " ", + f"[error]{str(old_req.specifier).lstrip('==') or '*'}[/error]", + "[info]->[/info]", + f"[green]{str(new_req.specifier).lstrip('==')}[/green]", ) diff --git a/src/sync_pre_commit_lock/poetry_plugin.py b/src/sync_pre_commit_lock/poetry_plugin.py index 762c000..0e2da77 100644 --- a/src/sync_pre_commit_lock/poetry_plugin.py +++ b/src/sync_pre_commit_lock/poetry_plugin.py @@ -9,6 +9,7 @@ from cleo.exceptions import CleoValueError from cleo.helpers import option from cleo.io.outputs.output import Verbosity +from packaging.requirements import Requirement from poetry.__version__ import __version__ as poetry_version from poetry.console.application import Application from poetry.console.commands.add import AddCommand @@ -30,7 +31,7 @@ from cleo.events.event_dispatcher import EventDispatcher from cleo.io.io import IO - from sync_pre_commit_lock.pre_commit_config import PreCommitRepo + from sync_pre_commit_lock.pre_commit_config import PreCommitHook, PreCommitRepo class PoetryPrinter(Printer): @@ -55,30 +56,66 @@ def error(self, msg: str) -> None: def success(self, msg: str) -> None: return self.io.write_line(f"{self.plugin_prefix} {msg}", verbosity=Verbosity.NORMAL) - def list_updated_packages(self, packages: dict[str, tuple[PreCommitRepo, str]]) -> None: + def list_updated_packages(self, packages: dict[str, tuple[PreCommitRepo, PreCommitRepo]]) -> None: from cleo.ui.table import Table table = Table(self.io, style="compact") table.set_rows( - [ - [ - "" + self.plugin_prefix + " " + self.success_list_token, - self._format_repo_url(repo[0].repo, package), - " ", - "" + repo[0].rev + "", - "->", - "" + repo[1] + "" + "", - ] - for package, repo in packages.items() - ] + [list(row) for package, (old, new) in packages.items() for row in self._format_repo(package, old, new)] ) table.render() + def _format_repo(self, package: str, old: PreCommitRepo, new: PreCommitRepo) -> Sequence[Sequence[str]]: + new_version = new.rev != old.rev + repo = ( + f"{self.plugin_prefix} {self.success_list_token}", + self._format_repo_url(old.repo, package), + " ", + f"{old.rev}" if new_version else "", + "->" if new_version else "", + f"{new.rev}" if new_version else "", + ) + nb_hooks = len(old.hooks) + hooks = [ + row + for idx, (old_hook, new_hook) in enumerate(zip(old.hooks, new.hooks)) + for row in self._format_hook(old_hook, new_hook, idx + 1 == nb_hooks) + ] + return [repo, *hooks] if hooks else [repo] + def _format_repo_url(self, repo_url: str, package_name: str) -> str: return repo_url.replace(package_name, f"{package_name}") + def _format_hook(self, old: PreCommitHook, new: PreCommitHook, last: bool) -> Sequence[Sequence[str]]: + if not (nb_deps := len(old.additional_dependencies)): + return [] + hook = ( + f"{self.plugin_prefix}", + f"{'└' if last else '├'} {old.id}", + "", + "", + "", + ) + dependencies = [ + self._format_additional_dependency(old_dep, new_dep, " " if last else "│", idx + 1 == nb_deps) + for idx, (old_dep, new_dep) in enumerate(zip(old.additional_dependencies, new.additional_dependencies)) + ] + return (hook, *dependencies) + + def _format_additional_dependency(self, old: str, new: str, prefix: str, last: bool) -> Sequence[str]: + old_req = Requirement(old) + new_req = Requirement(new) + return ( + f"{self.plugin_prefix}", + f"{prefix} {'└' if last else '├'} {old_req.name}", + " ", + f"{str(old_req.specifier).lstrip('==') or '*'}", + "->", + f"{str(new_req.specifier).lstrip('==')}", + ) + class PoetrySetupPreCommitHooks(SetupPreCommitHooks): install_pre_commit_hooks_command: ClassVar[Sequence[str | bytes]] = ["poetry", "run", "pre-commit", "install"] diff --git a/src/sync_pre_commit_lock/pre_commit_config.py b/src/sync_pre_commit_lock/pre_commit_config.py index 700d4ef..f26c816 100644 --- a/src/sync_pre_commit_lock/pre_commit_config.py +++ b/src/sync_pre_commit_lock/pre_commit_config.py @@ -1,8 +1,9 @@ from __future__ import annotations import difflib +from dataclasses import dataclass, field from functools import cached_property -from typing import TYPE_CHECKING, Any, NamedTuple +from typing import TYPE_CHECKING, Any import strictyaml as yaml from strictyaml import Any as AnyStrictYaml @@ -11,6 +12,7 @@ from sync_pre_commit_lock.utils import normalize_git_url if TYPE_CHECKING: + from collections.abc import Sequence from pathlib import Path schema = MapCombined( @@ -20,6 +22,16 @@ { "repo": Str(), Optional("rev"): Str(), + Optional("hooks"): Seq( + MapCombined( + { + "id": Str(), + Optional("additional_dependencies"): Seq(Str()), + }, + Str(), + AnyStrictYaml(), + ) + ), }, Str(), AnyStrictYaml(), @@ -31,9 +43,41 @@ ) -class PreCommitRepo(NamedTuple): +@dataclass(frozen=True) +class PreCommitHook: + id: str + additional_dependencies: Sequence[str] = field(default_factory=tuple) + + def __hash__(self) -> int: + return hash((self.id, *self.additional_dependencies)) + + def __eq__(self, other: object) -> bool: + return ( + isinstance(other, PreCommitHook) + and other.id == self.id + and all( + other_dep == self_dep + for other_dep, self_dep in zip(other.additional_dependencies, self.additional_dependencies) + ) + ) + + +@dataclass(frozen=True) +class PreCommitRepo: repo: str rev: str # Check if is not loaded as float/int/other yolo + hooks: Sequence[PreCommitHook] = field(default_factory=tuple) + + def __hash__(self) -> int: + return hash((self.repo, self.rev, *[hook.__hash__() for hook in self.hooks])) + + def __eq__(self, other: object) -> bool: + return ( + isinstance(other, PreCommitRepo) + and other.repo == self.repo + and other.rev == self.rev + and all(other_hook == self_hook for other_hook, self_hook in zip(other.hooks, self.hooks)) + ) class PreCommitHookConfig: @@ -68,12 +112,28 @@ def from_yaml_file(cls, file_path: Path) -> PreCommitHookConfig: def repos(self) -> list[PreCommitRepo]: """Return the repos, excluding local repos.""" return [ - PreCommitRepo(repo=repo["repo"], rev=repo["rev"]) for repo in (self.data["repos"] or []) if "rev" in repo + PreCommitRepo( + repo=repo["repo"], + rev=repo["rev"], + hooks=tuple( + PreCommitHook(hook["id"], hook.get("additional_dependencies", tuple())) + for hook in repo.get("hooks", tuple()) + ), + ) + for repo in (self.data["repos"] or []) + if "rev" in repo ] @cached_property def repos_normalized(self) -> set[PreCommitRepo]: - return {PreCommitRepo(repo=normalize_git_url(repo.repo), rev=repo.rev) for repo in self.repos} + return { + PreCommitRepo( + repo=normalize_git_url(repo.repo), + rev=repo.rev, + hooks=repo.hooks, + ) + for repo in self.repos + } @cached_property def document_start_offset(self) -> int: @@ -90,7 +150,7 @@ def document_start_offset(self) -> int: return i + 1 return 0 - def update_pre_commit_repo_versions(self, new_versions: dict[PreCommitRepo, str]) -> None: + def update_pre_commit_repo_versions(self, new_versions: dict[PreCommitRepo, PreCommitRepo]) -> None: """Fix the pre-commit hooks to match the lockfile. Preserve comments and formatting as much as possible.""" if len(new_versions) == 0: return @@ -102,15 +162,37 @@ def update_pre_commit_repo_versions(self, new_versions: dict[PreCommitRepo, str] if "rev" not in repo_rev: continue - repo, rev = repo_rev["repo"], repo_rev["rev"] - normalized_repo = PreCommitRepo(normalize_git_url(str(repo)), str(rev)) - if normalized_repo not in new_versions: + repo, rev, hooks = repo_rev["repo"], repo_rev["rev"], repo_rev.get("hooks", tuple()) + normalized_repo = PreCommitRepo( + normalize_git_url(str(repo)), + str(rev), + tuple( + PreCommitHook(str(hook["id"]), [str(dep) for dep in hook.get("additional_dependencies", tuple())]) + for hook in hooks + ), + ) + if not (updated_repo := new_versions.get(normalized_repo)): continue rev_line_number: int = rev.end_line + self.document_start_offset rev_line_idx: int = rev_line_number - 1 original_rev_line: str = updated_lines[rev_line_idx] - updated_lines[rev_line_idx] = original_rev_line.replace(str(rev), new_versions[normalized_repo]) + updated_lines[rev_line_idx] = original_rev_line.replace(str(rev), updated_repo.rev) + + for src_hook, old_hook, new_hook in zip(hooks, normalized_repo.hooks, updated_repo.hooks): + if new_hook == old_hook: + continue + for src_dep, old_dep, new_dep in zip( + src_hook.get("additional_dependencies", []), + old_hook.additional_dependencies, + new_hook.additional_dependencies, + ): + if old_dep == new_dep: + continue + dep_line_number: int = src_dep.end_line + self.document_start_offset + dep_line_idx: int = dep_line_number - 1 + original_dep_line: str = updated_lines[dep_line_idx] + updated_lines[dep_line_idx] = original_dep_line.replace(str(src_dep), new_dep) changes = difflib.ndiff(original_lines, updated_lines) change_count = sum(1 for change in changes if change[0] in ["+", "-"]) diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-only-deps.expected.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-only-deps.expected.yaml new file mode 100644 index 0000000..15ded84 --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-only-deps.expected.yaml @@ -0,0 +1,18 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.5.0 + hooks: + - id: mypy + additional_dependencies: + - types-PyYAML==1.2.4 + # Some comment + - types-requests==3.4.5 diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-only-deps.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-only-deps.yaml new file mode 100644 index 0000000..993809e --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-only-deps.yaml @@ -0,0 +1,18 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.5.0 + hooks: + - id: mypy + additional_dependencies: + - types-PyYAML + # Some comment + - types-requests diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-deps.expected.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-deps.expected.yaml new file mode 100644 index 0000000..15ded84 --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-deps.expected.yaml @@ -0,0 +1,18 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.5.0 + hooks: + - id: mypy + additional_dependencies: + - types-PyYAML==1.2.4 + # Some comment + - types-requests==3.4.5 diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-deps.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-deps.yaml new file mode 100644 index 0000000..28de35f --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-deps.yaml @@ -0,0 +1,18 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.0.0 + hooks: + - id: mypy + additional_dependencies: + - types-PyYAML==1.2.4 + # Some comment + - types-requests diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-one-liner-deps.expected.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-one-liner-deps.expected.yaml new file mode 100644 index 0000000..bd4adc0 --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-one-liner-deps.expected.yaml @@ -0,0 +1,15 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.5.0 + hooks: + - id: mypy + additional_dependencies: [types-PyYAML==1.2.4, types-requests==3.4.5] diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-one-liner-deps.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-one-liner-deps.yaml new file mode 100644 index 0000000..c488f5f --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-with-one-liner-deps.yaml @@ -0,0 +1,15 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.0.0 + hooks: + - id: mypy + additional_dependencies: [types-PyYAML, types-requests] diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-without-new-deps.expected.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-without-new-deps.expected.yaml new file mode 100644 index 0000000..15ded84 --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-without-new-deps.expected.yaml @@ -0,0 +1,18 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.5.0 + hooks: + - id: mypy + additional_dependencies: + - types-PyYAML==1.2.4 + # Some comment + - types-requests==3.4.5 diff --git a/tests/fixtures/sample_pre_commit_config/pre-commit-config-without-new-deps.yaml b/tests/fixtures/sample_pre_commit_config/pre-commit-config-without-new-deps.yaml new file mode 100644 index 0000000..814ad36 --- /dev/null +++ b/tests/fixtures/sample_pre_commit_config/pre-commit-config-without-new-deps.yaml @@ -0,0 +1,18 @@ + +# Many unused lines before document separator + +--- +default_language_version: + python: python3.11 + +repos: + + - repo: https://github.com/pre-commit/mirrors-mypy + # Some comment + rev: v1.0.0 + hooks: + - id: mypy + additional_dependencies: + - types-PyYAML==1.2.4 + # Some comment + - types-requests==3.4.5 diff --git a/tests/test_actions/test_install_hooks.py b/tests/test_actions/test_install_hooks.py index b7cada7..6dc1003 100644 --- a/tests/test_actions/test_install_hooks.py +++ b/tests/test_actions/test_install_hooks.py @@ -4,6 +4,7 @@ import pytest from pytest_mock import MockerFixture + from sync_pre_commit_lock import Printer from sync_pre_commit_lock.actions.install_hooks import SetupPreCommitHooks diff --git a/tests/test_actions/test_sync_hooks.py b/tests/test_actions/test_sync_hooks.py index b642603..769506a 100644 --- a/tests/test_actions/test_sync_hooks.py +++ b/tests/test_actions/test_sync_hooks.py @@ -1,14 +1,16 @@ from pathlib import Path from unittest.mock import MagicMock, patch +import pytest + from sync_pre_commit_lock import Printer from sync_pre_commit_lock.actions.sync_hooks import ( GenericLockedPackage, SyncPreCommitHooksVersion, ) from sync_pre_commit_lock.config import SyncPreCommitLockConfig -from sync_pre_commit_lock.db import PackageRepoMapping, RepoInfo -from sync_pre_commit_lock.pre_commit_config import PreCommitHookConfig, PreCommitRepo +from sync_pre_commit_lock.db import RepoInfo +from sync_pre_commit_lock.pre_commit_config import PreCommitHook, PreCommitHookConfig, PreCommitRepo def test_execute_returns_early_when_disabled() -> None: @@ -31,11 +33,8 @@ def test_execute_returns_early_when_disabled() -> None: @patch("sync_pre_commit_lock.pre_commit_config.PreCommitHookConfig.from_yaml_file") -@patch.object(SyncPreCommitHooksVersion, "build_mapping") @patch.object(SyncPreCommitHooksVersion, "analyze_repos") -def test_execute_returns_early_during_dry_run( - mock_analyze_repos: MagicMock, mock_build_mapping: MagicMock, mock_from_yaml_file: MagicMock -) -> None: +def test_execute_returns_early_during_dry_run(mock_analyze_repos: MagicMock, mock_from_yaml_file: MagicMock) -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) locked_packages: dict[str, GenericLockedPackage] = {} @@ -54,13 +53,12 @@ def test_execute_returns_early_during_dry_run( # Mocks pre_commit_config = MagicMock(spec=PreCommitHookConfig) mock_from_yaml_file.return_value = pre_commit_config - mock_build_mapping.return_value = ({}, {"repo1": "somepkg"}) + syncer.mapping_reverse_by_url = {"repo1": "somepkg"} mock_analyze_repos.return_value = {PreCommitRepo("repo1", "rev1"): "rev2"}, {} syncer.execute() # Assertions - mock_build_mapping.assert_called_once() mock_analyze_repos.assert_called_once() pre_commit_config.update_pre_commit_repo_versions.assert_not_called() printer.info.assert_called_with("Dry run, skipping pre-commit hook update.") @@ -109,11 +107,8 @@ def test_execute_handles_file_invalid(mock_from_yaml_file: MagicMock) -> None: @patch("sync_pre_commit_lock.pre_commit_config.PreCommitHookConfig.from_yaml_file") -@patch.object(SyncPreCommitHooksVersion, "build_mapping") @patch.object(SyncPreCommitHooksVersion, "analyze_repos") -def test_execute_synchronizes_hooks( - mock_analyze_repos: MagicMock, mock_build_mapping: MagicMock, mock_from_yaml_file: MagicMock -) -> None: +def test_execute_synchronizes_hooks(mock_analyze_repos: MagicMock, mock_from_yaml_file: MagicMock) -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) pre_commit_config_file_path.name = ".pre-commit-config.yaml" @@ -133,24 +128,20 @@ def test_execute_synchronizes_hooks( # Mocks pre_commit_config = MagicMock(spec=PreCommitHookConfig) mock_from_yaml_file.return_value = pre_commit_config - mock_build_mapping.return_value = ({}, {"repo1": "somepkg"}) + syncer.mapping_reverse_by_url = {"repo1": "somepkg"} mock_analyze_repos.return_value = {PreCommitRepo("repo1", "rev1"): "rev2"}, {} syncer.execute() # Assertions - mock_build_mapping.assert_called_once() mock_analyze_repos.assert_called_once() pre_commit_config.update_pre_commit_repo_versions.assert_called_once_with({PreCommitRepo("repo1", "rev1"): "rev2"}) printer.success.assert_called_with("Pre-commit hooks have been updated in .pre-commit-config.yaml!") @patch("sync_pre_commit_lock.pre_commit_config.PreCommitHookConfig.from_yaml_file") -@patch.object(SyncPreCommitHooksVersion, "build_mapping") @patch.object(SyncPreCommitHooksVersion, "analyze_repos") -def test_execute_synchronizes_hooks_no_match( - mock_analyze_repos: MagicMock, mock_build_mapping: MagicMock, mock_from_yaml_file: MagicMock -) -> None: +def test_execute_synchronizes_hooks_no_match(mock_analyze_repos: MagicMock, mock_from_yaml_file: MagicMock) -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) locked_packages: dict[str, GenericLockedPackage] = {} @@ -165,17 +156,16 @@ def test_execute_synchronizes_hooks_no_match( plugin_config=plugin_config, dry_run=dry_run, ) + syncer.mapping = {} # Mocks pre_commit_config = MagicMock(spec=PreCommitHookConfig) mock_from_yaml_file.return_value = pre_commit_config - mock_build_mapping.return_value = ({}, {}) mock_analyze_repos.return_value = {}, {} syncer.execute() # Assertions - mock_build_mapping.assert_called_once() mock_analyze_repos.assert_called_once() pre_commit_config.update_pre_commit_repo_versions.assert_not_called() printer.info.assert_called_with("No pre-commit hook detected that matches a locked package.") @@ -184,7 +174,7 @@ def test_execute_synchronizes_hooks_no_match( def test_get_pre_commit_repo_new_version() -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) - locked_packages: dict[str, GenericLockedPackage] = {"lib_name": GenericLockedPackage("lib_name", "2.0.0")} + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": GenericLockedPackage("lib-name", "2.0.0")} plugin_config = MagicMock(spec=SyncPreCommitLockConfig) plugin_config.ignore = [] syncer = SyncPreCommitHooksVersion( @@ -194,11 +184,9 @@ def test_get_pre_commit_repo_new_version() -> None: plugin_config=plugin_config, ) pre_commit_config_repo = PreCommitRepo("repo_url", "1.2.3") - mapping_db_repo_info: RepoInfo = {"repo": "repo_url", "rev": "${rev}"} + syncer.mapping = {"lib-name": {"repo": "repo_url", "rev": "${rev}"}} - new_version = syncer.get_pre_commit_repo_new_version( - pre_commit_config_repo, mapping_db_repo_info, locked_packages["lib_name"] - ) + new_version = syncer.get_pre_commit_repo_new_version(pre_commit_config_repo) assert new_version == "2.0.0" @@ -207,7 +195,7 @@ def test_get_pre_commit_repo_new_version() -> None: def test_analyze_repos(mock_get_pre_commit_repo_new_version: MagicMock) -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) - locked_packages: dict[str, GenericLockedPackage] = {"lib_name": GenericLockedPackage("lib_name", "2.0.0")} + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": GenericLockedPackage("lib-name", "2.0.0")} plugin_config = MagicMock(spec=SyncPreCommitLockConfig) syncer = SyncPreCommitHooksVersion( @@ -218,12 +206,12 @@ def test_analyze_repos(mock_get_pre_commit_repo_new_version: MagicMock) -> None: ) mock_get_pre_commit_repo_new_version.return_value = "2.0.0" pre_commit_repos = {PreCommitRepo("https://repo_url", "1.2.3")} - mapping: PackageRepoMapping = {"lib_name": {"repo": "https://repo_url", "rev": "${rev}"}} - mapping_reverse_by_url = {"https://repo_url": "lib_name"} + syncer.mapping = {"lib-name": {"repo": "https://repo_url", "rev": "${rev}"}} + syncer.mapping_reverse_by_url = {"https://repo_url": "lib-name"} - to_fix, _ = syncer.analyze_repos(pre_commit_repos, mapping, mapping_reverse_by_url) + to_fix, _ = syncer.analyze_repos(pre_commit_repos) - assert to_fix == {PreCommitRepo("https://repo_url", "1.2.3"): "2.0.0"} + assert to_fix == {PreCommitRepo("https://repo_url", "1.2.3"): PreCommitRepo("https://repo_url", "2.0.0")} def test_build_mapping() -> None: @@ -240,20 +228,18 @@ def test_build_mapping() -> None: ) plugin_config.dependency_mapping = {"new_lib": {"repo": "new_repo_url", "rev": "${rev}"}} - mapping, mapping_reverse_by_url = syncer.build_mapping() - - assert "new_lib" in mapping - assert mapping["new_lib"]["repo"] == "new_repo_url" - assert "new_repo_url" in mapping_reverse_by_url - assert mapping_reverse_by_url["new_repo_url"] == "new_lib" + assert "new_lib" in syncer.mapping + assert syncer.mapping["new_lib"]["repo"] == "new_repo_url" + assert "new_repo_url" in syncer.mapping_reverse_by_url + assert syncer.mapping_reverse_by_url["new_repo_url"] == "new_lib" def test_get_pre_commit_repo_new_version_ignored() -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) - locked_packages: dict[str, GenericLockedPackage] = {} + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": GenericLockedPackage("lib-name", "2.0.0")} plugin_config = MagicMock(spec=SyncPreCommitLockConfig) - plugin_config.ignore = ["lib_name"] + plugin_config.ignore = ["lib-name"] syncer = SyncPreCommitHooksVersion( printer=printer, @@ -261,12 +247,11 @@ def test_get_pre_commit_repo_new_version_ignored() -> None: locked_packages=locked_packages, plugin_config=plugin_config, ) + syncer.mapping = {"lib-name": RepoInfo(repo="repo_url", rev="${rev}")} pre_commit_config_repo = PreCommitRepo("repo_url", "1.2.3") - mapping_db_repo_info = RepoInfo(repo="repo_url", rev="${rev}") - locked_package = GenericLockedPackage("lib_name", "2.0.0") - new_version = syncer.get_pre_commit_repo_new_version(pre_commit_config_repo, mapping_db_repo_info, locked_package) + new_version = syncer.get_pre_commit_repo_new_version(pre_commit_config_repo) assert new_version is None @@ -274,7 +259,7 @@ def test_get_pre_commit_repo_new_version_ignored() -> None: def test_get_pre_commit_repo_new_version_version_match() -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) - locked_packages: dict[str, GenericLockedPackage] = {} + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": GenericLockedPackage("lib-name", "1.2.3")} plugin_config = MagicMock(spec=SyncPreCommitLockConfig) plugin_config.ignore = [] @@ -286,14 +271,41 @@ def test_get_pre_commit_repo_new_version_version_match() -> None: ) pre_commit_config_repo = PreCommitRepo("repo_url", "1.2.3") - mapping_db_repo_info = RepoInfo(repo="repo_url", rev="${rev}") - locked_package = GenericLockedPackage("lib_name", "1.2.3") + syncer.mapping = {"lib-name": RepoInfo(repo="repo_url", rev="${rev}")} - new_version = syncer.get_pre_commit_repo_new_version(pre_commit_config_repo, mapping_db_repo_info, locked_package) + new_version = syncer.get_pre_commit_repo_new_version(pre_commit_config_repo) assert new_version is None +@pytest.mark.parametrize( + "dependency, expected", + [ + pytest.param("dep==1.2.3", "dep==1.2.3", id="same"), + pytest.param("dep", "dep==1.2.3", id="locked"), + pytest.param("other", "other", id="not-in-lock"), + pytest.param("dep<>unparsable", "dep<>unparsable", id="unparsable"), + pytest.param("dep==1.0.0+dev", "dep==1.0.0+dev", id="local"), + pytest.param("Dep", "Dep==1.2.3", id="casing"), + ], +) +def test_get_pre_commit_repo_hook_new_dependency(dependency: str, expected: str) -> None: + printer = MagicMock(spec=Printer) + pre_commit_config_file_path = MagicMock(spec=Path) + locked_packages: dict[str, GenericLockedPackage] = {"dep": GenericLockedPackage("dep", "1.2.3")} + plugin_config = MagicMock(spec=SyncPreCommitLockConfig) + plugin_config.ignore = [] + + syncer = SyncPreCommitHooksVersion( + printer=printer, + pre_commit_config_file_path=pre_commit_config_file_path, + locked_packages=locked_packages, + plugin_config=plugin_config, + ) + + assert syncer.get_pre_commit_repo_hook_new_dependency(dependency) == expected + + def test_analyze_repos_repo_not_in_mapping() -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) @@ -308,10 +320,9 @@ def test_analyze_repos_repo_not_in_mapping() -> None: ) pre_commit_repos = {PreCommitRepo("repo_url", "1.2.3")} - mapping: PackageRepoMapping = {} - mapping_reverse_by_url: dict[str, str] = {} + syncer.mapping = {} - result, _ = syncer.analyze_repos(pre_commit_repos, mapping, mapping_reverse_by_url) + result, _ = syncer.analyze_repos(pre_commit_repos) assert result == {} @@ -330,10 +341,9 @@ def test_analyze_repos_dependency_not_locked() -> None: ) pre_commit_repos = {PreCommitRepo("repo_url", "1.2.3")} - mapping: PackageRepoMapping = {"lib_name": {"repo": "repo_url", "rev": "${rev}"}} - mapping_reverse_by_url = {"repo_url": "lib_name"} + syncer.mapping = {"lib-name": {"repo": "repo_url", "rev": "${rev}"}} - result, _ = syncer.analyze_repos(pre_commit_repos, mapping, mapping_reverse_by_url) + result, _ = syncer.analyze_repos(pre_commit_repos) assert result == {} @@ -341,7 +351,7 @@ def test_analyze_repos_dependency_not_locked() -> None: def test_analyze_repos_no_new_version() -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) - locked_packages: dict[str, GenericLockedPackage] = {"lib_name": MagicMock(version="1.2.3")} + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": MagicMock(version="1.2.3")} plugin_config = MagicMock(spec=SyncPreCommitLockConfig) plugin_config.ignore = [] @@ -353,10 +363,9 @@ def test_analyze_repos_no_new_version() -> None: ) pre_commit_repos = {PreCommitRepo("repo_url", "1.2.3")} - mapping = {"lib_name": RepoInfo(repo="repo_url", rev="${rev}")} - mapping_reverse_by_url = {"repo_url": "lib_name"} + syncer.mapping = {"lib-name": RepoInfo(repo="repo_url", rev="${rev}")} - result, _ = syncer.analyze_repos(pre_commit_repos, mapping, mapping_reverse_by_url) + result, _ = syncer.analyze_repos(pre_commit_repos) assert result == {} @@ -364,7 +373,7 @@ def test_analyze_repos_no_new_version() -> None: def test_analyze_repos_local() -> None: printer = MagicMock(spec=Printer) pre_commit_config_file_path = MagicMock(spec=Path) - locked_packages: dict[str, GenericLockedPackage] = {"lib_name": MagicMock(version="0.1.1+dev")} + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": MagicMock(version="0.1.1+dev")} plugin_config = MagicMock(spec=SyncPreCommitLockConfig) plugin_config.ignore = [] @@ -376,9 +385,80 @@ def test_analyze_repos_local() -> None: ) pre_commit_repos = {PreCommitRepo("repo_url", "1.2.3")} - mapping = {"lib_name": RepoInfo(repo="repo_url", rev="${rev}")} - mapping_reverse_by_url = {"repo_url": "lib_name"} + syncer.mapping = {"lib-name": RepoInfo(repo="repo_url", rev="${rev}")} - result, _ = syncer.analyze_repos(pre_commit_repos, mapping, mapping_reverse_by_url) + result, _ = syncer.analyze_repos(pre_commit_repos) assert result == {} + + +def test_analyze_repos_additional_dependencies() -> None: + printer = MagicMock(spec=Printer) + pre_commit_config_file_path = MagicMock(spec=Path) + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": GenericLockedPackage("lib-name", "2.0.0")} + plugin_config = SyncPreCommitLockConfig() + + syncer = SyncPreCommitHooksVersion( + printer=printer, + pre_commit_config_file_path=pre_commit_config_file_path, + locked_packages=locked_packages, + plugin_config=plugin_config, + ) + pre_commit_repo = PreCommitRepo("https://repo_url", "1.2.3", [PreCommitHook("hook", ["lib-name==1.2.2"])]) + pre_commit_repos = {pre_commit_repo} + syncer.mapping = {"lib-name": {"repo": "https://repo_url", "rev": "${rev}"}} + + to_fix, _ = syncer.analyze_repos(pre_commit_repos) + + assert to_fix == { + pre_commit_repo: PreCommitRepo("https://repo_url", "2.0.0", [PreCommitHook("hook", ["lib-name==2.0.0"])]) + } + + +def test_analyze_repos_not_in_lock_but_additional_dependencies() -> None: + printer = MagicMock(spec=Printer) + pre_commit_config_file_path = MagicMock(spec=Path) + locked_packages: dict[str, GenericLockedPackage] = {"lib-name": GenericLockedPackage("lib-name", "2.0.0")} + plugin_config = SyncPreCommitLockConfig() + + syncer = SyncPreCommitHooksVersion( + printer=printer, + pre_commit_config_file_path=pre_commit_config_file_path, + locked_packages=locked_packages, + plugin_config=plugin_config, + ) + pre_commit_repo = PreCommitRepo("https://repo_url", "1.2.3", [PreCommitHook("hook", ["lib-name==1.2.2"])]) + pre_commit_repos = {pre_commit_repo} + syncer.mapping = {"not_lib": {"repo": "https://repo_url", "rev": "${rev}"}} + + to_fix, _ = syncer.analyze_repos(pre_commit_repos) + + assert to_fix == { + pre_commit_repo: PreCommitRepo("https://repo_url", "1.2.3", [PreCommitHook("hook", ["lib-name==2.0.0"])]) + } + + +def test_analyze_repos_local_but_additional_dependencies() -> None: + printer = MagicMock(spec=Printer) + pre_commit_config_file_path = MagicMock(spec=Path) + locked_packages: dict[str, GenericLockedPackage] = { + "lib-name": GenericLockedPackage("lib-name", "2.0.0"), + "local_lib": GenericLockedPackage("local_lib", "1.0.0+dev"), + } + plugin_config = SyncPreCommitLockConfig() + + syncer = SyncPreCommitHooksVersion( + printer=printer, + pre_commit_config_file_path=pre_commit_config_file_path, + locked_packages=locked_packages, + plugin_config=plugin_config, + ) + pre_commit_repo = PreCommitRepo("https://repo_url", "1.2.3", [PreCommitHook("hook", ["lib-name==1.2.2"])]) + pre_commit_repos = {pre_commit_repo} + syncer.mapping = {"local_lib": {"repo": "https://repo_url", "rev": "${rev}"}} + + to_fix, _ = syncer.analyze_repos(pre_commit_repos) + + assert to_fix == { + pre_commit_repo: PreCommitRepo("https://repo_url", "1.2.3", [PreCommitHook("hook", ["lib-name==2.0.0"])]) + } diff --git a/tests/test_config.py b/tests/test_config.py index b0dbe3e..2131f7f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest + from sync_pre_commit_lock.config import SyncPreCommitLockConfig, from_toml, load_config, update_from_env from sync_pre_commit_lock.db import RepoInfo diff --git a/tests/test_pdm/test_pdm_plugin.py b/tests/test_pdm/test_pdm_plugin.py index 736d283..eb40dc2 100644 --- a/tests/test_pdm/test_pdm_plugin.py +++ b/tests/test_pdm/test_pdm_plugin.py @@ -12,12 +12,13 @@ from pdm.models.candidates import Candidate from pdm.project import Project from pdm.termui import UI + from sync_pre_commit_lock.config import SyncPreCommitLockConfig from sync_pre_commit_lock.pdm_plugin import ( PDMPrinter, PDMSetupPreCommitHooks, ) -from sync_pre_commit_lock.pre_commit_config import PreCommitRepo +from sync_pre_commit_lock.pre_commit_config import PreCommitHook, PreCommitRepo # Create the mock objects @@ -82,18 +83,71 @@ def test_on_pdm_install_setup_pre_commit_success(project: Project) -> None: def test_pdm_printer_list_success(capsys: pytest.CaptureFixture[str]) -> None: - from sync_pre_commit_lock.pdm_plugin import PDMPrinter - printer = PDMPrinter(UI()) printer.list_updated_packages( { - "package1": ( - PreCommitRepo(repo="https://repo1.local/test", rev="rev1"), - "rev2", + "package": ( + PreCommitRepo("https://repo1.local/test", "rev1", [PreCommitHook("hook")]), + PreCommitRepo("https://repo1.local/test", "rev2", [PreCommitHook("hook")]), ) } ) captured = capsys.readouterr() assert "[sync-pre-commit-lock] ✔ https://repo1.local/test rev1 -> rev2" in captured.out + + +def test_pdm_printer_list_success_additional_dependency(capsys: pytest.CaptureFixture[str]) -> None: + printer = PDMPrinter(UI()) + + printer.list_updated_packages( + { + "package": ( + PreCommitRepo("https://repo1.local/test", "rev1", [PreCommitHook("hook", ["dep"])]), + PreCommitRepo("https://repo1.local/test", "rev1", [PreCommitHook("hook", ["dep==0.1.2"])]), + ) + } + ) + captured = capsys.readouterr() + + assert "[sync-pre-commit-lock] ✔ https://repo1.local/test" in captured.out + assert "[sync-pre-commit-lock] └ hook" in captured.out + assert "[sync-pre-commit-lock] └ dep * -> 0.1.2" in captured.out + + +def test_pdm_printer_list_success_repo_with_multiple_hooks_and_additional_dependency( + capsys: pytest.CaptureFixture[str], +) -> None: + printer = PDMPrinter(UI()) + + printer.list_updated_packages( + { + "package": ( + PreCommitRepo( + repo="https://repo1.local/test", + rev="rev1", + hooks=[ + PreCommitHook("1st-hook", ["dep==0.1.2", "other==0.42"]), + PreCommitHook("2nd-hook", ["dep", "other>=0.42"]), + ], + ), + PreCommitRepo( + repo="https://repo1.local/test", + rev="rev2", + hooks=[ + PreCommitHook("1st-hook", ["dep==0.1.2", "other==3.4.5"]), + PreCommitHook("2st-hook", ["dep==0.1.2", "other==3.4.5"]), + ], + ), + ) + } + ) + captured = capsys.readouterr() + + assert "[sync-pre-commit-lock] ✔ https://repo1.local/test rev1 -> rev2" in captured.out + assert "[sync-pre-commit-lock] ├ 1st-hook" in captured.out + assert "[sync-pre-commit-lock] │ └ other 0.42 -> 3.4.5" in captured.out + assert "[sync-pre-commit-lock] └ 2nd-hook" in captured.out + assert "[sync-pre-commit-lock] ├ dep * -> 0.1.2" in captured.out + assert "[sync-pre-commit-lock] └ other >=0.42 -> 3.4.5" in captured.out diff --git a/tests/test_pdm/test_pdm_sync_pre_commit_hook.py b/tests/test_pdm/test_pdm_sync_pre_commit_hook.py index 07c13d3..1255ae7 100644 --- a/tests/test_pdm/test_pdm_sync_pre_commit_hook.py +++ b/tests/test_pdm/test_pdm_sync_pre_commit_hook.py @@ -15,6 +15,7 @@ from pdm.models.requirements import NamedRequirement from pdm.project import Project from pdm.termui import UI + from sync_pre_commit_lock import ( Printer, ) diff --git a/tests/test_poetry/test_poetry_plugin.py b/tests/test_poetry/test_poetry_plugin.py index f4719a3..67021a6 100644 --- a/tests/test_poetry/test_poetry_plugin.py +++ b/tests/test_poetry/test_poetry_plugin.py @@ -10,8 +10,9 @@ from poetry.console.commands.install import InstallCommand from poetry.console.commands.lock import LockCommand from poetry.console.commands.self.self_command import SelfCommand + from sync_pre_commit_lock.poetry_plugin import SyncPreCommitLockPlugin, SyncPreCommitPoetryCommand -from sync_pre_commit_lock.pre_commit_config import PreCommitRepo +from sync_pre_commit_lock.pre_commit_config import PreCommitHook, PreCommitRepo def test_activate() -> None: @@ -110,6 +111,7 @@ def test_poetry_printer_list_success(capsys: pytest.CaptureFixture[str]) -> None from cleo.io.inputs.input import Input from cleo.io.io import IO from cleo.io.outputs.output import Output + from sync_pre_commit_lock.poetry_plugin import PoetryPrinter output = Output() @@ -122,9 +124,9 @@ def _write(message: str, new_line: bool = False): printer.list_updated_packages( { - "package1": ( - PreCommitRepo(repo="https://repo1.local/test", rev="rev1"), - "rev2", + "package": ( + PreCommitRepo("https://repo1.local/test", "rev1", [PreCommitHook("hook")]), + PreCommitRepo("https://repo1.local/test", "rev2", [PreCommitHook("hook")]), ) } ) @@ -135,6 +137,89 @@ def _write(message: str, new_line: bool = False): assert "[sync-pre-commit-lock] • https://repo1.local/test rev1 -> rev2" in out +def test_poetry_printer_list_success_additional_dependency(capsys: pytest.CaptureFixture[str]) -> None: + from cleo.io.inputs.input import Input + from cleo.io.io import IO + from cleo.io.outputs.output import Output + + from sync_pre_commit_lock.poetry_plugin import PoetryPrinter + + output = Output() + + def _write(message: str, new_line: bool = False): + print(message) # noqa: T201 + + output._write = _write + printer = PoetryPrinter(IO(input=Input(), output=output, error_output=output)) + + printer.list_updated_packages( + { + "package": ( + PreCommitRepo("https://repo1.local/test", "rev1", [PreCommitHook("hook", ["dep"])]), + PreCommitRepo("https://repo1.local/test", "rev1", [PreCommitHook("hook", ["dep==0.1.2"])]), + ) + } + ) + captured = capsys.readouterr() + # Remove all <..> tags, as we don't have the real parser + out = re.sub(r"<[^>]*>", "", captured.out) + + assert "[sync-pre-commit-lock] • https://repo1.local/test" in out + assert "[sync-pre-commit-lock] └ hook" in out + assert "[sync-pre-commit-lock] └ dep * -> 0.1.2" in out + + +def test_poetry_printer_list_success_with_multiple_hooks_and_additional_dependency( + capsys: pytest.CaptureFixture[str], +) -> None: + from cleo.io.inputs.input import Input + from cleo.io.io import IO + from cleo.io.outputs.output import Output + + from sync_pre_commit_lock.poetry_plugin import PoetryPrinter + + output = Output() + + def _write(message: str, new_line: bool = False): + print(message) # noqa: T201 + + output._write = _write + printer = PoetryPrinter(IO(input=Input(), output=output, error_output=output)) + + printer.list_updated_packages( + { + "package": ( + PreCommitRepo( + repo="https://repo1.local/test", + rev="rev1", + hooks=[ + PreCommitHook("1st-hook", ["dep==0.1.2", "other==0.42"]), + PreCommitHook("2nd-hook", ["dep", "other>=0.42"]), + ], + ), + PreCommitRepo( + repo="https://repo1.local/test", + rev="rev2", + hooks=[ + PreCommitHook("1st-hook", ["dep==0.1.2", "other==3.4.5"]), + PreCommitHook("2st-hook", ["dep==0.1.2", "other==3.4.5"]), + ], + ), + ) + } + ) + captured = capsys.readouterr() + # Remove all <..> tags, as we don't have the real parser + out = re.sub(r"<[^>]*>", "", captured.out) + + assert "[sync-pre-commit-lock] • https://repo1.local/test rev1 -> rev2" in out + assert "[sync-pre-commit-lock] ├ 1st-hook" in out + assert "[sync-pre-commit-lock] │ └ other 0.42 -> 3.4.5" in out + assert "[sync-pre-commit-lock] └ 2nd-hook" in out + assert "[sync-pre-commit-lock] ├ dep * -> 0.1.2" in out + assert "[sync-pre-commit-lock] └ other >=0.42 -> 3.4.5" in out + + def test_direct_command_invocation(): with pytest.raises(RuntimeError, match="self.application is None"): SyncPreCommitPoetryCommand().handle() diff --git a/tests/test_pre_commit_config_file.py b/tests/test_pre_commit_config_file.py index 2850ab2..a4d59bf 100644 --- a/tests/test_pre_commit_config_file.py +++ b/tests/test_pre_commit_config_file.py @@ -4,7 +4,8 @@ import pytest import yaml from strictyaml.exceptions import YAMLValidationError -from sync_pre_commit_lock.pre_commit_config import PreCommitHookConfig, PreCommitRepo + +from sync_pre_commit_lock.pre_commit_config import PreCommitHook, PreCommitHookConfig, PreCommitRepo def test_pre_commit_hook_config_initialization() -> None: @@ -67,16 +68,125 @@ def test_files_offset(path: Path, offset: int) -> None: assert config.document_start_offset == offset -def test_update_versions(): +def test_update_versions() -> None: config = PreCommitHookConfig.from_yaml_file(FIXTURES / "pre-commit-config-document-separator.yaml") config.pre_commit_config_file_path = MagicMock() - config.update_pre_commit_repo_versions({PreCommitRepo("https://github.com/psf/black", "23.2.0"): "23.3.0"}) + initial_repo = PreCommitRepo("https://github.com/psf/black", "23.2.0", [PreCommitHook("black")]) + updated_repo = PreCommitRepo("https://github.com/psf/black", "23.3.0", [PreCommitHook("black")]) + config.update_pre_commit_repo_versions({initial_repo: updated_repo}) assert config.pre_commit_config_file_path.open.call_args[0][0] == "w" config.update_pre_commit_repo_versions({}) assert config.pre_commit_config_file_path.open.call_count == 1 with pytest.raises(RuntimeError): - config.update_pre_commit_repo_versions({PreCommitRepo("https://github.com/psf/notexist", "23.2.0"): "23.3.0"}) + config.update_pre_commit_repo_versions( + {PreCommitRepo("https://github.com/psf/notexist", "23.2.0"): updated_repo} + ) assert config.pre_commit_config_file_path.open.call_count == 1 + + +@pytest.mark.parametrize("base", ["only-deps", "with-deps", "with-one-liner-deps", "without-new-deps"]) +def test_update_additional_dependencies_versions(base: str) -> None: + config = PreCommitHookConfig.from_yaml_file(FIXTURES / f"pre-commit-config-{base}.yaml") + mock_file = config.pre_commit_config_file_path = MagicMock() + mock_file.open = mock_open() + + initial_repo = config.repos[0] + updated_repo = PreCommitRepo( + "https://github.com/pre-commit/mirrors-mypy", + "v1.5.0", + [PreCommitHook("mypy", ["types-PyYAML==1.2.4", "types-requests==3.4.5"])], + ) + + config.update_pre_commit_repo_versions({initial_repo: updated_repo}) + + expected = (FIXTURES / f"pre-commit-config-{base}.expected.yaml").read_text() + + mock_file.open().writelines.assert_called_once_with(expected.splitlines(keepends=True)) + + +# Syntactic sugar +Repo = PreCommitRepo +Hook = PreCommitHook + + +@pytest.mark.parametrize( + "repo1,repo2,equal", + ( + (Repo("https://some.url", "0.42"), Repo("https://some.url", "0.42"), True), + (Repo("https://some.url", "0.42", tuple()), Repo("https://some.url", "0.42", []), True), + ( + Repo("https://some.url", "0.42", [Hook("hook")]), + Repo("https://some.url", "0.42", [Hook("hook")]), + True, + ), + ( + Repo("https://some.url", "0.42", [Hook("hook", ["somelib"])]), + Repo("https://some.url", "0.42", [Hook("hook", ["somelib"])]), + True, + ), + ( + Repo("https://some.url", "0.42", [Hook("hook", ("somelib",))]), + Repo("https://some.url", "0.42", [Hook("hook", ["somelib"])]), + True, + ), + ( + Repo( + "https://some.url", + "0.42", + [ + Hook("1st-hook", ["somelib"]), + Hook("2nd-hook", ["somelib", "another-lib"]), + ], + ), + Repo( + "https://some.url", + "0.42", + [ + Hook("1st-hook", ["somelib"]), + Hook("2nd-hook", ["somelib", "another-lib"]), + ], + ), + True, + ), + ( + Repo("https://some.url", "0.42"), + Repo("https://some.new.url", "0.42"), + False, + ), + ( + Repo("https://some.url", "0.42"), + Repo("https://some.url", "0.43"), + False, + ), + ( + Repo("https://some.url", "0.42", [Hook("hook", ["somelib==0.1"])]), + Repo("https://some.url", "0.42", [Hook("hook", ["somelib"])]), + False, + ), + ( + Repo( + "https://some.url", + "0.42", + [ + Hook("1st-hook", ["somelib"]), + Hook("2nd-hook", ["somelib", "another-lib"]), + ], + ), + Repo( + "https://some.url", + "0.42", + [ + Hook("1st-hook", ["somelib"]), + Hook("2nd-hook", ["somelib==0.42", "another-lib"]), + ], + ), + False, + ), + ), +) +def test_precommit_repo_equality(repo1: PreCommitRepo, repo2: PreCommitRepo, equal: bool): + assert (repo1 == repo2) is equal + assert (hash(repo1) == hash(repo2)) is equal diff --git a/tests/test_utils.py b/tests/test_utils.py index 8afeec2..5b5343e 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,4 +1,5 @@ import pytest + from sync_pre_commit_lock.utils import normalize_git_url