From e4234976f756832619a5362af82c1b128949f64a Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Fri, 3 Nov 2023 07:20:46 +0100 Subject: [PATCH 01/39] Poetry update --- poetry.lock | 965 ++++++++++++++++++++++++------------------------- pyproject.toml | 1 + 2 files changed, 477 insertions(+), 489 deletions(-) diff --git a/poetry.lock b/poetry.lock index 348cae51..f64fc0e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -38,20 +38,21 @@ files = [ [[package]] name = "asttokens" -version = "2.4.0" +version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false python-versions = "*" files = [ - {file = "asttokens-2.4.0-py2.py3-none-any.whl", hash = "sha256:cf8fc9e61a86461aa9fb161a14a0841a03c405fa829ac6b202670b3495d2ce69"}, - {file = "asttokens-2.4.0.tar.gz", hash = "sha256:2e0171b991b2c959acc6c49318049236844a5da1d65ba2672c4880c1c894834e"}, + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, ] [package.dependencies] six = ">=1.12.0" [package.extras] -test = ["astroid", "pytest"] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "attrs" @@ -88,29 +89,21 @@ tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} [[package]] name = "babel" -version = "2.13.0" +version = "2.13.1" description = "Internationalization utilities" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.13.0-py3-none-any.whl", hash = "sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec"}, - {file = "Babel-2.13.0.tar.gz", hash = "sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210"}, + {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, + {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, ] +[package.dependencies] +setuptools = {version = "*", markers = "python_version >= \"3.12\""} + [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -optional = false -python-versions = "*" -files = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] - [[package]] name = "beautifulsoup4" version = "4.12.2" @@ -131,33 +124,29 @@ lxml = ["lxml"] [[package]] name = "black" -version = "23.9.1" +version = "23.10.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.9.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301"}, - {file = "black-23.9.1-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100"}, - {file = "black-23.9.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71"}, - {file = "black-23.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7"}, - {file = "black-23.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80"}, - {file = "black-23.9.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f"}, - {file = "black-23.9.1-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe"}, - {file = "black-23.9.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186"}, - {file = "black-23.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f"}, - {file = "black-23.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300"}, - {file = "black-23.9.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948"}, - {file = "black-23.9.1-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855"}, - {file = "black-23.9.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204"}, - {file = "black-23.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377"}, - {file = "black-23.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573"}, - {file = "black-23.9.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c"}, - {file = "black-23.9.1-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325"}, - {file = "black-23.9.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393"}, - {file = "black-23.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9"}, - {file = "black-23.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f"}, - {file = "black-23.9.1-py3-none-any.whl", hash = "sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9"}, - {file = "black-23.9.1.tar.gz", hash = "sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d"}, + {file = "black-23.10.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69"}, + {file = "black-23.10.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916"}, + {file = "black-23.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc"}, + {file = "black-23.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173"}, + {file = "black-23.10.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0"}, + {file = "black-23.10.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace"}, + {file = "black-23.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb"}, + {file = "black-23.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce"}, + {file = "black-23.10.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a"}, + {file = "black-23.10.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1"}, + {file = "black-23.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad"}, + {file = "black-23.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884"}, + {file = "black-23.10.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9"}, + {file = "black-23.10.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7"}, + {file = "black-23.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d"}, + {file = "black-23.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982"}, + {file = "black-23.10.1-py3-none-any.whl", hash = "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe"}, + {file = "black-23.10.1.tar.gz", hash = "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"}, ] [package.dependencies] @@ -263,101 +252,101 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.3.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-win32.whl", hash = "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"}, - {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] @@ -546,13 +535,13 @@ files = [ [[package]] name = "docutils" -version = "0.18.1" +version = "0.17.1" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ - {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, - {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, ] [[package]] @@ -585,13 +574,13 @@ test = ["pytest (>=6)"] [[package]] name = "executing" -version = "2.0.0" +version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "executing-2.0.0-py2.py3-none-any.whl", hash = "sha256:06df6183df67389625f4e763921c6cf978944721abf3e714000200aab95b0657"}, - {file = "executing-2.0.0.tar.gz", hash = "sha256:0ff053696fdeef426cda5bd18eacd94f82c91f49823a2e9090124212ceea9b08"}, + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, ] [package.extras] @@ -613,19 +602,19 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "filelock" -version = "3.12.4" +version = "3.13.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"}, - {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] -typing = ["typing-extensions (>=4.7.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] [[package]] name = "flake8" @@ -645,73 +634,68 @@ pyflakes = ">=3.1.0,<3.2.0" [[package]] name = "greenlet" -version = "3.0.0" +version = "3.0.1" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" files = [ - {file = "greenlet-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a"}, - {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779"}, - {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9"}, - {file = "greenlet-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7"}, - {file = "greenlet-3.0.0-cp310-universal2-macosx_11_0_x86_64.whl", hash = "sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f"}, - {file = "greenlet-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b"}, - {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c"}, - {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362"}, - {file = "greenlet-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c"}, - {file = "greenlet-3.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1482fba7fbed96ea7842b5a7fc11d61727e8be75a077e603e8ab49d24e234383"}, - {file = "greenlet-3.0.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb"}, - {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35"}, - {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17"}, - {file = "greenlet-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6b5ce7f40f0e2f8b88c28e6691ca6806814157ff05e794cdd161be928550f4c"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf94aa539e97a8411b5ea52fc6ccd8371be9550c4041011a091eb8b3ca1d810"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80dcd3c938cbcac986c5c92779db8e8ce51a89a849c135172c88ecbdc8c056b7"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e52a712c38e5fb4fd68e00dc3caf00b60cb65634d50e32281a9d6431b33b4af1"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5539f6da3418c3dc002739cb2bb8d169056aa66e0c83f6bacae0cd3ac26b423"}, - {file = "greenlet-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:343675e0da2f3c69d3fb1e894ba0a1acf58f481f3b9372ce1eb465ef93cf6fed"}, - {file = "greenlet-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:abe1ef3d780de56defd0c77c5ba95e152f4e4c4e12d7e11dd8447d338b85a625"}, - {file = "greenlet-3.0.0-cp37-cp37m-win32.whl", hash = "sha256:e693e759e172fa1c2c90d35dea4acbdd1d609b6936115d3739148d5e4cd11947"}, - {file = "greenlet-3.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bdd696947cd695924aecb3870660b7545a19851f93b9d327ef8236bfc49be705"}, - {file = "greenlet-3.0.0-cp37-universal2-macosx_11_0_x86_64.whl", hash = "sha256:cc3e2679ea13b4de79bdc44b25a0c4fcd5e94e21b8f290791744ac42d34a0353"}, - {file = "greenlet-3.0.0-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:63acdc34c9cde42a6534518e32ce55c30f932b473c62c235a466469a710bfbf9"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a1a6244ff96343e9994e37e5b4839f09a0207d35ef6134dce5c20d260d0302c"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b822fab253ac0f330ee807e7485769e3ac85d5eef827ca224feaaefa462dc0d0"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8060b32d8586e912a7b7dac2d15b28dbbd63a174ab32f5bc6d107a1c4143f40b"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:621fcb346141ae08cb95424ebfc5b014361621b8132c48e538e34c3c93ac7365"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6bb36985f606a7c49916eff74ab99399cdfd09241c375d5a820bb855dfb4af9f"}, - {file = "greenlet-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10b5582744abd9858947d163843d323d0b67be9432db50f8bf83031032bc218d"}, - {file = "greenlet-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f351479a6914fd81a55c8e68963609f792d9b067fb8a60a042c585a621e0de4f"}, - {file = "greenlet-3.0.0-cp38-cp38-win32.whl", hash = "sha256:9de687479faec7db5b198cc365bc34addd256b0028956501f4d4d5e9ca2e240a"}, - {file = "greenlet-3.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:3fd2b18432e7298fcbec3d39e1a0aa91ae9ea1c93356ec089421fabc3651572b"}, - {file = "greenlet-3.0.0-cp38-universal2-macosx_11_0_x86_64.whl", hash = "sha256:3c0d36f5adc6e6100aedbc976d7428a9f7194ea79911aa4bf471f44ee13a9464"}, - {file = "greenlet-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a"}, - {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692"}, - {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4"}, - {file = "greenlet-3.0.0-cp39-cp39-win32.whl", hash = "sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9"}, - {file = "greenlet-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce"}, - {file = "greenlet-3.0.0-cp39-universal2-macosx_11_0_x86_64.whl", hash = "sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355"}, - {file = "greenlet-3.0.0.tar.gz", hash = "sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b"}, + {file = "greenlet-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63"}, + {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e"}, + {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846"}, + {file = "greenlet-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9"}, + {file = "greenlet-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234"}, + {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884"}, + {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94"}, + {file = "greenlet-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c"}, + {file = "greenlet-3.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5"}, + {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d"}, + {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445"}, + {file = "greenlet-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80ac992f25d10aaebe1ee15df45ca0d7571d0f70b645c08ec68733fb7a020206"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:337322096d92808f76ad26061a8f5fccb22b0809bea39212cd6c406f6a7060d2"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9934adbd0f6e476f0ecff3c94626529f344f57b38c9a541f87098710b18af0a"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4d815b794fd8868c4d67602692c21bf5293a75e4b607bb92a11e821e2b859a"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41bdeeb552d814bcd7fb52172b304898a35818107cc8778b5101423c9017b3de"}, + {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6e6061bf1e9565c29002e3c601cf68569c450be7fc3f7336671af7ddb4657166"}, + {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa24255ae3c0ab67e613556375a4341af04a084bd58764731972bcbc8baeba36"}, + {file = "greenlet-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:b489c36d1327868d207002391f662a1d163bdc8daf10ab2e5f6e41b9b96de3b1"}, + {file = "greenlet-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f33f3258aae89da191c6ebaa3bc517c6c4cbc9b9f689e5d8452f7aedbb913fa8"}, + {file = "greenlet-3.0.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d2905ce1df400360463c772b55d8e2518d0e488a87cdea13dd2c71dcb2a1fa16"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a02d259510b3630f330c86557331a3b0e0c79dac3d166e449a39363beaae174"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55d62807f1c5a1682075c62436702aaba941daa316e9161e4b6ccebbbf38bda3"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3fcc780ae8edbb1d050d920ab44790201f027d59fdbd21362340a85c79066a74"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eddd98afc726f8aee1948858aed9e6feeb1758889dfd869072d4465973f6bfd"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eabe7090db68c981fca689299c2d116400b553f4b713266b130cfc9e2aa9c5a9"}, + {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f2f6d303f3dee132b322a14cd8765287b8f86cdc10d2cb6a6fae234ea488888e"}, + {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d923ff276f1c1f9680d32832f8d6c040fe9306cbfb5d161b0911e9634be9ef0a"}, + {file = "greenlet-3.0.1-cp38-cp38-win32.whl", hash = "sha256:0b6f9f8ca7093fd4433472fd99b5650f8a26dcd8ba410e14094c1e44cd3ceddd"}, + {file = "greenlet-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:990066bff27c4fcf3b69382b86f4c99b3652bab2a7e685d968cd4d0cfc6f67c6"}, + {file = "greenlet-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ce85c43ae54845272f6f9cd8320d034d7a946e9773c693b27d620edec825e376"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ee2e967bd7ff85d84a2de09df10e021c9b38c7d91dead95b406ed6350c6997"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87c8ceb0cf8a5a51b8008b643844b7f4a8264a2c13fcbcd8a8316161725383fe"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6a8c9d4f8692917a3dc7eb25a6fb337bff86909febe2f793ec1928cd97bedfc"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fbc5b8f3dfe24784cee8ce0be3da2d8a79e46a276593db6868382d9c50d97b1"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85d2b77e7c9382f004b41d9c72c85537fac834fb141b0296942d52bf03fe4a3d"}, + {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:696d8e7d82398e810f2b3622b24e87906763b6ebfd90e361e88eb85b0e554dc8"}, + {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:329c5a2e5a0ee942f2992c5e3ff40be03e75f745f48847f118a3cfece7a28546"}, + {file = "greenlet-3.0.1-cp39-cp39-win32.whl", hash = "sha256:cf868e08690cb89360eebc73ba4be7fb461cfbc6168dd88e2fbbe6f31812cd57"}, + {file = "greenlet-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac4a39d1abae48184d420aa8e5e63efd1b75c8444dd95daa3e03f6c6310e9619"}, + {file = "greenlet-3.0.1.tar.gz", hash = "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b"}, ] [package.extras] @@ -720,13 +704,13 @@ test = ["objgraph", "psutil"] [[package]] name = "hypothesis" -version = "6.87.2" +version = "6.88.1" description = "A library for property-based testing" optional = false python-versions = ">=3.8" files = [ - {file = "hypothesis-6.87.2-py3-none-any.whl", hash = "sha256:6383a987d2f304cb5594d0a8763241990653299b9b9c149d65078852b38a71de"}, - {file = "hypothesis-6.87.2.tar.gz", hash = "sha256:8a00073528b96a7659afc5414b969453928e2a96f54674016a48372634d6bc60"}, + {file = "hypothesis-6.88.1-py3-none-any.whl", hash = "sha256:b45b8a651dfe4ce26f900ce6ccbce997d4fbec39ba03dd243516bf81fea8c0b8"}, + {file = "hypothesis-6.88.1.tar.gz", hash = "sha256:f4c2c004b9ec3e0e25332ad2cb6b91eba477a855557a7b5c6e79068809ff8b51"}, ] [package.dependencies] @@ -752,13 +736,13 @@ zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2023.3)"] [[package]] name = "identify" -version = "2.5.30" +version = "2.5.31" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.30-py2.py3-none-any.whl", hash = "sha256:afe67f26ae29bab007ec21b03d4114f41316ab9dd15aa8736a167481e108da54"}, - {file = "identify-2.5.30.tar.gz", hash = "sha256:f302a4256a15c849b91cfcdcec052a8ce914634b2f77ae87dad29cd749f2d88d"}, + {file = "identify-2.5.31-py2.py3-none-any.whl", hash = "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d"}, + {file = "identify-2.5.31.tar.gz", hash = "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75"}, ] [package.extras] @@ -818,13 +802,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.25.2" +version = "6.26.0" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.25.2-py3-none-any.whl", hash = "sha256:2e2ee359baba19f10251b99415bb39de1e97d04e1fab385646f24f0596510b77"}, - {file = "ipykernel-6.25.2.tar.gz", hash = "sha256:f468ddd1f17acb48c8ce67fcfa49ba6d46d4f9ac0438c1f441be7c3d1372230b"}, + {file = "ipykernel-6.26.0-py3-none-any.whl", hash = "sha256:3ba3dc97424b87b31bb46586b5167b3161b32d7820b9201a9e698c71e271602c"}, + {file = "ipykernel-6.26.0.tar.gz", hash = "sha256:553856658eb8430bbe9653ea041a41bff63e9606fc4628873fc92a6cf3abd404"}, ] [package.dependencies] @@ -851,25 +835,23 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.16.1" +version = "8.17.2" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" files = [ - {file = "ipython-8.16.1-py3-none-any.whl", hash = "sha256:0852469d4d579d9cd613c220af7bf0c9cc251813e12be647cb9d463939db9b1e"}, - {file = "ipython-8.16.1.tar.gz", hash = "sha256:ad52f58fca8f9f848e256c629eff888efc0528c12fe0f8ec14f33205f23ef938"}, + {file = "ipython-8.17.2-py3-none-any.whl", hash = "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444"}, + {file = "ipython-8.17.2.tar.gz", hash = "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb"}, ] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" pygments = ">=2.4.0" stack-data = "*" @@ -877,17 +859,17 @@ traitlets = ">=5" typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "isort" @@ -944,13 +926,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.19.1" +version = "4.19.2" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.19.1-py3-none-any.whl", hash = "sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e"}, - {file = "jsonschema-4.19.1.tar.gz", hash = "sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf"}, + {file = "jsonschema-4.19.2-py3-none-any.whl", hash = "sha256:eee9e502c788e89cb166d4d37f43084e3b64ab405c795c03d343a4dbc2c810fc"}, + {file = "jsonschema-4.19.2.tar.gz", hash = "sha256:c9ff4d7447eed9592c23a12ccee508baf0dd0d59650615e847feb6cdca74f392"}, ] [package.dependencies] @@ -1043,13 +1025,13 @@ testing = ["coverage", "ipykernel", "jupytext", "matplotlib", "nbdime", "nbforma [[package]] name = "jupyter-client" -version = "8.3.1" +version = "8.5.0" description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.3.1-py3-none-any.whl", hash = "sha256:5eb9f55eb0650e81de6b7e34308d8b92d04fe4ec41cd8193a913979e33d8e1a5"}, - {file = "jupyter_client-8.3.1.tar.gz", hash = "sha256:60294b2d5b869356c893f57b1a877ea6510d60d45cf4b38057f1672d85699ac9"}, + {file = "jupyter_client-8.5.0-py3-none-any.whl", hash = "sha256:c3877aac7257ec68d79b5c622ce986bd2a992ca42f6ddc9b4dd1da50e89f7028"}, + {file = "jupyter_client-8.5.0.tar.gz", hash = "sha256:e8754066510ce456358df363f97eae64b50860f30dc1fe8c6771440db3be9a63"}, ] [package.dependencies] @@ -1066,13 +1048,13 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.3.2" +version = "5.5.0" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.3.2-py3-none-any.whl", hash = "sha256:a4af53c3fa3f6330cebb0d9f658e148725d15652811d1c32dc0f63bb96f2e6d6"}, - {file = "jupyter_core-5.3.2.tar.gz", hash = "sha256:0c28db6cbe2c37b5b398e1a1a5b22f84fd64cd10afc1f6c05b02fb09481ba45f"}, + {file = "jupyter_core-5.5.0-py3-none-any.whl", hash = "sha256:e11e02cd8ae0a9de5c6c44abf5727df9f2581055afe00b22183f621ba3585805"}, + {file = "jupyter_core-5.5.0.tar.gz", hash = "sha256:880b86053bf298a8724994f95e99b99130659022a4f7f45f563084b6223861d3"}, ] [package.dependencies] @@ -1081,7 +1063,7 @@ pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_ traitlets = ">=5.3" [package.extras] -docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] [[package]] @@ -1450,17 +1432,6 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -optional = false -python-versions = "*" -files = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] - [[package]] name = "platformdirs" version = "3.11.0" @@ -1493,13 +1464,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.4.0" +version = "3.5.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.8" files = [ - {file = "pre_commit-3.4.0-py2.py3-none-any.whl", hash = "sha256:96d529a951f8b677f730a7212442027e8ba53f9b04d217c4c67dc56c393ad945"}, - {file = "pre_commit-3.4.0.tar.gz", hash = "sha256:6bbd5129a64cad4c0dfaeeb12cd8f7ea7e15b77028d985341478c8af3c759522"}, + {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, + {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, ] [package.dependencies] @@ -1525,25 +1496,27 @@ wcwidth = "*" [[package]] name = "psutil" -version = "5.9.5" +version = "5.9.6" description = "Cross-platform lib for process and system monitoring in Python." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, - {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, - {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, - {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, - {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, - {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, - {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, - {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, + {file = "psutil-5.9.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d"}, + {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c"}, + {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28"}, + {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017"}, + {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c"}, + {file = "psutil-5.9.6-cp27-none-win32.whl", hash = "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9"}, + {file = "psutil-5.9.6-cp27-none-win_amd64.whl", hash = "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac"}, + {file = "psutil-5.9.6-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a"}, + {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c"}, + {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4"}, + {file = "psutil-5.9.6-cp36-cp36m-win32.whl", hash = "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602"}, + {file = "psutil-5.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa"}, + {file = "psutil-5.9.6-cp37-abi3-win32.whl", hash = "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c"}, + {file = "psutil-5.9.6-cp37-abi3-win_amd64.whl", hash = "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a"}, + {file = "psutil-5.9.6-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57"}, + {file = "psutil-5.9.6.tar.gz", hash = "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a"}, ] [package.extras] @@ -1610,13 +1583,13 @@ pybtex = ">=0.16" [[package]] name = "pycodestyle" -version = "2.11.0" +version = "2.11.1" description = "Python style guide checker" optional = false python-versions = ">=3.8" files = [ - {file = "pycodestyle-2.11.0-py2.py3-none-any.whl", hash = "sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8"}, - {file = "pycodestyle-2.11.0.tar.gz", hash = "sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0"}, + {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, + {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, ] [[package]] @@ -1684,13 +1657,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pydata-sphinx-theme" -version = "0.14.1" +version = "0.13.3" description = "Bootstrap-based Sphinx theme from the PyData community" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "pydata_sphinx_theme-0.14.1-py3-none-any.whl", hash = "sha256:c436027bc76ae023df4e70517e3baf90cdda5a88ee46b818b5ef0cc3884aba04"}, - {file = "pydata_sphinx_theme-0.14.1.tar.gz", hash = "sha256:d8d4ac81252c16a002e835d21f0fea6d04cf3608e95045c816e8cc823e79b053"}, + {file = "pydata_sphinx_theme-0.13.3-py3-none-any.whl", hash = "sha256:bf41ca6c1c6216e929e28834e404bfc90e080b51915bbe7563b5e6fda70354f0"}, + {file = "pydata_sphinx_theme-0.13.3.tar.gz", hash = "sha256:827f16b065c4fd97e847c11c108bf632b7f2ff53a3bca3272f63f3f3ff782ecc"}, ] [package.dependencies] @@ -1700,14 +1673,13 @@ beautifulsoup4 = "*" docutils = "!=0.17.0" packaging = "*" pygments = ">=2.7" -sphinx = ">=5.0" +sphinx = ">=4.2" typing-extensions = "*" [package.extras] -a11y = ["pytest-playwright"] dev = ["nox", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml"] -doc = ["ablog (>=0.11.0rc2)", "colorama", "ipyleaflet", "jupyter_sphinx", "jupyterlite-sphinx", "linkify-it-py", "matplotlib", "myst-nb", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-autoapi", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube (<1.4)", "sphinxext-rediraffe", "xarray"] -test = ["pytest", "pytest-cov", "pytest-regressions"] +doc = ["ablog (>=0.11.0rc2)", "colorama", "ipyleaflet", "jupyter_sphinx", "linkify-it-py", "matplotlib", "myst-nb", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube", "sphinxext-rediraffe", "xarray"] +test = ["codecov", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "pyflakes" @@ -1736,13 +1708,13 @@ plugins = ["importlib-metadata"] [[package]] name = "pytest" -version = "7.4.2" +version = "7.4.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, - {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] @@ -2013,110 +1985,110 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rpds-py" -version = "0.10.4" +version = "0.10.6" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.10.4-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:e41824343c2c129599645373992b1ce17720bb8a514f04ff9567031e1c26951e"}, - {file = "rpds_py-0.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b9d8884d58ea8801e5906a491ab34af975091af76d1a389173db491ee7e316bb"}, - {file = "rpds_py-0.10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5db93f9017b384a4f194e1d89e1ce82d0a41b1fafdbbd3e0c8912baf13f2950f"}, - {file = "rpds_py-0.10.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c31ecfc53ac03dad4928a1712f3a2893008bfba1b3cde49e1c14ff67faae2290"}, - {file = "rpds_py-0.10.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f92d2372ec992c82fd7c74aa21e2a1910b3dcdc6a7e6392919a138f21d528a3"}, - {file = "rpds_py-0.10.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7ea49ddf51d5ec0c3cbd95190dd15e077a3153c8d4b22a33da43b5dd2b3c640"}, - {file = "rpds_py-0.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c27942722cd5039bbf5098c7e21935a96243fed00ea11a9589f3c6c6424bd84"}, - {file = "rpds_py-0.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08f07150c8ebbdbce1d2d51b8e9f4d588749a2af6a98035485ebe45c7ad9394e"}, - {file = "rpds_py-0.10.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f3331a3684192659fa1090bf2b448db928152fcba08222e58106f44758ef25f7"}, - {file = "rpds_py-0.10.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:efffa359cc69840c8793f0c05a7b663de6afa7b9078fa6c80309ee38b9db677d"}, - {file = "rpds_py-0.10.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:86e8d6ff15fa7a9590c0addaf3ce52fb58bda4299cab2c2d0afa404db6848dab"}, - {file = "rpds_py-0.10.4-cp310-none-win32.whl", hash = "sha256:8f90fc6dd505867514c8b8ef68a712dc0be90031a773c1ae2ad469f04062daef"}, - {file = "rpds_py-0.10.4-cp310-none-win_amd64.whl", hash = "sha256:9f9184744fb800c9f28e155a5896ecb54816296ee79d5d1978be6a2ae60f53c4"}, - {file = "rpds_py-0.10.4-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:72e9b1e92830c876cd49565d8404e4dcc9928302d348ea2517bc3f9e3a873a2a"}, - {file = "rpds_py-0.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3650eae998dc718960e90120eb45d42bd57b18b21b10cb9ee05f91bff2345d48"}, - {file = "rpds_py-0.10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f40413d2859737ce6d95c29ce2dde0ef7cdc3063b5830ae4342fef5922c3bba7"}, - {file = "rpds_py-0.10.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b953d11b544ca5f2705bb77b177d8e17ab1bfd69e0fd99790a11549d2302258c"}, - {file = "rpds_py-0.10.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28b4942ec7d9d6114c1e08cace0157db92ef674636a38093cab779ace5742d3a"}, - {file = "rpds_py-0.10.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e0e2e01c5f61ddf47e3ed2d1fe1c9136e780ca6222d57a2517b9b02afd4710c"}, - {file = "rpds_py-0.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:927e3461dae0c09b1f2e0066e50c1a9204f8a64a3060f596e9a6742d3b307785"}, - {file = "rpds_py-0.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e69bbe0ede8f7fe2616e779421bbdb37f025c802335a90f6416e4d98b368a37"}, - {file = "rpds_py-0.10.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cc688a59c100f038fa9fec9e4ab457c2e2d1fca350fe7ea395016666f0d0a2dc"}, - {file = "rpds_py-0.10.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ec001689402b9104700b50a005c2d3d0218eae90eaa8bdbbd776fe78fe8a74b7"}, - {file = "rpds_py-0.10.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:628fbb8be71a103499d10b189af7764996ab2634ed7b44b423f1e19901606e0e"}, - {file = "rpds_py-0.10.4-cp311-none-win32.whl", hash = "sha256:e3f9c9e5dd8eba4768e15f19044e1b5e216929a43a54b4ab329e103aed9f3eda"}, - {file = "rpds_py-0.10.4-cp311-none-win_amd64.whl", hash = "sha256:3bc561c183684636c0099f9c3fbab8c1671841942edbce784bb01b4707d17924"}, - {file = "rpds_py-0.10.4-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:36ff30385fb9fb3ac23a28bffdd4a230a5229ed5b15704b708b7c84bfb7fce51"}, - {file = "rpds_py-0.10.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:db0589e0bf41ff6ce284ab045ca89f27be1adf19e7bce26c2e7de6739a70c18b"}, - {file = "rpds_py-0.10.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c330cb125983c5d380fef4a4155248a276297c86d64625fdaf500157e1981c"}, - {file = "rpds_py-0.10.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d230fddc60caced271cc038e43e6fb8f4dd6b2dbaa44ac9763f2d76d05b0365a"}, - {file = "rpds_py-0.10.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a9e864ec051a58fdb6bb2e6da03942adb20273897bc70067aee283e62bbac4d"}, - {file = "rpds_py-0.10.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e41d5b334e8de4bc3f38843f31b2afa9a0c472ebf73119d3fd55cde08974bdf"}, - {file = "rpds_py-0.10.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5bb3f3cb6072c73e6ec1f865d8b80419b599f1597acf33f63fbf02252aab5a03"}, - {file = "rpds_py-0.10.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:576d48e1e45c211e99fc02655ade65c32a75d3e383ccfd98ce59cece133ed02c"}, - {file = "rpds_py-0.10.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b28b9668a22ca2cfca4433441ba9acb2899624a323787a509a3dc5fbfa79c49d"}, - {file = "rpds_py-0.10.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ddbd113a37307638f94be5ae232a325155fd24dbfae2c56455da8724b471e7be"}, - {file = "rpds_py-0.10.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd0ad98c7d72b0e4cbfe89cdfa12cd07d2fd6ed22864341cdce12b318a383442"}, - {file = "rpds_py-0.10.4-cp312-none-win32.whl", hash = "sha256:2a97406d5e08b7095428f01dac0d3c091dc072351151945a167e7968d2755559"}, - {file = "rpds_py-0.10.4-cp312-none-win_amd64.whl", hash = "sha256:aab24b9bbaa3d49e666e9309556591aa00748bd24ea74257a405f7fed9e8b10d"}, - {file = "rpds_py-0.10.4-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6c5ca3eb817fb54bfd066740b64a2b31536eb8fe0b183dc35b09a7bd628ed680"}, - {file = "rpds_py-0.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fd37ab9a24021821b715478357af1cf369d5a42ac7405e83e5822be00732f463"}, - {file = "rpds_py-0.10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2573ec23ad3a59dd2bc622befac845695972f3f2d08dc1a4405d017d20a6c225"}, - {file = "rpds_py-0.10.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:362faeae52dc6ccc50c0b6a01fa2ec0830bb61c292033f3749a46040b876f4ba"}, - {file = "rpds_py-0.10.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:40f6e53461b19ddbb3354fe5bcf3d50d4333604ae4bf25b478333d83ca68002c"}, - {file = "rpds_py-0.10.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6090ba604ea06b525a231450ae5d343917a393cbf50423900dea968daf61d16f"}, - {file = "rpds_py-0.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28e29dac59df890972f73c511948072897f512974714a803fe793635b80ff8c7"}, - {file = "rpds_py-0.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f82abb5c5b83dc30e96be99ce76239a030b62a73a13c64410e429660a5602bfd"}, - {file = "rpds_py-0.10.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a3628815fd170a64624001bfb4e28946fd515bd672e68a1902d9e0290186eaf3"}, - {file = "rpds_py-0.10.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:d37f27ad80f742ef82796af3fe091888864958ad0bc8bab03da1830fa00c6004"}, - {file = "rpds_py-0.10.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:255a23bded80605e9f3997753e3a4b89c9aec9efb07ec036b1ca81440efcc1a9"}, - {file = "rpds_py-0.10.4-cp38-none-win32.whl", hash = "sha256:049098dabfe705e9638c55a3321137a821399c50940041a6fcce267a22c70db2"}, - {file = "rpds_py-0.10.4-cp38-none-win_amd64.whl", hash = "sha256:aa45cc71bf23a3181b8aa62466b5a2b7b7fb90fdc01df67ca433cd4fce7ec94d"}, - {file = "rpds_py-0.10.4-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:3507c459767cf24c11e9520e2a37c89674266abe8e65453e5cb66398aa47ee7b"}, - {file = "rpds_py-0.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2603e084054351cc65097da326570102c4c5bd07426ba8471ceaefdb0b642cc9"}, - {file = "rpds_py-0.10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0f1d336786cb62613c72c00578c98e5bb8cd57b49c5bae5d4ab906ca7872f98"}, - {file = "rpds_py-0.10.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf032367f921201deaecf221d4cc895ea84b3decf50a9c73ee106f961885a0ad"}, - {file = "rpds_py-0.10.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f050ceffd8c730c1619a16bbf0b9cd037dcdb94b54710928ba38c7bde67e4a4"}, - {file = "rpds_py-0.10.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8709eb4ab477c533b7d0a76cd3065d7d95c9e25e6b9f6e27caeeb8c63e8799c9"}, - {file = "rpds_py-0.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc20dadb102140dff63529e08ce6f9745dbd36e673ebb2b1c4a63e134bca81c2"}, - {file = "rpds_py-0.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cd7da2adc721ccf19ac7ec86cae3a4fcaba03d9c477d5bd64ded6e9bb817bf3f"}, - {file = "rpds_py-0.10.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e5dba1c11e089b526379e74f6c636202e4c5bad9a48c7416502b8a5b0d026c91"}, - {file = "rpds_py-0.10.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ffd539d213c1ea2989ab92a5b9371ae7159c8c03cf2bcb9f2f594752f755ecd3"}, - {file = "rpds_py-0.10.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e791e3d13b14d0a7921804d0efe4d7bd15508bbcf8cb7a0c1ee1a27319a5f033"}, - {file = "rpds_py-0.10.4-cp39-none-win32.whl", hash = "sha256:2f2ac8bb01f705c5caaa7fe77ffd9b03f92f1b5061b94228f6ea5eaa0fca68ad"}, - {file = "rpds_py-0.10.4-cp39-none-win_amd64.whl", hash = "sha256:7c7ca791bedda059e5195cf7c6b77384657a51429357cdd23e64ac1d4973d6dc"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:9c7e7bd1fa1f535af71dfcd3700fc83a6dc261a1204f8f5327d8ffe82e52905d"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7089d8bfa8064b28b2e39f5af7bf12d42f61caed884e35b9b4ea9e6fb1175077"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1f191befea279cb9669b57be97ab1785781c8bab805900e95742ebfaa9cbf1d"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:98c0aecf661c175ce9cb17347fc51a5c98c3e9189ca57e8fcd9348dae18541db"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d81359911c3bb31c899c6a5c23b403bdc0279215e5b3bc0d2a692489fed38632"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83da147124499fe41ed86edf34b4e81e951b3fe28edcc46288aac24e8a5c8484"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49db6c0a0e6626c2b97f5e7f8f7074da21cbd8ec73340c25e839a2457c007efa"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:125776d5db15162fdd9135372bef7fe4fb7c5f5810cf25898eb74a06a0816aec"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:32819b662e3b4c26355a4403ea2f60c0a00db45b640fe722dd12db3d2ef807fb"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:3bd38b80491ef9686f719c1ad3d24d14fbd0e069988fdd4e7d1a6ffcdd7f4a13"}, - {file = "rpds_py-0.10.4-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2e79eeeff8394284b09577f36316d410525e0cf0133abb3de10660e704d3d38e"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:3e37f1f134037601eb4b1f46854194f0cc082435dac2ee3de11e51529f7831f2"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:ba3246c60303eab3d0e562addf25a983d60bddc36f4d1edc2510f056d19df255"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9123ba0f3f98ff79780eebca9984a2b525f88563844b740f94cffb9099701230"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d98802b78093c7083cc51f83da41a5be5a57d406798c9f69424bd75f8ae0812a"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:58bae860d1d116e6b4e1aad0cdc48a187d5893994f56d26db0c5534df7a47afd"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd7e62e7d5bcfa38a62d8397fba6d0428b970ab7954c2197501cd1624f7f0bbb"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83f5228459b84fa6279e4126a53abfdd73cd9cc183947ee5084153880f65d7"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4bcb1abecd998a72ad4e36a0fca93577fd0c059a6aacc44f16247031b98f6ff4"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:9e7b3ad9f53ea9e085b3d27286dd13f8290969c0a153f8a52c8b5c46002c374b"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:cbec8e43cace64e63398155dc585dc479a89fef1e57ead06c22d3441e1bd09c3"}, - {file = "rpds_py-0.10.4-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ad21c60fc880204798f320387164dcacc25818a7b4ec2a0bf6b6c1d57b007d23"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:6baea8a4f6f01e69e75cfdef3edd4a4d1c4b56238febbdf123ce96d09fbff010"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:94876c21512535955a960f42a155213315e6ab06a4ce8ce372341a2a1b143eeb"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cb55454a20d1b935f9eaab52e6ceab624a2efd8b52927c7ae7a43e02828dbe0"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13cbd79ccedc6b39c279af31ebfb0aec0467ad5d14641ddb15738bf6e4146157"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00a88003db3cc953f8656b59fc9af9d0637a1fb93c235814007988f8c153b2f2"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0f7f77a77c37159c9f417b8dd847f67a29e98c6acb52ee98fc6b91efbd1b2b6"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70563a1596d2e0660ca2cebb738443437fc0e38597e7cbb276de0a7363924a52"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e3ece9aa6d07e18c966f14b4352a4c6f40249f6174d3d2c694c1062e19c6adbb"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d5ad7b1a1f6964d19b1a8acfc14bf7864f39587b3e25c16ca04f6cd1815026b3"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:60018626e637528a1fa64bb3a2b3e46ab7bf672052316d61c3629814d5e65052"}, - {file = "rpds_py-0.10.4-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ae8a32ab77a84cc870bbfb60645851ca0f7d58fd251085ad67464b1445d632ca"}, - {file = "rpds_py-0.10.4.tar.gz", hash = "sha256:18d5ff7fbd305a1d564273e9eb22de83ae3cd9cd6329fddc8f12f6428a711a6a"}, + {file = "rpds_py-0.10.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:6bdc11f9623870d75692cc33c59804b5a18d7b8a4b79ef0b00b773a27397d1f6"}, + {file = "rpds_py-0.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26857f0f44f0e791f4a266595a7a09d21f6b589580ee0585f330aaccccb836e3"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7f5e15c953ace2e8dde9824bdab4bec50adb91a5663df08d7d994240ae6fa31"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61fa268da6e2e1cd350739bb61011121fa550aa2545762e3dc02ea177ee4de35"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c48f3fbc3e92c7dd6681a258d22f23adc2eb183c8cb1557d2fcc5a024e80b094"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0503c5b681566e8b722fe8c4c47cce5c7a51f6935d5c7012c4aefe952a35eed"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:734c41f9f57cc28658d98270d3436dba65bed0cfc730d115b290e970150c540d"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a5d7ed104d158c0042a6a73799cf0eb576dfd5fc1ace9c47996e52320c37cb7c"}, + {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e3df0bc35e746cce42579826b89579d13fd27c3d5319a6afca9893a9b784ff1b"}, + {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:73e0a78a9b843b8c2128028864901f55190401ba38aae685350cf69b98d9f7c9"}, + {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ed505ec6305abd2c2c9586a7b04fbd4baf42d4d684a9c12ec6110deefe2a063"}, + {file = "rpds_py-0.10.6-cp310-none-win32.whl", hash = "sha256:d97dd44683802000277bbf142fd9f6b271746b4846d0acaf0cefa6b2eaf2a7ad"}, + {file = "rpds_py-0.10.6-cp310-none-win_amd64.whl", hash = "sha256:b455492cab07107bfe8711e20cd920cc96003e0da3c1f91297235b1603d2aca7"}, + {file = "rpds_py-0.10.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e8cdd52744f680346ff8c1ecdad5f4d11117e1724d4f4e1874f3a67598821069"}, + {file = "rpds_py-0.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66414dafe4326bca200e165c2e789976cab2587ec71beb80f59f4796b786a238"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc435d059f926fdc5b05822b1be4ff2a3a040f3ae0a7bbbe672babb468944722"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8e7f2219cb72474571974d29a191714d822e58be1eb171f229732bc6fdedf0ac"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3953c6926a63f8ea5514644b7afb42659b505ece4183fdaaa8f61d978754349e"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2bb2e4826be25e72013916eecd3d30f66fd076110de09f0e750163b416500721"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bf347b495b197992efc81a7408e9a83b931b2f056728529956a4d0858608b80"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:102eac53bb0bf0f9a275b438e6cf6904904908562a1463a6fc3323cf47d7a532"}, + {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40f93086eef235623aa14dbddef1b9fb4b22b99454cb39a8d2e04c994fb9868c"}, + {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e22260a4741a0e7a206e175232867b48a16e0401ef5bce3c67ca5b9705879066"}, + {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4e56860a5af16a0fcfa070a0a20c42fbb2012eed1eb5ceeddcc7f8079214281"}, + {file = "rpds_py-0.10.6-cp311-none-win32.whl", hash = "sha256:0774a46b38e70fdde0c6ded8d6d73115a7c39d7839a164cc833f170bbf539116"}, + {file = "rpds_py-0.10.6-cp311-none-win_amd64.whl", hash = "sha256:4a5ee600477b918ab345209eddafde9f91c0acd931f3776369585a1c55b04c57"}, + {file = "rpds_py-0.10.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:5ee97c683eaface61d38ec9a489e353d36444cdebb128a27fe486a291647aff6"}, + {file = "rpds_py-0.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0713631d6e2d6c316c2f7b9320a34f44abb644fc487b77161d1724d883662e31"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5a53f5998b4bbff1cb2e967e66ab2addc67326a274567697379dd1e326bded7"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a555ae3d2e61118a9d3e549737bb4a56ff0cec88a22bd1dfcad5b4e04759175"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:945eb4b6bb8144909b203a88a35e0a03d22b57aefb06c9b26c6e16d72e5eb0f0"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:52c215eb46307c25f9fd2771cac8135d14b11a92ae48d17968eda5aa9aaf5071"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1b3cd23d905589cb205710b3988fc8f46d4a198cf12862887b09d7aaa6bf9b9"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64ccc28683666672d7c166ed465c09cee36e306c156e787acef3c0c62f90da5a"}, + {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:516a611a2de12fbea70c78271e558f725c660ce38e0006f75139ba337d56b1f6"}, + {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9ff93d3aedef11f9c4540cf347f8bb135dd9323a2fc705633d83210d464c579d"}, + {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d858532212f0650be12b6042ff4378dc2efbb7792a286bee4489eaa7ba010586"}, + {file = "rpds_py-0.10.6-cp312-none-win32.whl", hash = "sha256:3c4eff26eddac49d52697a98ea01b0246e44ca82ab09354e94aae8823e8bda02"}, + {file = "rpds_py-0.10.6-cp312-none-win_amd64.whl", hash = "sha256:150eec465dbc9cbca943c8e557a21afdcf9bab8aaabf386c44b794c2f94143d2"}, + {file = "rpds_py-0.10.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:cf693eb4a08eccc1a1b636e4392322582db2a47470d52e824b25eca7a3977b53"}, + {file = "rpds_py-0.10.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4134aa2342f9b2ab6c33d5c172e40f9ef802c61bb9ca30d21782f6e035ed0043"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e782379c2028a3611285a795b89b99a52722946d19fc06f002f8b53e3ea26ea9"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f6da6d842195fddc1cd34c3da8a40f6e99e4a113918faa5e60bf132f917c247"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a9fe992887ac68256c930a2011255bae0bf5ec837475bc6f7edd7c8dfa254e"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b788276a3c114e9f51e257f2a6f544c32c02dab4aa7a5816b96444e3f9ffc336"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa1afc70a02645809c744eefb7d6ee8fef7e2fad170ffdeacca267fd2674f13"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bddd4f91eede9ca5275e70479ed3656e76c8cdaaa1b354e544cbcf94c6fc8ac4"}, + {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:775049dfa63fb58293990fc59473e659fcafd953bba1d00fc5f0631a8fd61977"}, + {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c6c45a2d2b68c51fe3d9352733fe048291e483376c94f7723458cfd7b473136b"}, + {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0699ab6b8c98df998c3eacf51a3b25864ca93dab157abe358af46dc95ecd9801"}, + {file = "rpds_py-0.10.6-cp38-none-win32.whl", hash = "sha256:ebdab79f42c5961682654b851f3f0fc68e6cc7cd8727c2ac4ffff955154123c1"}, + {file = "rpds_py-0.10.6-cp38-none-win_amd64.whl", hash = "sha256:24656dc36f866c33856baa3ab309da0b6a60f37d25d14be916bd3e79d9f3afcf"}, + {file = "rpds_py-0.10.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:0898173249141ee99ffcd45e3829abe7bcee47d941af7434ccbf97717df020e5"}, + {file = "rpds_py-0.10.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9e9184fa6c52a74a5521e3e87badbf9692549c0fcced47443585876fcc47e469"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5752b761902cd15073a527b51de76bbae63d938dc7c5c4ad1e7d8df10e765138"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99a57006b4ec39dbfb3ed67e5b27192792ffb0553206a107e4aadb39c5004cd5"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09586f51a215d17efdb3a5f090d7cbf1633b7f3708f60a044757a5d48a83b393"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e225a6a14ecf44499aadea165299092ab0cba918bb9ccd9304eab1138844490b"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2039f8d545f20c4e52713eea51a275e62153ee96c8035a32b2abb772b6fc9e5"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:34ad87a831940521d462ac11f1774edf867c34172010f5390b2f06b85dcc6014"}, + {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dcdc88b6b01015da066da3fb76545e8bb9a6880a5ebf89e0f0b2e3ca557b3ab7"}, + {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:25860ed5c4e7f5e10c496ea78af46ae8d8468e0be745bd233bab9ca99bfd2647"}, + {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7854a207ef77319ec457c1eb79c361b48807d252d94348305db4f4b62f40f7f3"}, + {file = "rpds_py-0.10.6-cp39-none-win32.whl", hash = "sha256:e6fcc026a3f27c1282c7ed24b7fcac82cdd70a0e84cc848c0841a3ab1e3dea2d"}, + {file = "rpds_py-0.10.6-cp39-none-win_amd64.whl", hash = "sha256:e98c4c07ee4c4b3acf787e91b27688409d918212dfd34c872201273fdd5a0e18"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:68fe9199184c18d997d2e4293b34327c0009a78599ce703e15cd9a0f47349bba"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3339eca941568ed52d9ad0f1b8eb9fe0958fa245381747cecf2e9a78a5539c42"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a360cfd0881d36c6dc271992ce1eda65dba5e9368575663de993eeb4523d895f"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:031f76fc87644a234883b51145e43985aa2d0c19b063e91d44379cd2786144f8"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f36a9d751f86455dc5278517e8b65580eeee37d61606183897f122c9e51cef3"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:052a832078943d2b2627aea0d19381f607fe331cc0eb5df01991268253af8417"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:023574366002bf1bd751ebaf3e580aef4a468b3d3c216d2f3f7e16fdabd885ed"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:defa2c0c68734f4a82028c26bcc85e6b92cced99866af118cd6a89b734ad8e0d"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879fb24304ead6b62dbe5034e7b644b71def53c70e19363f3c3be2705c17a3b4"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:53c43e10d398e365da2d4cc0bcaf0854b79b4c50ee9689652cdc72948e86f487"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3777cc9dea0e6c464e4b24760664bd8831738cc582c1d8aacf1c3f546bef3f65"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:40578a6469e5d1df71b006936ce95804edb5df47b520c69cf5af264d462f2cbb"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:cf71343646756a072b85f228d35b1d7407da1669a3de3cf47f8bbafe0c8183a4"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10f32b53f424fc75ff7b713b2edb286fdbfc94bf16317890260a81c2c00385dc"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:81de24a1c51cfb32e1fbf018ab0bdbc79c04c035986526f76c33e3f9e0f3356c"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac17044876e64a8ea20ab132080ddc73b895b4abe9976e263b0e30ee5be7b9c2"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8a78bd4879bff82daef48c14d5d4057f6856149094848c3ed0ecaf49f5aec2"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78ca33811e1d95cac8c2e49cb86c0fb71f4d8409d8cbea0cb495b6dbddb30a55"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c63c3ef43f0b3fb00571cff6c3967cc261c0ebd14a0a134a12e83bdb8f49f21f"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:7fde6d0e00b2fd0dbbb40c0eeec463ef147819f23725eda58105ba9ca48744f4"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:79edd779cfc46b2e15b0830eecd8b4b93f1a96649bcb502453df471a54ce7977"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9164ec8010327ab9af931d7ccd12ab8d8b5dc2f4c6a16cbdd9d087861eaaefa1"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d29ddefeab1791e3c751e0189d5f4b3dbc0bbe033b06e9c333dca1f99e1d523e"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:30adb75ecd7c2a52f5e76af50644b3e0b5ba036321c390b8e7ec1bb2a16dd43c"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd609fafdcdde6e67a139898196698af37438b035b25ad63704fd9097d9a3482"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6eef672de005736a6efd565577101277db6057f65640a813de6c2707dc69f396"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cf4393c7b41abbf07c88eb83e8af5013606b1cdb7f6bc96b1b3536b53a574b8"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad857f42831e5b8d41a32437f88d86ead6c191455a3499c4b6d15e007936d4cf"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7360573f1e046cb3b0dceeb8864025aa78d98be4bb69f067ec1c40a9e2d9df"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d08f63561c8a695afec4975fae445245386d645e3e446e6f260e81663bfd2e38"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:f0f17f2ce0f3529177a5fff5525204fad7b43dd437d017dd0317f2746773443d"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:442626328600bde1d09dc3bb00434f5374948838ce75c41a52152615689f9403"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e9616f5bd2595f7f4a04b67039d890348ab826e943a9bfdbe4938d0eba606971"}, + {file = "rpds_py-0.10.6.tar.gz", hash = "sha256:4ce5a708d65a8dbf3748d2474b580d606b1b9f91b5c6ab2a316e0b0cf7a4ba50"}, ] [[package]] @@ -2181,20 +2153,20 @@ files = [ [[package]] name = "sphinx" -version = "5.0.2" +version = "4.5.0" description = "Python documentation generator" optional = false python-versions = ">=3.6" files = [ - {file = "Sphinx-5.0.2-py3-none-any.whl", hash = "sha256:d3e57663eed1d7c5c50895d191fdeda0b54ded6f44d5621b50709466c338d1e8"}, - {file = "Sphinx-5.0.2.tar.gz", hash = "sha256:b18e978ea7565720f26019c702cd85c84376e948370f1cd43d60265010e1c7b0"}, + {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, + {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, ] [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=1.3" colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.19" +docutils = ">=0.14,<0.18" imagesize = "*" importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} Jinja2 = ">=2.3" @@ -2211,8 +2183,8 @@ sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.950)", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest (>=4.6)", "typed-ast"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] [[package]] name = "sphinx-autodoc-typehints" @@ -2372,6 +2344,27 @@ code-style = ["black", "flake8 (>=3.7.0,<3.8.0)", "pre-commit (==1.17.0)"] rtd = ["myst-parser", "sphinx (>=3.0)", "sphinx-book-theme"] testing = ["coverage (<5.0)", "jupyter-book", "pytest (>=5.4,<6.0)", "pytest-cov (>=2.8,<3.0)", "pytest-regressions"] +[[package]] +name = "sphinx-panels" +version = "0.6.0" +description = "A sphinx extension for creating panels in a grid layout." +optional = false +python-versions = "*" +files = [ + {file = "sphinx-panels-0.6.0.tar.gz", hash = "sha256:d36dcd26358117e11888f7143db4ac2301ebe90873ac00627bf1fe526bf0f058"}, + {file = "sphinx_panels-0.6.0-py3-none-any.whl", hash = "sha256:bd64afaf85c07f8096d21c8247fc6fd757e339d1be97832c8832d6ae5ed2e61d"}, +] + +[package.dependencies] +docutils = "*" +sphinx = ">=2,<5" + +[package.extras] +code-style = ["pre-commit (>=2.7.0,<2.8.0)"] +live-dev = ["sphinx-autobuild", "web-compile (>=0.2.0,<0.3.0)"] +testing = ["pytest (>=6.0.1,<6.1.0)", "pytest-regressions (>=2.0.1,<2.1.0)"] +themes = ["myst-parser (>=0.12.9,<0.13.0)", "pydata-sphinx-theme (>=0.4.0,<0.5.0)", "sphinx-book-theme (>=0.0.36,<0.1.0)", "sphinx-rtd-theme"] + [[package]] name = "sphinx-thebe" version = "0.2.1" @@ -2412,18 +2405,15 @@ sphinx = ["matplotlib", "myst-nb", "numpy", "sphinx-book-theme", "sphinx-design" [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.7" +version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"}, - {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"}, + {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, + {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] @@ -2448,36 +2438,30 @@ Sphinx = ">=2.1" [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.5" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." optional = false -python-versions = ">=3.9" +python-versions = ">=3.5" files = [ - {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"}, - {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"}, + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.4" +version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"}, - {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"}, + {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, + {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] @@ -2498,96 +2482,99 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.6" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." optional = false -python-versions = ">=3.9" +python-versions = ">=3.5" files = [ - {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"}, - {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"}, + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.9" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." optional = false -python-versions = ">=3.9" +python-versions = ">=3.5" files = [ - {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"}, - {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"}, + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.21" +version = "2.0.23" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e7dc99b23e33c71d720c4ae37ebb095bebebbd31a24b7d99dfc4753d2803ede"}, - {file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f0c4ee579acfe6c994637527c386d1c22eb60bc1c1d36d940d8477e482095d4"}, - {file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f7d57a7e140efe69ce2d7b057c3f9a595f98d0bbdfc23fd055efdfbaa46e3a5"}, - {file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca38746eac23dd7c20bec9278d2058c7ad662b2f1576e4c3dbfcd7c00cc48fa"}, - {file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3cf229704074bce31f7f47d12883afee3b0a02bb233a0ba45ddbfe542939cca4"}, - {file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb87f763b5d04a82ae84ccff25554ffd903baafba6698e18ebaf32561f2fe4aa"}, - {file = "SQLAlchemy-2.0.21-cp310-cp310-win32.whl", hash = "sha256:89e274604abb1a7fd5c14867a412c9d49c08ccf6ce3e1e04fffc068b5b6499d4"}, - {file = "SQLAlchemy-2.0.21-cp310-cp310-win_amd64.whl", hash = "sha256:e36339a68126ffb708dc6d1948161cea2a9e85d7d7b0c54f6999853d70d44430"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bf8eebccc66829010f06fbd2b80095d7872991bfe8415098b9fe47deaaa58063"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b977bfce15afa53d9cf6a632482d7968477625f030d86a109f7bdfe8ce3c064a"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ff3dc2f60dbf82c9e599c2915db1526d65415be323464f84de8db3e361ba5b9"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44ac5c89b6896f4740e7091f4a0ff2e62881da80c239dd9408f84f75a293dae9"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:87bf91ebf15258c4701d71dcdd9c4ba39521fb6a37379ea68088ce8cd869b446"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b69f1f754d92eb1cc6b50938359dead36b96a1dcf11a8670bff65fd9b21a4b09"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-win32.whl", hash = "sha256:af520a730d523eab77d754f5cf44cc7dd7ad2d54907adeb3233177eeb22f271b"}, - {file = "SQLAlchemy-2.0.21-cp311-cp311-win_amd64.whl", hash = "sha256:141675dae56522126986fa4ca713739d00ed3a6f08f3c2eb92c39c6dfec463ce"}, - {file = "SQLAlchemy-2.0.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7614f1eab4336df7dd6bee05bc974f2b02c38d3d0c78060c5faa4cd1ca2af3b8"}, - {file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d59cb9e20d79686aa473e0302e4a82882d7118744d30bb1dfb62d3c47141b3ec"}, - {file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a95aa0672e3065d43c8aa80080cdd5cc40fe92dc873749e6c1cf23914c4b83af"}, - {file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8c323813963b2503e54d0944813cd479c10c636e3ee223bcbd7bd478bf53c178"}, - {file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:419b1276b55925b5ac9b4c7044e999f1787c69761a3c9756dec6e5c225ceca01"}, - {file = "SQLAlchemy-2.0.21-cp37-cp37m-win32.whl", hash = "sha256:4615623a490e46be85fbaa6335f35cf80e61df0783240afe7d4f544778c315a9"}, - {file = "SQLAlchemy-2.0.21-cp37-cp37m-win_amd64.whl", hash = "sha256:cca720d05389ab1a5877ff05af96551e58ba65e8dc65582d849ac83ddde3e231"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b4eae01faee9f2b17f08885e3f047153ae0416648f8e8c8bd9bc677c5ce64be9"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3eb7c03fe1cd3255811cd4e74db1ab8dca22074d50cd8937edf4ef62d758cdf4"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2d494b6a2a2d05fb99f01b84cc9af9f5f93bf3e1e5dbdafe4bed0c2823584c1"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b19ae41ef26c01a987e49e37c77b9ad060c59f94d3b3efdfdbf4f3daaca7b5fe"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fc6b15465fabccc94bf7e38777d665b6a4f95efd1725049d6184b3a39fd54880"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:014794b60d2021cc8ae0f91d4d0331fe92691ae5467a00841f7130fe877b678e"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-win32.whl", hash = "sha256:0268256a34806e5d1c8f7ee93277d7ea8cc8ae391f487213139018b6805aeaf6"}, - {file = "SQLAlchemy-2.0.21-cp38-cp38-win_amd64.whl", hash = "sha256:73c079e21d10ff2be54a4699f55865d4b275fd6c8bd5d90c5b1ef78ae0197301"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:785e2f2c1cb50d0a44e2cdeea5fd36b5bf2d79c481c10f3a88a8be4cfa2c4615"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c111cd40910ffcb615b33605fc8f8e22146aeb7933d06569ac90f219818345ef"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cba4e7369de663611ce7460a34be48e999e0bbb1feb9130070f0685e9a6b66"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50a69067af86ec7f11a8e50ba85544657b1477aabf64fa447fd3736b5a0a4f67"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ccb99c3138c9bde118b51a289d90096a3791658da9aea1754667302ed6564f6e"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:513fd5b6513d37e985eb5b7ed89da5fd9e72354e3523980ef00d439bc549c9e9"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-win32.whl", hash = "sha256:f9fefd6298433b6e9188252f3bff53b9ff0443c8fde27298b8a2b19f6617eeb9"}, - {file = "SQLAlchemy-2.0.21-cp39-cp39-win_amd64.whl", hash = "sha256:2e617727fe4091cedb3e4409b39368f424934c7faa78171749f704b49b4bb4ce"}, - {file = "SQLAlchemy-2.0.21-py3-none-any.whl", hash = "sha256:ea7da25ee458d8f404b93eb073116156fd7d8c2a776d8311534851f28277b4ce"}, - {file = "SQLAlchemy-2.0.21.tar.gz", hash = "sha256:05b971ab1ac2994a14c56b35eaaa91f86ba080e9ad481b20d99d77f381bb6258"}, -] - -[package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""} + {file = "SQLAlchemy-2.0.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:638c2c0b6b4661a4fd264f6fb804eccd392745c5887f9317feb64bb7cb03b3ea"}, + {file = "SQLAlchemy-2.0.23-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3b5036aa326dc2df50cba3c958e29b291a80f604b1afa4c8ce73e78e1c9f01d"}, + {file = "SQLAlchemy-2.0.23-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:787af80107fb691934a01889ca8f82a44adedbf5ef3d6ad7d0f0b9ac557e0c34"}, + {file = "SQLAlchemy-2.0.23-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c14eba45983d2f48f7546bb32b47937ee2cafae353646295f0e99f35b14286ab"}, + {file = "SQLAlchemy-2.0.23-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0666031df46b9badba9bed00092a1ffa3aa063a5e68fa244acd9f08070e936d3"}, + {file = "SQLAlchemy-2.0.23-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:89a01238fcb9a8af118eaad3ffcc5dedaacbd429dc6fdc43fe430d3a941ff965"}, + {file = "SQLAlchemy-2.0.23-cp310-cp310-win32.whl", hash = "sha256:cabafc7837b6cec61c0e1e5c6d14ef250b675fa9c3060ed8a7e38653bd732ff8"}, + {file = "SQLAlchemy-2.0.23-cp310-cp310-win_amd64.whl", hash = "sha256:87a3d6b53c39cd173990de2f5f4b83431d534a74f0e2f88bd16eabb5667e65c6"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d5578e6863eeb998980c212a39106ea139bdc0b3f73291b96e27c929c90cd8e1"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62d9e964870ea5ade4bc870ac4004c456efe75fb50404c03c5fd61f8bc669a72"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c80c38bd2ea35b97cbf7c21aeb129dcbebbf344ee01a7141016ab7b851464f8e"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75eefe09e98043cff2fb8af9796e20747ae870c903dc61d41b0c2e55128f958d"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd45a5b6c68357578263d74daab6ff9439517f87da63442d244f9f23df56138d"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a86cb7063e2c9fb8e774f77fbf8475516d270a3e989da55fa05d08089d77f8c4"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-win32.whl", hash = "sha256:b41f5d65b54cdf4934ecede2f41b9c60c9f785620416e8e6c48349ab18643855"}, + {file = "SQLAlchemy-2.0.23-cp311-cp311-win_amd64.whl", hash = "sha256:9ca922f305d67605668e93991aaf2c12239c78207bca3b891cd51a4515c72e22"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d0f7fb0c7527c41fa6fcae2be537ac137f636a41b4c5a4c58914541e2f436b45"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7c424983ab447dab126c39d3ce3be5bee95700783204a72549c3dceffe0fc8f4"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f508ba8f89e0a5ecdfd3761f82dda2a3d7b678a626967608f4273e0dba8f07ac"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6463aa765cf02b9247e38b35853923edbf2f6fd1963df88706bc1d02410a5577"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e599a51acf3cc4d31d1a0cf248d8f8d863b6386d2b6782c5074427ebb7803bda"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fd54601ef9cc455a0c61e5245f690c8a3ad67ddb03d3b91c361d076def0b4c60"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-win32.whl", hash = "sha256:42d0b0290a8fb0165ea2c2781ae66e95cca6e27a2fbe1016ff8db3112ac1e846"}, + {file = "SQLAlchemy-2.0.23-cp312-cp312-win_amd64.whl", hash = "sha256:227135ef1e48165f37590b8bfc44ed7ff4c074bf04dc8d6f8e7f1c14a94aa6ca"}, + {file = "SQLAlchemy-2.0.23-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:14aebfe28b99f24f8a4c1346c48bc3d63705b1f919a24c27471136d2f219f02d"}, + {file = "SQLAlchemy-2.0.23-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e983fa42164577d073778d06d2cc5d020322425a509a08119bdcee70ad856bf"}, + {file = "SQLAlchemy-2.0.23-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e0dc9031baa46ad0dd5a269cb7a92a73284d1309228be1d5935dac8fb3cae24"}, + {file = "SQLAlchemy-2.0.23-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5f94aeb99f43729960638e7468d4688f6efccb837a858b34574e01143cf11f89"}, + {file = "SQLAlchemy-2.0.23-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:63bfc3acc970776036f6d1d0e65faa7473be9f3135d37a463c5eba5efcdb24c8"}, + {file = "SQLAlchemy-2.0.23-cp37-cp37m-win32.whl", hash = "sha256:f48ed89dd11c3c586f45e9eec1e437b355b3b6f6884ea4a4c3111a3358fd0c18"}, + {file = "SQLAlchemy-2.0.23-cp37-cp37m-win_amd64.whl", hash = "sha256:1e018aba8363adb0599e745af245306cb8c46b9ad0a6fc0a86745b6ff7d940fc"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:64ac935a90bc479fee77f9463f298943b0e60005fe5de2aa654d9cdef46c54df"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c4722f3bc3c1c2fcc3702dbe0016ba31148dd6efcd2a2fd33c1b4897c6a19693"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4af79c06825e2836de21439cb2a6ce22b2ca129bad74f359bddd173f39582bf5"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:683ef58ca8eea4747737a1c35c11372ffeb84578d3aab8f3e10b1d13d66f2bc4"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d4041ad05b35f1f4da481f6b811b4af2f29e83af253bf37c3c4582b2c68934ab"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aeb397de65a0a62f14c257f36a726945a7f7bb60253462e8602d9b97b5cbe204"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-win32.whl", hash = "sha256:42ede90148b73fe4ab4a089f3126b2cfae8cfefc955c8174d697bb46210c8306"}, + {file = "SQLAlchemy-2.0.23-cp38-cp38-win_amd64.whl", hash = "sha256:964971b52daab357d2c0875825e36584d58f536e920f2968df8d581054eada4b"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:616fe7bcff0a05098f64b4478b78ec2dfa03225c23734d83d6c169eb41a93e55"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e680527245895aba86afbd5bef6c316831c02aa988d1aad83c47ffe92655e74"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9585b646ffb048c0250acc7dad92536591ffe35dba624bb8fd9b471e25212a35"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4895a63e2c271ffc7a81ea424b94060f7b3b03b4ea0cd58ab5bb676ed02f4221"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cc1d21576f958c42d9aec68eba5c1a7d715e5fc07825a629015fe8e3b0657fb0"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:967c0b71156f793e6662dd839da54f884631755275ed71f1539c95bbada9aaab"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-win32.whl", hash = "sha256:0a8c6aa506893e25a04233bc721c6b6cf844bafd7250535abb56cb6cc1368884"}, + {file = "SQLAlchemy-2.0.23-cp39-cp39-win_amd64.whl", hash = "sha256:f3420d00d2cb42432c1d0e44540ae83185ccbbc67a6054dcc8ab5387add6620b"}, + {file = "SQLAlchemy-2.0.23-py3-none-any.whl", hash = "sha256:31952bbc527d633b9479f5f81e8b9dfada00b91d6baba021a869095f1a97006d"}, + {file = "SQLAlchemy-2.0.23.tar.gz", hash = "sha256:c1bda93cbbe4aa2aa0aa8655c5aeda505cd219ff3e8da91d1d329e143e4aff69"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} typing-extensions = ">=4.2.0" [package.extras] aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"] asyncio = ["greenlet (!=0.4.17)"] asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] @@ -2598,7 +2585,7 @@ mssql-pyodbc = ["pyodbc"] mypy = ["mypy (>=0.910)"] mysql = ["mysqlclient (>=1.4.0)"] mysql-connector = ["mysql-connector-python"] -oracle = ["cx-oracle (>=7)"] +oracle = ["cx-oracle (>=8)"] oracle-oracledb = ["oracledb (>=1.0.1)"] postgresql = ["psycopg2 (>=2.7)"] postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] @@ -2676,18 +2663,18 @@ files = [ [[package]] name = "traitlets" -version = "5.11.2" +version = "5.13.0" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.11.2-py3-none-any.whl", hash = "sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae"}, - {file = "traitlets-5.11.2.tar.gz", hash = "sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e"}, + {file = "traitlets-5.13.0-py3-none-any.whl", hash = "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619"}, + {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.5.1)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.6.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "typing-extensions" @@ -2716,13 +2703,13 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "urllib3" -version = "2.0.6" +version = "2.0.7" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.6-py3-none-any.whl", hash = "sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2"}, - {file = "urllib3-2.0.6.tar.gz", hash = "sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564"}, + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, ] [package.extras] @@ -2733,13 +2720,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.24.5" +version = "20.24.6" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.5-py3-none-any.whl", hash = "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b"}, - {file = "virtualenv-20.24.5.tar.gz", hash = "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752"}, + {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"}, + {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"}, ] [package.dependencies] @@ -2753,24 +2740,24 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "wcwidth" -version = "0.2.8" +version = "0.2.9" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.8-py2.py3-none-any.whl", hash = "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704"}, - {file = "wcwidth-0.2.8.tar.gz", hash = "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"}, + {file = "wcwidth-0.2.9-py2.py3-none-any.whl", hash = "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223"}, + {file = "wcwidth-0.2.9.tar.gz", hash = "sha256:a675d1a4a2d24ef67096a04b85b02deeecd8e226f57b5e3a72dbb9ed99d27da8"}, ] [[package]] name = "wheel" -version = "0.41.2" +version = "0.41.3" description = "A built-package format for Python" optional = false python-versions = ">=3.7" files = [ - {file = "wheel-0.41.2-py3-none-any.whl", hash = "sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8"}, - {file = "wheel-0.41.2.tar.gz", hash = "sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"}, + {file = "wheel-0.41.3-py3-none-any.whl", hash = "sha256:488609bc63a29322326e05560731bf7bfea8e48ad646e1f5e40d366607de0942"}, + {file = "wheel-0.41.3.tar.gz", hash = "sha256:4d4987ce51a49370ea65c0bfd2234e8ce80a12780820d9dc462597a6e60d0841"}, ] [package.extras] @@ -2794,4 +2781,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 4" -content-hash = "e9195db68e2736fcbd460999b14f2b9e4efcaa9da2b244dad0fac86462bd001a" +content-hash = "f970a4c8b838843c6123c703e1a92b5f32e414f2f3609da74c826ae55dbd031c" diff --git a/pyproject.toml b/pyproject.toml index dfbed1a1..ef00bc5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ dunamai = "^1.12.0" hypothesis = "^6.54.2" jupyter-book = "^0.15.0" sphinx-autodoc-typehints = "^1.17.0" +sphinx-panels = "^0.6.0" pydantic = "^1.10.0" [tool.black] From 89e54dff54717257439d89721cdaa0fc7b09981c Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Fri, 3 Nov 2023 07:23:03 +0100 Subject: [PATCH 02/39] Update Python version for docs --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 7795c6f8..a038766b 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -6,7 +6,7 @@ version: 2 build: os: ubuntu-20.04 tools: - python: "3.9" + python: "3.10" sphinx: configuration: docs/requirements.txt From e7ed602cead2fd5df1b8964a07d0d0a292437039 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Fri, 3 Nov 2023 09:04:57 +0100 Subject: [PATCH 03/39] Ruff format --- .pre-commit-config.yaml | 10 ++-- expression/collections/array.py | 44 ++++----------- expression/collections/asyncseq.py | 8 +-- expression/collections/block.py | 84 ++++++++--------------------- expression/collections/map.py | 40 ++++---------- expression/collections/maptree.py | 56 +++++-------------- expression/collections/seq.py | 56 +++++-------------- expression/core/aiotools.py | 4 +- expression/core/builder.py | 3 +- expression/core/compose.py | 4 +- expression/core/curry.py | 4 +- expression/core/fn.py | 4 +- expression/core/mailbox.py | 4 +- expression/core/option.py | 32 +++-------- expression/core/pipe.py | 6 +-- expression/core/result.py | 44 ++++----------- expression/core/typing.py | 4 +- expression/core/union.py | 18 ++----- expression/effect/option.py | 7 +-- expression/effect/result.py | 7 +-- expression/effect/seq.py | 8 +-- expression/extra/option/pipeline.py | 8 +-- expression/extra/parser.py | 40 ++++---------- expression/extra/result/catch.py | 8 +-- expression/extra/result/pipeline.py | 8 +-- expression/system/cancellation.py | 8 +-- poetry.lock | 49 +++++++++-------- pyproject.toml | 4 +- 28 files changed, 160 insertions(+), 412 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0a1119a6..9a203d0d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,14 +3,10 @@ repos: - hooks: - id: ruff args: ["--fix"] - + - id: ruff-format + args: [--check] repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.287 - - hooks: - - id: black - exclude: ^docs/ - repo: https://github.com/psf/black - rev: 23.1.0 + rev: v0.1.3 - hooks: - id: pyright name: pyright diff --git a/expression/collections/array.py b/expression/collections/array.py index 4386051b..629b893e 100644 --- a/expression/collections/array.py +++ b/expression/collections/array.py @@ -99,9 +99,7 @@ class TypeCode(Enum): Any = "a" -def array_from_typecode( - type_code: TypeCode, initializer: Iterable[Any] | None -) -> _Array[Any]: +def array_from_typecode(type_code: TypeCode, initializer: Iterable[Any] | None) -> _Array[Any]: arr: _Array[Any] = list(initializer if initializer else []) if type_code == TypeCode.Byte: return bytearray(arr) @@ -200,9 +198,7 @@ def map(self, mapping: Callable[[_TSource], _TResult]) -> TypedArray[_TResult]: result = builtins.map(mapping, self.value) return TypedArray(result) - def choose( - self, chooser: Callable[[_TSource], Option[_TResult]] - ) -> TypedArray[_TResult]: + def choose(self, chooser: Callable[[_TSource], Option[_TResult]]) -> TypedArray[_TResult]: """Choose items from the list. Applies the given function to each element of the list. Returns @@ -222,9 +218,7 @@ def mapper(x: _TSource) -> TypedArray[_TResult]: return self.collect(mapper) - def collect( - self, mapping: Callable[[_TSource], TypedArray[_TResult]] - ) -> TypedArray[_TResult]: + def collect(self, mapping: Callable[[_TSource], TypedArray[_TResult]]) -> TypedArray[_TResult]: mapped = builtins.map(mapping, self.value) xs = (y for x in mapped for y in x) return TypedArray(xs) @@ -255,13 +249,9 @@ def filter(self, predicate: Callable[[_TSource], bool]) -> TypedArray[_TSource]: A list containing only the elements that satisfy the predicate. """ - return TypedArray( - builtins.filter(predicate, self.value), typecode=self.typecode - ) + return TypedArray(builtins.filter(predicate, self.value), typecode=self.typecode) - def fold( - self, folder: Callable[[_TState, _TSource], _TState], state: _TState - ) -> _TState: + def fold(self, folder: Callable[[_TState, _TSource], _TState], state: _TState) -> _TState: """Fold array. Applies a function to each element of the array, @@ -363,9 +353,7 @@ def skip(self, count: int) -> TypedArray[_TSource]: def skip_last(self, count: int) -> TypedArray[_TSource]: return TypedArray(self.value[:-count]) - def sort( - self: TypedArray[_TSourceSortable], reverse: bool = False - ) -> TypedArray[_TSourceSortable]: + def sort(self: TypedArray[_TSourceSortable], reverse: bool = False) -> TypedArray[_TSourceSortable]: """Sort array directly. Returns a new sorted collection. @@ -378,9 +366,7 @@ def sort( """ return TypedArray(builtins.sorted(self.value, reverse=reverse)) - def sort_with( - self, func: Callable[[_TSource], Any], reverse: bool = False - ) -> TypedArray[_TSource]: + def sort_with(self, func: Callable[[_TSource], Any], reverse: bool = False) -> TypedArray[_TSource]: """Sort array with supplied function. Returns a new sorted collection. @@ -498,9 +484,7 @@ def __repr__(self) -> str: @curry_flip(1) -def map( - source: TypedArray[_TSource], mapper: Callable[[_TSource], _TResult] -) -> TypedArray[_TResult]: +def map(source: TypedArray[_TSource], mapper: Callable[[_TSource], _TResult]) -> TypedArray[_TResult]: """Map array. Builds a new array whose elements are the results of applying @@ -521,9 +505,7 @@ def empty() -> TypedArray[Any]: @curry_flip(1) -def filter( - source: TypedArray[_TSource], predicate: Callable[[_TSource], bool] -) -> TypedArray[_TSource]: +def filter(source: TypedArray[_TSource], predicate: Callable[[_TSource], bool]) -> TypedArray[_TSource]: """Filter array. Returns a new array containing only the elements of the @@ -612,9 +594,7 @@ def sum(source: TypedArray[_TSourceSum]) -> int: @curry_flip(1) -def sum_by( - source: TypedArray[_TSource], projection: Callable[[_TSource], _TSourceSum] -) -> int: +def sum_by(source: TypedArray[_TSource], projection: Callable[[_TSource], _TSourceSum]) -> int: return builtins.sum(source.map(projection).value) @@ -664,9 +644,7 @@ def try_head(source: TypedArray[_TSource]) -> Option[_TSource]: @curry_flip(1) -def unfold( - state: _TState, generator: Callable[[_TState], Option[tuple[_TSource, _TState]]] -) -> TypedArray[_TSource]: +def unfold(state: _TState, generator: Callable[[_TState], Option[tuple[_TSource, _TState]]]) -> TypedArray[_TSource]: """Unfold array. Returns a list that contains the elements generated by the diff --git a/expression/collections/asyncseq.py b/expression/collections/asyncseq.py index d192fb95..eb2982b3 100644 --- a/expression/collections/asyncseq.py +++ b/expression/collections/asyncseq.py @@ -86,9 +86,7 @@ async def range(*args: int, **kw: int) -> AsyncIterable[int]: yield value -def filter( - predicate: Callable[[TSource], bool] -) -> Callable[[AsyncIterable[TSource]], AsyncIterable[TSource]]: +def filter(predicate: Callable[[TSource], bool]) -> Callable[[AsyncIterable[TSource]], AsyncIterable[TSource]]: async def _filter(source: AsyncIterable[TSource]) -> AsyncIterable[TSource]: async for value in source: if predicate(value): @@ -97,9 +95,7 @@ async def _filter(source: AsyncIterable[TSource]) -> AsyncIterable[TSource]: return _filter -def map( - mapper: Callable[[TSource], TResult] -) -> Callable[[AsyncIterable[TSource]], AsyncIterable[TResult]]: +def map(mapper: Callable[[TSource], TResult]) -> Callable[[AsyncIterable[TSource]], AsyncIterable[TResult]]: async def _map(source: AsyncIterable[TSource]) -> AsyncIterable[TResult]: async for value in source: yield mapper(value) diff --git a/expression/collections/block.py b/expression/collections/block.py index 779854fd..2c18f037 100644 --- a/expression/collections/block.py +++ b/expression/collections/block.py @@ -110,9 +110,7 @@ def append(self, other: Block[_TSource]) -> Block[_TSource]: """Append other block to end of the block.""" return Block(self._value + other._value) - def choose( - self, chooser: Callable[[_TSource], Option[_TResult]] - ) -> Block[_TResult]: + def choose(self, chooser: Callable[[_TSource], Option[_TResult]]) -> Block[_TResult]: """Choose items from the list. Applies the given function to each element of the list. Returns @@ -132,9 +130,7 @@ def mapper(x: _TSource) -> Block[_TResult]: return self.collect(mapper) - def collect( - self, mapping: Callable[[_TSource], Block[_TResult]] - ) -> Block[_TResult]: + def collect(self, mapping: Callable[[_TSource], Block[_TResult]]) -> Block[_TResult]: mapped = builtins.map(mapping, self._value) xs = (y for x in mapped for y in x) return Block(xs) @@ -163,9 +159,7 @@ def filter(self, predicate: Callable[[_TSource], bool]) -> Block[_TSource]: """ return Block(builtins.filter(predicate, self._value)) - def fold( - self, folder: Callable[[_TState, _TSource], _TState], state: _TState - ) -> _TState: + def fold(self, folder: Callable[[_TState, _TSource], _TState], state: _TState) -> _TState: """Fold block. Applies a function to each element of the collection, @@ -264,9 +258,7 @@ def map(self, mapping: Callable[[_TSource], _TResult]) -> Block[_TResult]: return Block((*builtins.map(mapping, self),)) @overload - def starmap( - self: Block[tuple[_T1, _T2]], mapping: Callable[[_T1, _T2], _TResult] - ) -> Block[_TResult]: + def starmap(self: Block[tuple[_T1, _T2]], mapping: Callable[[_T1, _T2], _TResult]) -> Block[_TResult]: ... @overload @@ -301,9 +293,7 @@ def starmap(self: Block[Any], mapping: Callable[..., Any]) -> Block[Any]: def sum(self: Block[_TSourceSum | Literal[0]]) -> _TSourceSum | Literal[0]: return builtins.sum(self._value) - def sum_by( - self: Block[_TSourceSum], projection: Callable[[_TSourceSum], _TResult] - ) -> _TResult: + def sum_by(self: Block[_TSourceSum], projection: Callable[[_TSourceSum], _TResult]) -> _TResult: return pipe(self, sum_by(projection)) def mapi(self, mapping: Callable[[int, _TSource], _TResult]) -> Block[_TResult]: @@ -337,9 +327,7 @@ def of_seq(xs: Iterable[_TSource]) -> Block[_TSource]: def of_option(option: Option[_TSource]) -> Block[_TSource]: return of_option(option) - def partition( - self, predicate: Callable[[_TSource], bool] - ) -> tuple[Block[_TSource], Block[_TSource]]: + def partition(self, predicate: Callable[[_TSource], bool]) -> tuple[Block[_TSource], Block[_TSource]]: """Partition block. Splits the collection into two collections, containing the @@ -429,9 +417,7 @@ def tail(self) -> Block[_TSource]: _, *tail = self._value return Block(tail) - def sort( - self: Block[_TSourceSortable], reverse: bool = False - ) -> Block[_TSourceSortable]: + def sort(self: Block[_TSourceSortable], reverse: bool = False) -> Block[_TSourceSortable]: """Sort list directly. Returns a new sorted collection. @@ -444,9 +430,7 @@ def sort( """ return Block(builtins.sorted(self._value, reverse=reverse)) - def sort_with( - self, func: Callable[[_TSource], Any], reverse: bool = False - ) -> Block[_TSource]: + def sort_with(self, func: Callable[[_TSource], Any], reverse: bool = False) -> Block[_TSource]: """Sort list with supplied function. Returns a new sorted collection. @@ -509,9 +493,7 @@ def try_head(self) -> Option[_TSource]: return Nothing @staticmethod - def unfold( - generator: Callable[[_TState], Option[tuple[_TSource, _TState]]], state: _TState - ) -> Block[_TSource]: + def unfold(generator: Callable[[_TState], Option[tuple[_TSource, _TState]]], state: _TState) -> Block[_TSource]: """Unfold block. Returns a list that contains the elements generated by the @@ -591,16 +573,12 @@ def append(source: Block[_TSource], other: Block[_TSource]) -> Block[_TSource]: @curry_flip(1) -def choose( - source: Block[_TSource], chooser: Callable[[_TSource], Option[_TResult]] -) -> Block[_TResult]: +def choose(source: Block[_TSource], chooser: Callable[[_TSource], Option[_TResult]]) -> Block[_TResult]: return source.choose(chooser) @curry_flip(1) -def collect( - source: Block[_TSource], mapping: Callable[[_TSource], Block[_TResult]] -) -> Block[_TResult]: +def collect(source: Block[_TSource], mapping: Callable[[_TSource], Block[_TResult]]) -> Block[_TResult]: """Collect block. For each element of the list, applies the given function. @@ -637,9 +615,7 @@ def cons(head: _TSource, tail: Block[_TSource]) -> Block[_TSource]: @curry_flip(1) -def filter( - source: Block[_TSource], predicate: Callable[[_TSource], bool] -) -> Block[_TSource]: +def filter(source: Block[_TSource], predicate: Callable[[_TSource], bool]) -> Block[_TSource]: """Filter elements in block. Returns a new collection containing only the elements of the @@ -750,9 +726,7 @@ def is_empty(source: Block[Any]) -> bool: @curry_flip(1) -def map( - source: Block[_TSource], mapper: Callable[[_TSource], _TResult] -) -> Block[_TResult]: +def map(source: Block[_TSource], mapper: Callable[[_TSource], _TResult]) -> Block[_TResult]: """Map list. Builds a new collection whose elements are the results of applying @@ -798,16 +772,12 @@ def reduce( @overload -def starmap( - mapper: Callable[[_T1, _T2], _TResult] -) -> Callable[[Block[tuple[_T1, _T2]]], Block[_TResult]]: +def starmap(mapper: Callable[[_T1, _T2], _TResult]) -> Callable[[Block[tuple[_T1, _T2]]], Block[_TResult]]: ... @overload -def starmap( - mapper: Callable[[_T1, _T2, _T3], _TResult] -) -> Callable[[Block[tuple[_T1, _T2, _T3]]], Block[_TResult]]: +def starmap(mapper: Callable[[_T1, _T2, _T3], _TResult]) -> Callable[[Block[tuple[_T1, _T2, _T3]]], Block[_TResult]]: ... @@ -838,22 +808,16 @@ def mapper_(args: tuple[Any, ...]) -> Any: return map(mapper_) -def map2( - mapper: Callable[[_T1, _T2], _TResult] -) -> Callable[[Block[tuple[_T1, _T2]]], Block[_TResult]]: +def map2(mapper: Callable[[_T1, _T2], _TResult]) -> Callable[[Block[tuple[_T1, _T2]]], Block[_TResult]]: return starmap(mapper) -def map3( - mapper: Callable[[_T1, _T2, _T3], _TResult] -) -> Callable[[Block[tuple[_T1, _T2, _T3]]], Block[_TResult]]: +def map3(mapper: Callable[[_T1, _T2, _T3], _TResult]) -> Callable[[Block[tuple[_T1, _T2, _T3]]], Block[_TResult]]: return starmap(mapper) @curry_flip(1) -def mapi( - source: Block[_TSource], mapper: Callable[[int, _TSource], _TResult] -) -> Block[_TResult]: +def mapi(source: Block[_TSource], mapper: Callable[[int, _TSource], _TResult]) -> Block[_TResult]: """Map list with index. Builds a new collection whose elements are the results of @@ -980,9 +944,7 @@ def sort( @curry_flip(1) -def sort_with( - source: Block[_TSource], func: Callable[[_TSource], Any], reverse: bool = False -) -> Block[_TSource]: +def sort_with(source: Block[_TSource], func: Callable[[_TSource], Any], reverse: bool = False) -> Block[_TSource]: """Returns a new collection sorted using "func" key function. Args: @@ -1001,9 +963,7 @@ def sum(source: Block[_TSourceSum | Literal[0]]) -> _TSourceSum | Literal[0]: @curry_flip(1) -def sum_by( - source: Block[_TSourceSum], projection: Callable[[_TSourceSum], _TResult] -) -> _TResult: +def sum_by(source: Block[_TSourceSum], projection: Callable[[_TSourceSum], _TResult]) -> _TResult: xs = source.map(projection) return builtins.sum(xs) # type: ignore @@ -1062,9 +1022,7 @@ def try_head(source: Block[_TSource]) -> Option[_TSource]: @curry_flip(1) -def unfold( - state: _TState, generator: Callable[[_TState], Option[tuple[_TSource, _TState]]] -) -> Block[_TSource]: +def unfold(state: _TState, generator: Callable[[_TState], Option[tuple[_TSource, _TState]]]) -> Block[_TSource]: """Unfold block. Returns a list that contains the elements generated by the diff --git a/expression/collections/map.py b/expression/collections/map.py index ac79539c..ff3b343b 100644 --- a/expression/collections/map.py +++ b/expression/collections/map.py @@ -54,9 +54,7 @@ def create(ie: Iterable[tuple[Key, Value]]) -> Map[Key, Value]: def contains_key(self, key: Key) -> bool: return maptree.mem(key, self._tree) - def change( - self, key: Key, f: Callable[[Option[Value]], Option[Value]] - ) -> Map[Key, Value]: + def change(self, key: Key, f: Callable[[Option[Value]], Option[Value]]) -> Map[Key, Value]: return Map(maptree.change(key, f, self._tree)) @staticmethod @@ -93,14 +91,10 @@ def iterate(self, f: Callable[[Key, Value], None]) -> None: # def MapRange (f:'Value->'Result) = # return Map<'Key, 'Result>(comparer, maptree.map f tree) - def fold( - self, folder: Callable[[Result, tuple[Key, Value]], Result], state: Result - ) -> Result: + def fold(self, folder: Callable[[Result, tuple[Key, Value]], Result], state: Result) -> Result: return maptree.fold(folder, state, self._tree) - def fold_back( - self, folder: Callable[[tuple[Key, Value], Result], Result], state: Result - ) -> Result: + def fold_back(self, folder: Callable[[tuple[Key, Value], Result], Result], state: Result) -> Result: return maptree.fold_back(folder, self._tree, state) def map(self, mapping: Callable[[Key, Value], Result]) -> Map[Key, Result]: @@ -119,9 +113,7 @@ def map(self, mapping: Callable[[Key, Value], Result]) -> Map[Key, Result]: """ return Map(maptree.map(mapping, self._tree)) - def partition( - self, predicate: Callable[[Key, Value], bool] - ) -> tuple[Map[Key, Value], Map[Key, Value]]: + def partition(self, predicate: Callable[[Key, Value], bool]) -> tuple[Map[Key, Value], Map[Key, Value]]: r1, r2 = maptree.partition(predicate, self._tree) return Map(r1), Map(r2) @@ -167,9 +159,7 @@ def try_get_value(self, key: Key, value: list[Value]): def try_find(self, key: Key) -> Option[Value]: return maptree.try_find(key, self._tree) - def try_pick( - self, chooser: Callable[[Key, Value], Option[Result]] - ) -> Option[Result]: + def try_pick(self, chooser: Callable[[Key, Value], Option[Result]]) -> Option[Result]: return maptree.try_pick(chooser, self._tree) @staticmethod @@ -286,9 +276,7 @@ def add(table: Map[Key, Value], key: Key, value: Value) -> Map[Key, Value]: @curry_flip(1) -def change( - table: Map[Key, Value], key: Key, fn: Callable[[Option[Value]], Option[Value]] -) -> Map[Key, Value]: +def change(table: Map[Key, Value], key: Key, fn: Callable[[Option[Value]], Option[Value]]) -> Map[Key, Value]: """Change element in map. Returns a new map with the value stored under key changed @@ -354,9 +342,7 @@ def _iterate(table: Map[Key, Value]) -> None: @curry_flip(1) -def try_pick( - table: Map[Key, Value], chooser: Callable[[Key, Value], Option[Result]] -) -> Option[Result]: +def try_pick(table: Map[Key, Value], chooser: Callable[[Key, Value], Option[Result]]) -> Option[Result]: """Pick element in map. Searches the map looking for the first element where the given @@ -375,9 +361,7 @@ def try_pick( @curry_flip(1) -def pick( - table: Map[Key, Value], chooser: Callable[[Key, Value], Option[Result]] -) -> Result: +def pick(table: Map[Key, Value], chooser: Callable[[Key, Value], Option[Result]]) -> Result: for res in table.try_pick(chooser): return res else: @@ -404,9 +388,7 @@ def exists(table: Map[Key, Value], predicate: Callable[[Key, Value], bool]) -> b @curry_flip(1) -def filter( - table: Map[Key, Value], predicate: Callable[[Key, Value], bool] -) -> Map[Key, Value]: +def filter(table: Map[Key, Value], predicate: Callable[[Key, Value], bool]) -> Map[Key, Value]: return table.filter(predicate) @@ -416,9 +398,7 @@ def for_all(table: Map[Key, Value], predicate: Callable[[Key, Value], bool]) -> @curry_flip(1) -def map( - table: Map[Key, Value], mapping: Callable[[Key, Value], Result] -) -> Map[Key, Result]: +def map(table: Map[Key, Value], mapping: Callable[[Key, Value], Result]) -> Map[Key, Result]: return table.map(mapping) diff --git a/expression/collections/maptree.py b/expression/collections/maptree.py index c7baa4f6..fcfa7a1e 100644 --- a/expression/collections/maptree.py +++ b/expression/collections/maptree.py @@ -88,23 +88,17 @@ def height(m: MapTree[Key, Value]) -> int: TOLERANCE = 2 -def mk( - left: MapTree[Key, Value], key: Key, value: Value, right: MapTree[Key, Value] -) -> MapTree[Key, Value]: +def mk(left: MapTree[Key, Value], key: Key, value: Value, right: MapTree[Key, Value]) -> MapTree[Key, Value]: hl = height(left) hr = height(right) m = hr if hl < hr else hl if m == 0: # m=0 ~ is_empty(l) and is_empty(r) return Some(MapTreeLeaf(key, value)) else: - return Some( - MapTreeNode(key, value, left, right, m + 1) - ) # new map is higher by 1 than the highest + return Some(MapTreeNode(key, value, left, right, m + 1)) # new map is higher by 1 than the highest -def rebalance( - t1: MapTree[Key, Value], k: Key, v: Value, t2: MapTree[Key, Value] -) -> MapTree[Key, Value]: +def rebalance(t1: MapTree[Key, Value], k: Key, v: Value, t2: MapTree[Key, Value]) -> MapTree[Key, Value]: t1h = height(t1) t2h = height(t2) if t2h > t1h + TOLERANCE: # right is heavier than left @@ -230,9 +224,7 @@ def partition( return partition_aux(predicate, m, (empty, empty)) -def filter1( - predicate: Callable[[Key, Value], bool], k: Key, v: Value, acc: MapTree[Key, Value] -) -> MapTree[Key, Value]: +def filter1(predicate: Callable[[Key, Value], bool], k: Key, v: Value, acc: MapTree[Key, Value]) -> MapTree[Key, Value]: if predicate(k, v): return add(k, v, acc) else: @@ -256,15 +248,11 @@ def filter_aux( return acc -def filter( - f: Callable[[Key, Value], bool], m: MapTree[Key, Value] -) -> MapTree[Key, Value]: +def filter(f: Callable[[Key, Value], bool], m: MapTree[Key, Value]) -> MapTree[Key, Value]: return filter_aux(f, m, empty) -def splice_out_successor( - m: MapTree[Key, Value] -) -> tuple[Key, Value, Option[MapTreeLeaf[Key, Value]]]: +def splice_out_successor(m: MapTree[Key, Value]) -> tuple[Key, Value, Option[MapTreeLeaf[Key, Value]]]: for m2 in m.to_list(): if isinstance(m2, MapTreeNode): mn = m2 @@ -304,9 +292,7 @@ def remove(k: Key, m: MapTree[Key, Value]) -> Option[MapTreeLeaf[Key, Value]]: return empty -def change( - k: Key, u: Callable[[Option[Value]], Option[Value]], m: MapTree[Key, Value] -) -> MapTree[Key, Value]: +def change(k: Key, u: Callable[[Option[Value]], Option[Value]], m: MapTree[Key, Value]) -> MapTree[Key, Value]: for m2 in m.to_list(): if isinstance(m2, MapTreeNode): mn = m2 @@ -375,9 +361,7 @@ def iter(fn: Callable[[Key, Value], None], m: MapTree[Key, Value]) -> None: fn(m2.key, m2.value) -def try_pick( - f: Callable[[Key, Value], Option[Result]], m: MapTree[Key, Value] -) -> Option[Result]: +def try_pick(f: Callable[[Key, Value], Option[Result]], m: MapTree[Key, Value]) -> Option[Result]: for m2 in m.to_list(): if isinstance(m2, MapTreeNode): mn = m2 @@ -418,9 +402,7 @@ def forall(f: Callable[[Key, Value], bool], m: MapTree[Key, Value]) -> bool: return True -def map( - f: Callable[[Key, Value], Result], m: MapTree[Key, Value] -) -> MapTree[Key, Result]: +def map(f: Callable[[Key, Value], Result], m: MapTree[Key, Value]) -> MapTree[Key, Result]: for m2 in m.to_list(): if isinstance(m2, MapTreeNode): mn = m2 @@ -434,9 +416,7 @@ def map( return empty -def fold_back( - f: Callable[[tuple[Key, Value], Result], Result], m: MapTree[Key, Value], x: Result -) -> Result: +def fold_back(f: Callable[[tuple[Key, Value], Result], Result], m: MapTree[Key, Value], x: Result) -> Result: for m2 in m.to_list(): if isinstance(m2, MapTreeNode): mn = m2 @@ -449,9 +429,7 @@ def fold_back( return x -def fold( - f: Callable[[Result, tuple[Key, Value]], Result], x: Result, m: MapTree[Key, Value] -) -> Result: +def fold(f: Callable[[Result, tuple[Key, Value]], Result], x: Result, m: MapTree[Key, Value]) -> Result: for m2 in m.to_list(): if isinstance(m2, MapTreeNode): mn = m2 @@ -465,9 +443,7 @@ def fold( def to_list(m: MapTree[Key, Value]) -> Block[tuple[Key, Value]]: - def loop( - m: MapTree[Key, Value], acc: Block[tuple[Key, Value]] - ) -> Block[tuple[Key, Value]]: + def loop(m: MapTree[Key, Value], acc: Block[tuple[Key, Value]]) -> Block[tuple[Key, Value]]: for m2 in m.to_list(): if isinstance(m2, MapTreeNode): mn = m2 @@ -488,9 +464,7 @@ def folder(acc: MapTree[Key, Value], kv: tuple[Key, Value]): return xs.fold(folder, empty) -def mk_from_iterator( - acc: MapTree[Key, Value], e: Iterator[tuple[Key, Value]] -) -> MapTree[Key, Value]: +def mk_from_iterator(acc: MapTree[Key, Value], e: Iterator[tuple[Key, Value]]) -> MapTree[Key, Value]: try: (x, y) = next(e) except StopIteration: @@ -536,9 +510,7 @@ def __next__(self) -> tuple[Key, Value]: rest = self.stack.tail() for m in self.stack.head(): if isinstance(m, MapTreeNode): - failwith( - "Please report error: Map iterator, unexpected stack for next()" - ) + failwith("Please report error: Map iterator, unexpected stack for next()") else: self.stack = collapseLHS(rest) return m.key, m.value diff --git a/expression/collections/seq.py b/expression/collections/seq.py index 9edb1623..58ca2b7e 100644 --- a/expression/collections/seq.py +++ b/expression/collections/seq.py @@ -132,9 +132,7 @@ def empty() -> Seq[_TSource]: """Returns empty sequence.""" return Seq() - def fold( - self, folder: Callable[[_TState, _TSource], _TState], state: _TState - ) -> _TState: + def fold(self, folder: Callable[[_TState, _TSource], _TState], state: _TState) -> _TState: """Fold sequence. Applies a function to each element of the collection, @@ -177,9 +175,7 @@ def map(self, mapper: Callable[[_TSource], _TResult]) -> Seq[_TResult]: return Seq(pipe(self, map(mapper))) @overload - def starmap( - self: Seq[tuple[_T1, _T2]], mapping: Callable[[_T1, _T2], _TResult] - ) -> Seq[_TResult]: + def starmap(self: Seq[tuple[_T1, _T2]], mapping: Callable[[_T1, _T2], _TResult]) -> Seq[_TResult]: ... @overload @@ -248,9 +244,7 @@ def range(start: int, stop: int, step: int) -> Iterable[int]: def range(*args: int, **kw: int) -> Iterable[int]: return range(*args, **kw) - def scan( - self, scanner: Callable[[_TState, _TSource], _TState], state: _TState - ) -> Iterable[_TState]: + def scan(self, scanner: Callable[[_TState, _TSource], _TState], state: _TState) -> Iterable[_TState]: """Scan sequence. Like fold, but computes on-demand and returns the sequence of @@ -413,9 +407,7 @@ def _(source: Iterable[_TSource]) -> Iterable[_TSource]: @curry_flip(1) -def choose( - source: Iterable[_TSource], chooser: Callable[[_TSource], Option[_TResult]] -) -> Iterable[_TResult]: +def choose(source: Iterable[_TSource], chooser: Callable[[_TSource], Option[_TResult]]) -> Iterable[_TResult]: """Choose items from the sequence. Applies the given function to each element of the list. Returns @@ -489,9 +481,7 @@ def delay(generator: Callable[[], Iterable[_TSource]]) -> Iterable[_TSource]: @curry_flip(1) -def filter( - source: Iterable[_TSource], predicate: Callable[[_TSource], bool] -) -> Iterable[_TSource]: +def filter(source: Iterable[_TSource], predicate: Callable[[_TSource], bool]) -> Iterable[_TSource]: """Filter sequence. Filters the sequence to a new sequence containing only the @@ -562,9 +552,7 @@ def _fold_back(state: _TState) -> _TState: The state object after the folding function is applied to each element of the sequence. """ - return functools.reduce( - lambda x, y: folder(y, x), reversed(list(source)), state - ) + return functools.reduce(lambda x, y: folder(y, x), reversed(list(source)), state) return _fold_back @@ -639,9 +627,7 @@ def length(source: Seq[Any]) -> int: @curry_flip(1) -def map( - source: Iterable[_TSource], mapper: Callable[[_TSource], _TResult] -) -> Iterable[_TResult]: +def map(source: Iterable[_TSource], mapper: Callable[[_TSource], _TResult]) -> Iterable[_TResult]: """Map source sequence. Builds a new collection whose elements are the results of @@ -664,9 +650,7 @@ def gen(): @overload -def starmap( - mapper: Callable[[_T1, _T2], _TResult] -) -> Callable[[Iterable[tuple[_T1, _T2]]], Iterable[_TResult]]: +def starmap(mapper: Callable[[_T1, _T2], _TResult]) -> Callable[[Iterable[tuple[_T1, _T2]]], Iterable[_TResult]]: ... @@ -704,22 +688,16 @@ def mapper_(args: tuple[Any, ...]) -> Any: return map(mapper_) -def map2( - mapper: Callable[[_T1, _T2], _TResult] -) -> Callable[[Iterable[tuple[_T1, _T2]]], Iterable[_TResult]]: +def map2(mapper: Callable[[_T1, _T2], _TResult]) -> Callable[[Iterable[tuple[_T1, _T2]]], Iterable[_TResult]]: return starmap(mapper) -def map3( - mapper: Callable[[_T1, _T2, _T3], _TResult] -) -> Callable[[Iterable[tuple[_T1, _T2, _T3]]], Iterable[_TResult]]: +def map3(mapper: Callable[[_T1, _T2, _T3], _TResult]) -> Callable[[Iterable[tuple[_T1, _T2, _T3]]], Iterable[_TResult]]: return starmap(mapper) @curry_flip(1) -def mapi( - source: Iterable[_TSource], mapping: Callable[[int, _TSource], _TResult] -) -> Iterable[_TResult]: +def mapi(source: Iterable[_TSource], mapping: Callable[[int, _TSource], _TResult]) -> Iterable[_TResult]: """Map list with index. Builds a new collection whose elements are the results of @@ -765,9 +743,7 @@ def min(source: Iterable[_TSupportsLessThan]) -> _TSupportsLessThan: @curry_flip(1) -def min_by( - source: Iterable[_TSource], projection: Callable[[_TSource], _TSupportsLessThan] -) -> _TSupportsLessThan: +def min_by(source: Iterable[_TSource], projection: Callable[[_TSource], _TSupportsLessThan]) -> _TSupportsLessThan: return builtins.min(projection(x) for x in source) @@ -868,9 +844,7 @@ def sum(source: Iterable[_TSupportsSum]) -> _TSupportsSum: @curry_flip(1) -def sum_by( - source: Iterable[_TSource], projection: Callable[[_TSource], _TSupportsSum] -) -> _TSupportsSum: +def sum_by(source: Iterable[_TSource], projection: Callable[[_TSource], _TSupportsSum]) -> _TSupportsSum: """Sum all elements in sequence. Returns the sum of the results generated by applying the function to @@ -920,9 +894,7 @@ def to_list(source: Iterable[_TSource]) -> Block[_TSource]: @curry_flip(1) -def unfold( - state: _TState, generator: Callable[[_TState], Option[tuple[_TSource, _TState]]] -) -> Iterable[_TSource]: +def unfold(state: _TState, generator: Callable[[_TState], Option[tuple[_TSource, _TState]]]) -> Iterable[_TSource]: """Unfold sequence. Generates a list that contains the elements generated by the given diff --git a/expression/core/aiotools.py b/expression/core/aiotools.py index ed363f0f..f6116fa1 100644 --- a/expression/core/aiotools.py +++ b/expression/core/aiotools.py @@ -81,9 +81,7 @@ def cb(): return None -def start_immediate( - computation: Awaitable[Any], token: CancellationToken | None = None -) -> None: +def start_immediate(computation: Awaitable[Any], token: CancellationToken | None = None) -> None: """Start computation immediately. Runs an asynchronous computation, starting immediately on the diff --git a/expression/core/builder.py b/expression/core/builder.py index 76a3d4d8..d2afd71a 100644 --- a/expression/core/builder.py +++ b/expression/core/builder.py @@ -73,8 +73,7 @@ def __call__( self, fn: Callable[ _P, - Generator[_TInner | None, _TInner, _TInner | None] - | Generator[_TInner | None, None, _TInner | None], + Generator[_TInner | None, _TInner, _TInner | None] | Generator[_TInner | None, None, _TInner | None], ], ) -> Callable[_P, _TOuter]: """Option builder. diff --git a/expression/core/compose.py b/expression/core/compose.py index 717c4d7d..85d62e8c 100644 --- a/expression/core/compose.py +++ b/expression/core/compose.py @@ -31,9 +31,7 @@ def compose(__fn1: Callable[[_A], _B], __fn2: Callable[[_B], _C]) -> Callable[[_ @overload -def compose( - __fn1: Callable[[_A], _B], __fn2: Callable[[_B], _C], __fn3: Callable[[_C], _D] -) -> Callable[[_A], _D]: +def compose(__fn1: Callable[[_A], _B], __fn2: Callable[[_B], _C], __fn3: Callable[[_C], _D]) -> Callable[[_A], _D]: ... diff --git a/expression/core/curry.py b/expression/core/curry.py index 315739f9..63b074f3 100644 --- a/expression/core/curry.py +++ b/expression/core/curry.py @@ -14,9 +14,7 @@ _Arity = Literal[0, 1, 2, 3, 4] -def _curry( - args: tuple[Any, ...], arity: int, fun: Callable[..., Any] -) -> Callable[..., Any]: +def _curry(args: tuple[Any, ...], arity: int, fun: Callable[..., Any]) -> Callable[..., Any]: def wrapper(*args_: Any, **kw: Any) -> Any: if arity == 1: return fun(*args, *args_, **kw) diff --git a/expression/core/fn.py b/expression/core/fn.py index 8574f39c..0f0038ed 100644 --- a/expression/core/fn.py +++ b/expression/core/fn.py @@ -50,9 +50,7 @@ def wrapper(*args: _P.args, **kw: _P.kwargs) -> _TResult: return wrapper -def tailrec_async( - fn: Callable[_P, Awaitable[TailCallResult[_TResult, _P]]] -) -> Callable[_P, Awaitable[_TResult]]: +def tailrec_async(fn: Callable[_P, Awaitable[TailCallResult[_TResult, _P]]]) -> Callable[_P, Awaitable[_TResult]]: """Tail call recursive async function decorator.""" async def trampoline(bouncer: TailCallResult[_TResult, _P]) -> _TResult: diff --git a/expression/core/mailbox.py b/expression/core/mailbox.py index 4b5235ff..17e05acb 100644 --- a/expression/core/mailbox.py +++ b/expression/core/mailbox.py @@ -63,9 +63,7 @@ def post(self, msg: _Msg) -> None: self.messages.put(msg) self.loop.call_soon_threadsafe(self.__process_events) - def post_and_async_reply( - self, build_message: Callable[[AsyncReplyChannel[_Reply]], _Msg] - ) -> Awaitable[_Reply]: + def post_and_async_reply(self, build_message: Callable[[AsyncReplyChannel[_Reply]], _Msg]) -> Awaitable[_Reply]: """Post with async reply. Post a message asynchronously to the mailbox processor and wait diff --git a/expression/core/option.py b/expression/core/option.py index 90493ab8..323c8c24 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -79,9 +79,7 @@ def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: raise NotImplementedError @abstractmethod - def map2( - self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2] - ) -> Option[_TResult]: + def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: raise NotImplementedError @abstractmethod @@ -245,9 +243,7 @@ def is_none(self) -> bool: def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: return Some(mapper(self._value)) - def map2( - self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2] - ) -> Option[_TResult]: + def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: if isinstance(other, Some): return Some(mapper(self._value, other.value)) return Nothing @@ -382,9 +378,7 @@ def is_none(self) -> bool: def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: return Nothing - def map2( - self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2] - ) -> Option[_TResult]: + def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: return Nothing def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: @@ -488,9 +482,7 @@ def __hash__(self) -> int: @curry_flip(1) -def bind( - option: Option[_TSource], mapper: Callable[[_TSource], Option[_TResult]] -) -> Option[_TResult]: +def bind(option: Option[_TSource], mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: """Bind option. Applies and returns the result of the mapper if the value is @@ -519,9 +511,7 @@ def default_value(option: Option[_TSource], value: _TSource) -> _TSource: return option.default_value(value) -def default_with( - getter: Callable[[], _TSource] -) -> Callable[[Option[_TSource]], _TSource]: +def default_with(getter: Callable[[], _TSource]) -> Callable[[Option[_TSource]], _TSource]: """Get with default value lazily. Gets the value of the option if the option is Some, otherwise @@ -543,16 +533,12 @@ def is_some(option: Option[_TSource]) -> TypeGuard[Some[_TSource]]: @curry_flip(1) -def map( - option: Option[_TSource], mapper: Callable[[_TSource], _TResult] -) -> Option[_TResult]: +def map(option: Option[_TSource], mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: return option.map(mapper) @curry_flip(2) -def map2( - opt1: Option[_T1], opt2: Option[_T2], mapper: Callable[[_T1, _T2], _TResult] -) -> Option[_TResult]: +def map2(opt1: Option[_T1], opt2: Option[_T2], mapper: Callable[[_T1, _T2], _TResult]) -> Option[_TResult]: return opt1.map2(mapper, opt2) @@ -627,9 +613,7 @@ def to_result(value: Option[_TSource], error: _TError) -> Result[_TSource, _TErr return value.to_result(error) -def to_result_with( - value: Option[_TSource], error: Callable[[], _TError] -) -> Result[_TSource, _TError]: +def to_result_with(value: Option[_TSource], error: Callable[[], _TError]) -> Result[_TSource, _TError]: return value.to_result_with(error) diff --git a/expression/core/pipe.py b/expression/core/pipe.py index 7be385bc..a3dfef18 100644 --- a/expression/core/pipe.py +++ b/expression/core/pipe.py @@ -184,11 +184,7 @@ def pipe2(__values: Any, *fns: Any) -> Any: def pipe3(__values: Any, *fns: Any) -> Any: - return ( - pipe(fns[0](__values[0])(__values[1])(__values[2]), *fns[1:]) - if fns - else __values - ) + return pipe(fns[0](__values[0])(__values[1])(__values[2]), *fns[1:]) if fns else __values def starpipe(args: Any, *fns: Callable[..., Any]): diff --git a/expression/core/result.py b/expression/core/result.py index 92cc534b..cb3826a5 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -110,9 +110,7 @@ def map2( raise NotImplementedError @abstractmethod - def map_error( - self, mapper: Callable[[_TError], _TResult] - ) -> Result[_TSource, _TResult]: + def map_error(self, mapper: Callable[[_TError], _TResult]) -> Result[_TSource, _TResult]: """Map error. Return a result of the error value after applying the mapping @@ -121,9 +119,7 @@ def map_error( raise NotImplementedError @abstractmethod - def bind( - self, mapper: Callable[[_TSource], Result[_TResult, _TError]] - ) -> Result[_TResult, _TError]: + def bind(self, mapper: Callable[[_TSource], Result[_TResult, _TError]]) -> Result[_TResult, _TError]: raise NotImplementedError @abstractmethod @@ -152,16 +148,12 @@ def to_option(self) -> Option[_TSource]: raise NotImplementedError @classmethod - def of_option( - cls, value: Option[_TSource], error: _TError - ) -> Result[_TSource, _TError]: + def of_option(cls, value: Option[_TSource], error: _TError) -> Result[_TSource, _TError]: """Convert option to a result.""" return of_option(value, error) @classmethod - def of_option_with( - cls, value: Option[_TSource], error: Callable[[], _TError] - ) -> Result[_TSource, _TError]: + def of_option_with(cls, value: Option[_TSource], error: Callable[[], _TError]) -> Result[_TSource, _TError]: """Convert option to a result.""" return of_option_with(value, error) @@ -224,14 +216,10 @@ def map2( ) -> Result[_TResult, _TError]: return other.map(lambda value: mapper(self._value, value)) - def bind( - self, mapper: Callable[[_TSource], Result[_TResult, _TError]] - ) -> Result[_TResult, _TError]: + def bind(self, mapper: Callable[[_TSource], Result[_TResult, _TError]]) -> Result[_TResult, _TError]: return mapper(self._value) - def map_error( - self, mapper: Callable[[_TError], _TResult] - ) -> Result[_TSource, _TResult]: + def map_error(self, mapper: Callable[[_TError], _TResult]) -> Result[_TSource, _TResult]: """Map error. Return a result of the error value after applying the mapping @@ -348,14 +336,10 @@ def map2( ) -> Result[_TResult, _TError]: return Error(self._error) - def bind( - self, mapper: Callable[[_TSource], Result[_TResult, _TError]] - ) -> Result[_TResult, _TError]: + def bind(self, mapper: Callable[[_TSource], Result[_TResult, _TError]]) -> Result[_TResult, _TError]: return Error(self._error) - def map_error( - self, mapper: Callable[[_TError], _TResult] - ) -> Result[_TSource, _TResult]: + def map_error(self, mapper: Callable[[_TError], _TResult]) -> Result[_TSource, _TResult]: """Map error. Return a result of the error value after applying the mapping @@ -425,9 +409,7 @@ def _default_value(result: Result[_TSource, Any]) -> _TSource: return _default_value -def default_with( - getter: Callable[[_TError], _TSource] -) -> Callable[[Result[_TSource, _TError]], _TSource]: +def default_with(getter: Callable[[_TError], _TSource]) -> Callable[[Result[_TSource, _TError]], _TSource]: """Get with default value lazily. Gets the value of the option if the option is Some, otherwise @@ -441,9 +423,7 @@ def _default_with(result: Result[_TSource, _TError]) -> _TSource: @curry_flip(1) -def map( - result: Result[_TSource, _TError], mapper: Callable[[_TSource], _TResult] -) -> Result[_TResult, _TError]: +def map(result: Result[_TSource, _TError], mapper: Callable[[_TSource], _TResult]) -> Result[_TResult, _TError]: return result.map(mapper) @@ -497,9 +477,7 @@ def of_option(value: Option[_TSource], error: _TError) -> Result[_TSource, _TErr return value.to_result(error) -def of_option_with( - value: Option[_TSource], error: Callable[[], _TError] -) -> Result[_TSource, _TError]: +def of_option_with(value: Option[_TSource], error: Callable[[], _TError]) -> Result[_TSource, _TError]: return value.to_result_with(error) diff --git a/expression/core/typing.py b/expression/core/typing.py index 69a3d115..a1d8418d 100644 --- a/expression/core/typing.py +++ b/expression/core/typing.py @@ -90,9 +90,7 @@ def downcast(type: type[_Derived], expr: Any) -> _Derived: Note: F# `:?>` or `downcast`. """ - assert isinstance( - expr, type - ), f"The type of expression {expr} is not a supertype of {type}" + assert isinstance(expr, type), f"The type of expression {expr} is not a supertype of {type}" return expr diff --git a/expression/core/union.py b/expression/core/union.py index 0b959975..7d2ac5dc 100644 --- a/expression/core/union.py +++ b/expression/core/union.py @@ -53,9 +53,7 @@ def tag(tag: int | None = None) -> Tag[None]: return Tag(tag) -class TypedTaggedUnion( - SupportsValidation["TypedTaggedUnion[_T]"], Generic[_T], PipeMixin, ABC -): +class TypedTaggedUnion(SupportsValidation["TypedTaggedUnion[_T]"], Generic[_T], PipeMixin, ABC): """A discriminated (tagged) union. Takes a value, and an optional tag that may be used for matching. @@ -68,19 +66,13 @@ def __init__(self, tag: Tag[_T], value: _T = None) -> None: self.tag = tag if not hasattr(self.__class__, "_tags"): - tags = { - tag.tag: name - for (name, tag) in self.__class__.__dict__.items() - if isinstance(tag, Tag) - } + tags = {tag.tag: name for (name, tag) in self.__class__.__dict__.items() if isinstance(tag, Tag)} setattr(self.__class__, "_tags", tags) self.name = getattr(self.__class__, "_tags")[tag.tag] def dict(self) -> Any: - tags: dict[str, Any] = { - k: v for (k, v) in self.__class__.__dict__.items() if v is self.tag - } + tags: dict[str, Any] = {k: v for (k, v) in self.__class__.__dict__.items() if v is self.tag} if self.value and hasattr(self.value, "dict"): value: Any = self.value.dict() # type: ignore else: @@ -99,9 +91,7 @@ def _validate(union: Any, field: ModelField) -> TypedTaggedUnion[_T]: if isinstance(union, TypedTaggedUnion): return cast(TypedTaggedUnion[_T], union) - tags: dict[str, Any] = { - k: v for (k, v) in cls.__dict__.items() if k == union["tag"] - } + tags: dict[str, Any] = {k: v for (k, v) in cls.__dict__.items() if k == union["tag"]} if field.sub_fields: sub_field = field.sub_fields[0] value, error = sub_field.validate(union["value"], {}, loc=union["tag"]) diff --git a/expression/effect/option.py b/expression/effect/option.py index dc408a67..3bf45aad 100644 --- a/expression/effect/option.py +++ b/expression/effect/option.py @@ -12,9 +12,7 @@ class OptionBuilder(Builder[_TSource, Option[Any]]): - def bind( - self, xs: Option[_TSource], fn: Callable[[_TSource], Option[_TResult]] - ) -> Option[_TResult]: + def bind(self, xs: Option[_TSource], fn: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: return option.bind(fn)(xs) def return_(self, x: _TSource) -> Option[_TSource]: @@ -33,8 +31,7 @@ def __call__( self, # Ignored self parameter fn: Callable[ _P, - Generator[_TSource | None, _TSource, _TSource | None] - | Generator[_TSource | None, None, _TSource | None], + Generator[_TSource | None, _TSource, _TSource | None] | Generator[_TSource | None, None, _TSource | None], ], ) -> Callable[_P, Option[_TSource]]: return super().__call__(fn) diff --git a/expression/effect/result.py b/expression/effect/result.py index 5fe3862b..dacff749 100644 --- a/expression/effect/result.py +++ b/expression/effect/result.py @@ -26,9 +26,7 @@ def return_(self, x: _TSource) -> Result[_TSource, _TError]: def return_from(self, xs: Result[_TSource, _TError]) -> Result[_TSource, _TError]: return xs - def combine( - self, xs: Result[_TSource, _TError], ys: Result[_TSource, _TError] - ) -> Result[_TSource, _TError]: + def combine(self, xs: Result[_TSource, _TError], ys: Result[_TSource, _TError]) -> Result[_TSource, _TError]: return xs.bind(lambda _: ys) def zero(self) -> Result[_TSource, _TError]: @@ -38,8 +36,7 @@ def __call__( self, # Ignored self parameter fn: Callable[ _P, - Generator[_TSource | None, _TSource, _TSource | None] - | Generator[_TSource | None, None, _TSource | None], + Generator[_TSource | None, _TSource, _TSource | None] | Generator[_TSource | None, None, _TSource | None], ], ) -> Callable[_P, Result[_TSource, _TError]]: return super().__call__(fn) diff --git a/expression/effect/seq.py b/expression/effect/seq.py index a9c650cf..97c31d63 100644 --- a/expression/effect/seq.py +++ b/expression/effect/seq.py @@ -10,9 +10,7 @@ class SeqBuilder(Builder[_TSource, Iterable[Any]]): - def bind( - self, xs: Iterable[_TSource], fn: Callable[[_TSource], Iterable[_TResult]] - ) -> Iterable[_TResult]: + def bind(self, xs: Iterable[_TSource], fn: Callable[[_TSource], Iterable[_TResult]]) -> Iterable[_TResult]: for x in xs: return fn(x) return [] @@ -23,9 +21,7 @@ def return_(self, x: _TSource) -> Iterable[_TSource]: def return_from(self, xs: Iterable[_TSource]) -> Iterable[_TSource]: return xs - def combine( - self, xs: Iterable[_TSource], ys: Iterable[_TSource] - ) -> Iterable[_TSource]: + def combine(self, xs: Iterable[_TSource], ys: Iterable[_TSource]) -> Iterable[_TSource]: ret = seq.concat(xs, ys) return ret diff --git a/expression/extra/option/pipeline.py b/expression/extra/option/pipeline.py index 5cb2dacb..bc35fb1e 100644 --- a/expression/extra/option/pipeline.py +++ b/expression/extra/option/pipeline.py @@ -26,9 +26,7 @@ def pipeline(__fn: Callable[[_A], Option[_B]]) -> Callable[[_A], Option[_B]]: @overload -def pipeline( - __fn1: Callable[[_A], Option[_B]], __fn2: Callable[[_B], Option[_C]] -) -> Callable[[_A], Option[_C]]: +def pipeline(__fn1: Callable[[_A], Option[_B]], __fn2: Callable[[_B], Option[_C]]) -> Callable[[_A], Option[_C]]: ... @@ -91,9 +89,7 @@ def pipeline(*fns: Callable[[Any], Option[Any]]) -> Callable[[Any], Option[Any]] The composed functions. """ - def reducer( - acc: Callable[[Any], Option[Any]], fn: Callable[[Any], Option[Any]] - ) -> Callable[[Any], Option[Any]]: + def reducer(acc: Callable[[Any], Option[Any]], fn: Callable[[Any], Option[Any]]) -> Callable[[Any], Option[Any]]: def gn(x: Any) -> Option[Any]: return acc(x).bind(fn) diff --git a/expression/extra/parser.py b/expression/extra/parser.py index e24d49e5..e1e44060 100644 --- a/expression/extra/parser.py +++ b/expression/extra/parser.py @@ -23,9 +23,7 @@ class Parser(Generic[_A]): __slots__ = ["_name", "_run"] - def __init__( - self, run: Callable[[Remaining], ParseResult[_A]], name: str | None = None - ) -> None: + def __init__(self, run: Callable[[Remaining], ParseResult[_A]], name: str | None = None) -> None: self._run = run self._name = name or "parser" @@ -66,15 +64,11 @@ def map(self, mapper: Callable[[_A], _B]) -> Parser[_B]: return pipe(self, mapped) @overload - def starmap( - self: Parser[tuple[_B, _C]], mapper: Callable[[_B, _C], _D] - ) -> Parser[_D]: + def starmap(self: Parser[tuple[_B, _C]], mapper: Callable[[_B, _C], _D]) -> Parser[_D]: ... @overload - def starmap( - self: Parser[tuple[_B, _C, _D]], mapper: Callable[[_B, _C, _D], _E] - ) -> Parser[_E]: + def starmap(self: Parser[tuple[_B, _C, _D]], mapper: Callable[[_B, _C, _D], _E]) -> Parser[_E]: ... def starmap(self: Parser[Any], mapper: Callable[..., Any]) -> Parser[Any]: @@ -204,17 +198,13 @@ def run(input: Remaining) -> ParseResult[_B]: @curry(1) @overload -def starmap( - mapper: Callable[[_A, _B], _C], parser: Parser[tuple[_A, _B]] -) -> Parser[_C]: +def starmap(mapper: Callable[[_A, _B], _C], parser: Parser[tuple[_A, _B]]) -> Parser[_C]: ... @curry(1) @overload -def starmap( - mapper: Callable[[_A, _B, _C], _D], parser: Parser[tuple[_A, _B, _C]] -) -> Parser[_D]: +def starmap(mapper: Callable[[_A, _B, _C], _D], parser: Parser[tuple[_A, _B, _C]]) -> Parser[_D]: ... @@ -257,9 +247,7 @@ def mapper(fx: tuple[Callable[[_A], _B], _A]) -> _B: @curry(2) -def lift2( - fn: Callable[[_A], Callable[[_B], _C]], xP: Parser[_A], yP: Parser[_B] -) -> Parser[_C]: +def lift2(fn: Callable[[_A], Callable[[_B], _C]], xP: Parser[_A], yP: Parser[_B]) -> Parser[_C]: return apply(apply(preturn(fn), xP), yP) @@ -293,9 +281,7 @@ def pstring(string_input: str) -> Parser[str]: ) -def parse_zero_or_more( - parser: Parser[_A], input: Remaining -) -> tuple[Block[_A], Remaining]: +def parse_zero_or_more(parser: Parser[_A], input: Remaining) -> tuple[Block[_A], Remaining]: # run parser with the input first_result = parser.run(input) @@ -304,9 +290,7 @@ def parse_zero_or_more( case Ok((first_value, input_after_first_parse)): # if parse succeeds, call recursively # to get the subsequent values - subsequent_values, remaining_input = parse_zero_or_more( - parser, input_after_first_parse - ) + subsequent_values, remaining_input = parse_zero_or_more(parser, input_after_first_parse) values = subsequent_values.cons(first_value) return values, remaining_input case _: @@ -330,9 +314,7 @@ def run(input: Remaining) -> ParseResult[Block[_A]]: match firstResult: case Ok((first_value, input_after_first_parse)): # if first found, look for zeroOrMore now - subsequent_values, remaining_input = parse_zero_or_more( - parser, input_after_first_parse - ) + subsequent_values, remaining_input = parse_zero_or_more(parser, input_after_first_parse) values = subsequent_values.cons(first_value) return Ok[tuple[Block[_A], Remaining], str]((values, remaining_input)) @@ -451,9 +433,7 @@ def result_to_int(sign: Option[str], digit_list: Block[str]) -> int: def _pfloat() -> Parser[float]: # helper - def result_to_float( - sd: tuple[Option[str], Block[str]], digits2: Option[Block[str]] - ) -> float: + def result_to_float(sd: tuple[Option[str], Block[str]], digits2: Option[Block[str]]) -> float: # ignore int overflow for now sign, digits1 = sd if digits2.is_some(): diff --git a/expression/extra/result/catch.py b/expression/extra/result/catch.py index c2926a0f..c02fa4e6 100644 --- a/expression/extra/result/catch.py +++ b/expression/extra/result/catch.py @@ -24,9 +24,7 @@ def catch( @overload -def catch( - f: Callable[..., _TSource], *, exception: type[_TError] -) -> Callable[..., Result[_TSource, _TError]]: +def catch(f: Callable[..., _TSource], *, exception: type[_TError]) -> Callable[..., Result[_TSource, _TError]]: ... @@ -36,9 +34,7 @@ def catch( # type: ignore [Callable[..., _TSource]], Callable[..., Result[_TSource, _TError]] | Result[_TSource, _TError], ]: - def decorator( - fn: Callable[..., _TSource] - ) -> Callable[..., Result[_TSource, _TError]]: + def decorator(fn: Callable[..., _TSource]) -> Callable[..., Result[_TSource, _TError]]: @wraps(fn) def wrapper(*args: Any, **kwargs: Any) -> Result[_TSource, _TError]: try: diff --git a/expression/extra/result/pipeline.py b/expression/extra/result/pipeline.py index 78c847ea..db57ce2f 100644 --- a/expression/extra/result/pipeline.py +++ b/expression/extra/result/pipeline.py @@ -21,9 +21,7 @@ def pipeline() -> Callable[[Any], Result[Any, Any]]: @overload -def pipeline( - __fn: Callable[[_A], Result[_B, _TError]] -) -> Callable[[_A], Result[_B, _TError]]: +def pipeline(__fn: Callable[[_A], Result[_B, _TError]]) -> Callable[[_A], Result[_B, _TError]]: ... @@ -77,9 +75,7 @@ def pipeline( ... -def pipeline( - *fns: Callable[[Any], Result[Any, Any]] -) -> Callable[[Any], Result[Any, Any]]: +def pipeline(*fns: Callable[[Any], Result[Any, Any]]) -> Callable[[Any], Result[Any, Any]]: """Pipeline multiple result returning functions left to right. A pipeline kleisli (>=>) composes zero or more functions into a diff --git a/expression/system/cancellation.py b/expression/system/cancellation.py index eb774902..0044e34a 100644 --- a/expression/system/cancellation.py +++ b/expression/system/cancellation.py @@ -24,18 +24,14 @@ class CancellationToken: is appropriate. """ - def __init__( - self, cancelled: bool = True, source: CancellationTokenSource | None = None - ) -> None: + def __init__(self, cancelled: bool = True, source: CancellationTokenSource | None = None) -> None: """The init function. Should not be used directly. Create cancellation tokens using the `CancellationTokenSource` instead. """ self._cancelled = cancelled - self._source = ( - CancellationTokenSource.cancelled_source() if source is None else source - ) + self._source = CancellationTokenSource.cancelled_source() if source is None else source @property def is_cancellation_requested(self) -> bool: diff --git a/poetry.lock b/poetry.lock index f64fc0e6..984c4aa7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2091,6 +2091,32 @@ files = [ {file = "rpds_py-0.10.6.tar.gz", hash = "sha256:4ce5a708d65a8dbf3748d2474b580d606b1b9f91b5c6ab2a316e0b0cf7a4ba50"}, ] +[[package]] +name = "ruff" +version = "0.1.3" +description = "An extremely fast Python linter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.1.3-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:b46d43d51f7061652eeadb426a9e3caa1e0002470229ab2fc19de8a7b0766901"}, + {file = "ruff-0.1.3-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:b8afeb9abd26b4029c72adc9921b8363374f4e7edb78385ffaa80278313a15f9"}, + {file = "ruff-0.1.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca3cf365bf32e9ba7e6db3f48a4d3e2c446cd19ebee04f05338bc3910114528b"}, + {file = "ruff-0.1.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4874c165f96c14a00590dcc727a04dca0cfd110334c24b039458c06cf78a672e"}, + {file = "ruff-0.1.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eec2dd31eed114e48ea42dbffc443e9b7221976554a504767ceaee3dd38edeb8"}, + {file = "ruff-0.1.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:dc3ec4edb3b73f21b4aa51337e16674c752f1d76a4a543af56d7d04e97769613"}, + {file = "ruff-0.1.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e3de9ed2e39160800281848ff4670e1698037ca039bda7b9274f849258d26ce"}, + {file = "ruff-0.1.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c595193881922cc0556a90f3af99b1c5681f0c552e7a2a189956141d8666fe8"}, + {file = "ruff-0.1.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f75e670d529aa2288cd00fc0e9b9287603d95e1536d7a7e0cafe00f75e0dd9d"}, + {file = "ruff-0.1.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:76dd49f6cd945d82d9d4a9a6622c54a994689d8d7b22fa1322983389b4892e20"}, + {file = "ruff-0.1.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:918b454bc4f8874a616f0d725590277c42949431ceb303950e87fef7a7d94cb3"}, + {file = "ruff-0.1.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8859605e729cd5e53aa38275568dbbdb4fe882d2ea2714c5453b678dca83784"}, + {file = "ruff-0.1.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0b6c55f5ef8d9dd05b230bb6ab80bc4381ecb60ae56db0330f660ea240cb0d4a"}, + {file = "ruff-0.1.3-py3-none-win32.whl", hash = "sha256:3e7afcbdcfbe3399c34e0f6370c30f6e529193c731b885316c5a09c9e4317eef"}, + {file = "ruff-0.1.3-py3-none-win_amd64.whl", hash = "sha256:7a18df6638cec4a5bd75350639b2bb2a2366e01222825562c7346674bdceb7ea"}, + {file = "ruff-0.1.3-py3-none-win_arm64.whl", hash = "sha256:12fd53696c83a194a2db7f9a46337ce06445fb9aa7d25ea6f293cf75b21aca9f"}, + {file = "ruff-0.1.3.tar.gz", hash = "sha256:3ba6145369a151401d5db79f0a47d50e470384d0d89d0d6f7fab0b589ad07c34"}, +] + [[package]] name = "setuptools" version = "68.2.2" @@ -2344,27 +2370,6 @@ code-style = ["black", "flake8 (>=3.7.0,<3.8.0)", "pre-commit (==1.17.0)"] rtd = ["myst-parser", "sphinx (>=3.0)", "sphinx-book-theme"] testing = ["coverage (<5.0)", "jupyter-book", "pytest (>=5.4,<6.0)", "pytest-cov (>=2.8,<3.0)", "pytest-regressions"] -[[package]] -name = "sphinx-panels" -version = "0.6.0" -description = "A sphinx extension for creating panels in a grid layout." -optional = false -python-versions = "*" -files = [ - {file = "sphinx-panels-0.6.0.tar.gz", hash = "sha256:d36dcd26358117e11888f7143db4ac2301ebe90873ac00627bf1fe526bf0f058"}, - {file = "sphinx_panels-0.6.0-py3-none-any.whl", hash = "sha256:bd64afaf85c07f8096d21c8247fc6fd757e339d1be97832c8832d6ae5ed2e61d"}, -] - -[package.dependencies] -docutils = "*" -sphinx = ">=2,<5" - -[package.extras] -code-style = ["pre-commit (>=2.7.0,<2.8.0)"] -live-dev = ["sphinx-autobuild", "web-compile (>=0.2.0,<0.3.0)"] -testing = ["pytest (>=6.0.1,<6.1.0)", "pytest-regressions (>=2.0.1,<2.1.0)"] -themes = ["myst-parser (>=0.12.9,<0.13.0)", "pydata-sphinx-theme (>=0.4.0,<0.5.0)", "sphinx-book-theme (>=0.0.36,<0.1.0)", "sphinx-rtd-theme"] - [[package]] name = "sphinx-thebe" version = "0.2.1" @@ -2781,4 +2786,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 4" -content-hash = "f970a4c8b838843c6123c703e1a92b5f32e414f2f3609da74c826ae55dbd031c" +content-hash = "5d9f4696cece7fa12acf3fac835727eb0057344529a6461ea3e6143ccafce22d" diff --git a/pyproject.toml b/pyproject.toml index ef00bc5d..665fcee1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,9 +37,11 @@ dunamai = "^1.12.0" hypothesis = "^6.54.2" jupyter-book = "^0.15.0" sphinx-autodoc-typehints = "^1.17.0" -sphinx-panels = "^0.6.0" pydantic = "^1.10.0" +[tool.poetry.group.dev.dependencies] +ruff = "^0.1.3" + [tool.black] line-length = 88 target-version = ['py310'] From 6186c8aeaeea89d7d8c9f65f85629cdcc9bbd863 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Fri, 3 Nov 2023 09:09:06 +0100 Subject: [PATCH 04/39] Upgrade pyright --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9a203d0d..52ee9944 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: language: node pass_filenames: false types: [python] - additional_dependencies: ["pyright@1.1.330"] + additional_dependencies: ["pyright@1.1.334"] repo: local - hooks: - id: jb-to-sphinx From c8d74522c183b6d50a77c8119b66652a5e69be94 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Fri, 3 Nov 2023 12:14:26 +0100 Subject: [PATCH 05/39] Fix typing error --- expression/core/result.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expression/core/result.py b/expression/core/result.py index cb3826a5..3d133ccd 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -138,7 +138,7 @@ def dict(self) -> builtins.dict[str, _TSource | _TError]: raise NotImplementedError @abstractmethod - def swap(self) -> Result[_TError, _TResult]: + def swap(self) -> Result[_TError, _TSource]: """Swaps the value in the result so an Ok becomes an Error and an Error becomes an Ok.""" raise NotImplementedError From a8bedbe4ec316a13821ced3664e691210f6a8ec3 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 07:56:20 +0100 Subject: [PATCH 06/39] Refactor to new tagged union type --- expression/__init__.py | 14 +- expression/core/__init__.py | 10 +- expression/core/option.py | 914 ++++++++++++++-------- expression/core/result.py | 498 +++++------- expression/core/try_.py | 17 +- expression/core/union.py | 178 ++--- expression/extra/parser.py | 34 +- expression/extra/result/catch.py | 3 +- poetry.lock | 1259 ++++++++++++++++-------------- pyproject.toml | 4 +- tests/test_catch.py | 12 +- tests/test_option.py | 58 +- tests/test_parser.py | 93 +-- tests/test_result.py | 121 +-- tests/test_try.py | 18 +- tests/test_union.py | 417 +++++----- 16 files changed, 1927 insertions(+), 1723 deletions(-) diff --git a/expression/__init__.py b/expression/__init__.py index 3b13c058..3bbe7941 100644 --- a/expression/__init__.py +++ b/expression/__init__.py @@ -9,7 +9,7 @@ GitHub: https://github.com/cognitedata/Expression """ -from . import collections, core, effect +from . import collections, core # , effect from ._version import __version__ from .core import ( AsyncReplyChannel, @@ -27,18 +27,15 @@ Failure, MailboxProcessor, Nothing, - Nothing_, Ok, Option, Result, - SingleCaseUnion, Some, Success, - Tag, - TaggedUnion, TailCall, TailCallResult, Try, + case, compose, curry, curry_flip, @@ -59,6 +56,7 @@ result, snd, tag, + tagged_union, tailrec, tailrec_async, try_downcast, @@ -75,6 +73,7 @@ __all__ = [ "AsyncReplyChannel", "Builder", + "case", "Choice", "Choice1of2", "Choice1of3", @@ -105,7 +104,6 @@ "is_some", "MailboxProcessor", "Nothing", - "Nothing_", "Ok", "option", "Option", @@ -114,12 +112,10 @@ "pipe3", "result", "Result", - "SingleCaseUnion", "snd", "Some", "Success", - "Tag", - "TaggedUnion", + "tagged_union", "TailCall", "TailCallResult", "tailrec", diff --git a/expression/core/__init__.py b/expression/core/__init__.py index 18ad271d..351e41d8 100644 --- a/expression/core/__init__.py +++ b/expression/core/__init__.py @@ -18,7 +18,7 @@ from .fn import TailCall, TailCallResult, tailrec, tailrec_async from .mailbox import AsyncReplyChannel, MailboxProcessor from .misc import flip, fst, identity, snd -from .option import Nothing, Nothing_, Option, Some, default_arg, is_none, is_some +from .option import Nothing, Option, Some, default_arg, is_none, is_some from .pipe import PipeMixin, pipe, pipe2, pipe3 from .result import Error, Ok, Result, is_error, is_ok from .try_ import Failure, Success, Try @@ -31,7 +31,7 @@ try_downcast, upcast, ) -from .union import SingleCaseUnion, Tag, TaggedUnion, tag +from .union import case, tag, tagged_union __all__ = [ @@ -74,7 +74,7 @@ "PipeMixin", "result", "Result", - "SingleCaseUnion", + "tagged_union", "snd", "Some", "Success", @@ -82,8 +82,8 @@ "SupportsGreaterThan", "SupportsMatch", "SupportsSum", - "Tag", - "TaggedUnion", + "tag", + "case", "TailCall", "TailCallResult", "tailrec", diff --git a/expression/core/option.py b/expression/core/option.py index 323c8c24..05af1ec4 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -8,14 +8,18 @@ from __future__ import annotations import builtins -from abc import ABC, abstractmethod -from collections.abc import Callable, Generator, Iterable, Iterator -from typing import TYPE_CHECKING, Any, ClassVar, TypeAlias, TypeGuard, TypeVar, cast +from collections.abc import Callable, Generator, Iterable +from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, cast, get_args, get_origin + +from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler +from pydantic_core import CoreSchema, core_schema from .curry import curry_flip from .error import EffectError from .pipe import PipeMixin -from .typing import GenericValidator, ModelField, SupportsValidation + +# from .typing import ModelField +from .union import case, tag, tagged_union if TYPE_CHECKING: @@ -30,59 +34,77 @@ _T2 = TypeVar("_T2") -def _validate(value: Any, field: ModelField) -> Option[Any]: - if isinstance(value, BaseOption): - return cast(Option[Any], value) - - if isinstance(value, builtins.dict) and not value: - return Nothing - - if field.sub_fields: - sub_field = field.sub_fields[0] - value, error = sub_field.validate(value, {}, loc="Option") - if error: - raise ValueError(str(error)) - - return Some(cast(Any, value)) - - -class BaseOption( +@tagged_union +class Option( Iterable[_TSource], PipeMixin, - SupportsValidation["BaseOption[_TSource]"], - ABC, + # SupportsValidation["BaseOption[_TSource]"], ): """Option abstract base class.""" - __validators__: ClassVar = [_validate] + tag: Literal["some", "none"] = tag() + + some: _TSource = case() + none: None = case() + + @staticmethod + def Some(value: _TSource) -> Option[_TSource]: + """Create a Some option.""" + return Option(some=value) + + @staticmethod + def Nothing() -> Option[_TSource]: + """Create a None option.""" + return Option(none=None) - @abstractmethod def default_value(self, value: _TSource) -> _TSource: """Get with default value. Gets the value of the option if the option is Some, otherwise returns the specified default value. """ - raise NotImplementedError + match self: + case Option(tag="some", some=some): + return some + case _: + return value - @abstractmethod def default_with(self, getter: Callable[[], _TSource]) -> _TSource: """Get with default value lazily. Gets the value of the option if the option is Some, otherwise returns the value produced by the getter """ - raise NotImplementedError + match self: + case Option(tag="some", some=some): + return some + case _: + return getter() - @abstractmethod def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: - raise NotImplementedError + """Map option. + + Applies the mapper to the value if the option is Some, otherwise + returns `Nothing`. + """ + match self: + case Option(tag="some", some=some): + return Some(mapper(some)) + case _: + return Nothing - @abstractmethod def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: - raise NotImplementedError + """Map2 option. + + Applies the mapper to the values if both options are Some, + otherwise returns `Nothing`. + """ + match self, other: + case Option(tag="some", some=some), Option(tag="some", some=other_value): + return Some(mapper(some, other_value)) + case _: + return Nothing - @abstractmethod def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: """Bind option. @@ -97,48 +119,78 @@ def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResul Returns: An option of the output type of the mapper. """ - raise NotImplementedError + match self: + case Option(tag="some", some=some): + return mapper(some) + case _: + return Nothing - @abstractmethod def or_else(self, if_none: Option[_TSource]) -> Option[_TSource]: """Returns option if it is Some, otherwise returns `if_one`.""" - raise NotImplementedError + match self: + case Option(tag="some"): + return self + case _: + return if_none - @abstractmethod def or_else_with(self, if_none: Callable[[], Option[_TSource]]) -> Option[_TSource]: """Or-else-with. Returns option if it is Some, otherwise evaluates the given function and returns the result. """ - raise NotImplementedError + match self: + case Option(tag="some"): + return self + case _: + return if_none() - @abstractmethod def filter(self, predicate: Callable[[_TSource], bool]) -> Option[_TSource]: """Filter option. Returns the input if the predicate evaluates to true, otherwise returns `Nothing`. """ - raise NotImplementedError + match self: + case Option(tag="some", some=some) if predicate(some): + return self + case _: + return Nothing - @abstractmethod def to_list(self) -> list[_TSource]: - raise NotImplementedError + """Convert option to list.""" + match self: + case Option(tag="some", some=some): + return [some] + case _: + return [] - @abstractmethod def to_seq(self) -> Seq[_TSource]: - raise NotImplementedError + """Convert option to sequence.""" + # deferred import to avoid circular dependencies + from expression.collections.seq import Seq + + match self: + case Option(tag="some", some=some): + return Seq.of(some) + case _: + return Seq() - @abstractmethod def is_some(self) -> bool: """Returns true if the option is not Nothing.""" - raise NotImplementedError + match self: + case Option(tag="some"): + return True + case _: + return False - @abstractmethod def is_none(self) -> bool: """Returns true if the option is Nothing.""" - raise NotImplementedError + match self: + case Option(tag="some"): + return False + case _: + return True @classmethod def of_obj(cls, value: _TSource) -> Option[_TSource]: @@ -155,324 +207,500 @@ def of_result(cls, result: Result[_TSource, _TError]) -> Option[_TSource]: """Convert result to an option.""" return of_result(result) - @abstractmethod def to_optional(self) -> _TSource | None: """Convert option to an optional.""" - raise NotImplementedError + match self: + case Option(tag="some", some=some): + return some + case _: + return None - @abstractmethod def to_result(self, error: _TError) -> Result[_TSource, _TError]: """Convert option to a result.""" - raise NotImplementedError + from expression.core.result import Result + + match self: + case Option(tag="some", some=some): + return Result[_TSource, _TError].Ok(some) + case _: + return Result[_TSource, _TError].Error(error) - @abstractmethod def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TError]: """Convert option to a result.""" - raise NotImplementedError + from expression.core.result import Result - @abstractmethod - def dict(self) -> _TSource | builtins.dict[str, Any]: + match self: + case Option(tag="some", some=some): + return Result[_TSource, _TError].Ok(some) + case _: + return Result[_TSource, _TError].Error(error()) + + def model_dump(self) -> _TSource | None: """Returns a json string representation of the option.""" - raise NotImplementedError + match self: + case Option(tag="some", some=value): + attr = getattr(value, "model_dump", None) + if attr and callable(attr): + value = attr() + + return value + case _: + return None @property - @abstractmethod def value(self) -> _TSource: """Returns the value wrapped by the option. A `ValueError` is raised if the option is `Nothing`. """ - raise NotImplementedError + match self: + case Option(tag="some", some=some): + return some + case _: + raise ValueError("There is no value.") - @abstractmethod def __eq__(self, o: Any) -> bool: - raise NotImplementedError + return isinstance(o, Option) and self.tag == o.tag and getattr(self, self.tag) == getattr(o, self.tag) - @abstractmethod def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: - raise NotImplementedError + match self: + case Option(tag="some", some=value): + return (yield value) + case _: + raise EffectError(Nothing) - @abstractmethod def __lt__(self, other: Any) -> bool: - raise NotImplementedError + if isinstance(other, Option): + return self.value < other.value # type: ignore + return False + + def __str__(self) -> str: + match self: + case Option(tag="some", some=some): + return f"Some {some}" + case _: + return "Nothing" def __repr__(self) -> str: return self.__str__() - @classmethod - def __get_validators__(cls) -> Iterator[GenericValidator[BaseOption[_TSource]]]: - yield from cls.__validators__ - - @abstractmethod def __hash__(self) -> int: - raise NotImplementedError - - -class Some(BaseOption[_TSource]): - """The Some option case class.""" - - __match_args__ = ("value",) - - def __init__(self, value: _TSource) -> None: - self._value = value - - def default_value(self, value: _TSource) -> _TSource: - """Get value or default value. - - Gets the value of the option if the option is Some, otherwise - returns the specified default value. - """ - return self._value - - def default_with(self, getter: Callable[[], _TSource]) -> _TSource: - """Get with default value. - - Gets the value of the option if the option is Some, otherwise - returns the value produced by the getter - """ - return self._value - - def is_some(self) -> bool: - """Returns `True`.""" - return True - - def is_none(self) -> bool: - """Returns `False`.""" - return False - - def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: - return Some(mapper(self._value)) - - def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: - if isinstance(other, Some): - return Some(mapper(self._value, other.value)) - return Nothing - - def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: - """Bind option. - - Applies and returns the result of the mapper if the value is - `Some`. If the value is `Nothing` then `Nothing` is returned. - - Args: - mapper: A function that takes the value of type TSource from - an option and transforms it into an option containing a - value of type TResult. - - Returns: - An option of the output type of the mapper. - """ - return mapper(self._value) - - def or_else(self, if_none: Option[_TSource]) -> Option[_TSource]: - """Returns `self`.""" - return self - - def or_else_with(self, if_none: Callable[[], Option[_TSource]]) -> Option[_TSource]: - """Returns `self`.""" - return self - - def filter(self, predicate: Callable[[_TSource], bool]) -> Option[_TSource]: - """Filter option. - - Returns the input if the predicate evaluates to true, - otherwise returns `Nothing`. - """ - return self if predicate(self._value) else Nothing + match self: + case Option(tag="some", some=value): + return hash((self.tag, value)) + case _: + return hash((self.tag, 0)) - def to_list(self) -> list[_TSource]: - return [self._value] - - def to_seq(self) -> Seq[_TSource]: - # deferred import to avoid circular dependencies - from expression.collections.seq import Seq - - return Seq.of(self._value) - - def to_optional(self) -> _TSource | None: - """Convert option to an optional.""" - return self._value - - def to_result(self, error: _TError) -> Result[_TSource, _TError]: - """Convert option to a result.""" - from expression.core.result import Ok - - return Ok(self._value) - - def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TError]: - """Convert option to a result.""" - from expression.core.result import Ok - - return Ok(self._value) - - def dict(self) -> _TSource: - attr = getattr(self._value, "dict", None) or getattr(self._value, "dict", None) - if attr and callable(attr): - value = attr() + @classmethod + def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: + print("Some:__get_pydantic_core_schema__", source_type, handler) + origin = get_origin(source_type) + if origin is None: # used as `x: Owner` without params + origin = source_type + item_tp = Any else: - value = self._value - - return value - - @property - def value(self) -> _TSource: - """Returns the value wrapped by the option. - - A `ValueError` is raised if the option is `Nothing`. - """ - return self._value - - def __lt__(self, other: Any) -> bool: - if isinstance(other, Some): - return self._value < other._value # type: ignore - return False - - def __eq__(self, o: Any) -> bool: - if isinstance(o, Some): - return self._value == o._value # type: ignore - return False - - def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: - return (yield self._value) - - def __str__(self) -> str: - return f"Some {self._value}" - - def __hash__(self) -> int: - return hash(self._value) - - -class Nothing_(BaseOption[_TSource], EffectError): - """The None option case class. - - Do not use. Use the singleton `Nothing` instead. Since Nothing is a - singleton it can be tested e.g using `is`: - >>> if xs is Nothing: - ... return True - """ - - def default_value(self, value: _TSource) -> _TSource: - """Get value or default value. - - Gets the value of the option if the option is Some, otherwise - returns the specified default value. - """ - return value - - def default_with(self, getter: Callable[[], _TSource]) -> _TSource: - """Get with default value. - - Gets the value of the option if the option is Some, otherwise - returns the value produced by the getter - """ - return getter() - - def is_some(self) -> bool: - """Returns `False`.""" - return False - - def is_none(self) -> bool: - """Returns `True`.""" - return True - - def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: - return Nothing - - def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: - return Nothing - - def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: - """Bind option. - - Applies and returns the result of the mapper if the value is - `Some`. If the value is `Nothing` then `Nothing` is returned. - - Args: - mapper: A function that takes the value of type TSource from - an option and transforms it into an option containing a - value of type TResult. - - Returns: - An option of the output type of the mapper. - """ - return Nothing - - def or_else(self, if_none: Option[_TSource]) -> Option[_TSource]: - """Returns `if_none`.""" - return if_none - - def or_else_with(self, if_none: Callable[[], Option[_TSource]]) -> Option[_TSource]: - """Evaluates `if_none` and returns the result.""" - return if_none() - - def filter(self, predicate: Callable[[_TSource], bool]) -> Option[_TSource]: - return Nothing + item_tp = get_args(source_type)[0] - def to_list(self) -> list[_TSource]: - return [] - - def to_seq(self) -> Seq[_TSource]: - # deferred import to avoid circular dependencies - from expression.collections.seq import Seq - - return Seq() - - def to_optional(self) -> _TSource | None: - """Convert option to an optional.""" - return None - - def to_result(self, error: _TError) -> Result[_TSource, _TError]: - """Convert option to a result.""" - from expression.core.result import Error - - return Error(error) - - def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TError]: - """Convert option to a result.""" - from expression.core.result import Error + value_schema = handler.generate_schema(item_tp) + none_schema = handler.generate_schema(None) - return Error(error()) - - def dict(self) -> builtins.dict[str, Any]: - return {} # Pydantic cannot handle None or other types than Optional - - @property - def value(self) -> _TSource: - """Returns the value wrapped by the option. - - A `ValueError` is raised if the option is `Nothing`. - """ - raise ValueError("There is no value.") - - def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: - """Return iterator for the `Nothing` case. - - We basically want to return nothing, but we have to return - something to signal fail. - """ - raise Nothing - while False: - yield - - def __lt__(self, other: Any) -> bool: - return True - - def __eq__(self, o: Any) -> bool: - if o is Nothing: - return True - return False - - def __str__(self): - return "Nothing" - - def __hash__(self) -> int: - return 0 + def validate_some(v: Any, handler: ValidatorFunctionWrapHandler) -> Option[Any]: + print("Some:validate", v, handler) + value = handler(v) + return Some(value) + def validate_none(v: Any, handler: ValidatorFunctionWrapHandler) -> Option[Any]: + print("None:validate", v, handler) + value = handler(v) + return Nothing -# The singleton None class. We use the name 'Nothing' here instead of `None` to -# avoid conflicts with the builtin `None` value in Python. -# Note to self: Must be of type `Nothing_` or pattern matching will not work. -Nothing: Nothing_[Any] = Nothing_() + python_schema = core_schema.union_schema( + [ + core_schema.is_instance_schema(Option), + core_schema.chain_schema( + [ + core_schema.none_schema(), + core_schema.no_info_wrap_validator_function(validate_none, none_schema), + ] + ), + core_schema.chain_schema( + [ + # Ensure the value is an instance of _T + core_schema.is_instance_schema(item_tp), + # Use the value_schema to validate `values` + core_schema.no_info_wrap_validator_function(validate_some, value_schema), + ] + ), + ] + ) + + return core_schema.json_or_python_schema( + json_schema=core_schema.chain_schema( + [ + core_schema.any_schema(), + # after validating the json data convert it to python + core_schema.no_info_before_validator_function( + lambda data: cls(some=data) if data is not None else cls(none=data), + python_schema, + ), + ] + ), + python_schema=python_schema, + serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.model_dump()), + ) + + +# class Some(BaseOption[_TSource]): +# """The Some option case class.""" + +# __match_args__ = ("value",) + +# def __init__(self, value: _TSource) -> None: +# self._value = value + +# def default_value(self, value: _TSource) -> _TSource: +# """Get value or default value. + +# Gets the value of the option if the option is Some, otherwise +# returns the specified default value. +# """ +# return self._value + +# def default_with(self, getter: Callable[[], _TSource]) -> _TSource: +# """Get with default value. + +# Gets the value of the option if the option is Some, otherwise +# returns the value produced by the getter +# """ +# return self._value + +# def is_some(self) -> bool: +# """Returns `True`.""" +# return True + +# def is_none(self) -> bool: +# """Returns `False`.""" +# return False + +# def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: +# return Some(mapper(self._value)) + +# def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: +# if isinstance(other, Some): +# return Some(mapper(self._value, other.value)) +# return Nothing + +# def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: +# """Bind option. + +# Applies and returns the result of the mapper if the value is +# `Some`. If the value is `Nothing` then `Nothing` is returned. + +# Args: +# mapper: A function that takes the value of type TSource from +# an option and transforms it into an option containing a +# value of type TResult. + +# Returns: +# An option of the output type of the mapper. +# """ +# return mapper(self._value) + +# def or_else(self, if_none: Option[_TSource]) -> Option[_TSource]: +# """Returns `self`.""" +# return self + +# def or_else_with(self, if_none: Callable[[], Option[_TSource]]) -> Option[_TSource]: +# """Returns `self`.""" +# return self + +# def filter(self, predicate: Callable[[_TSource], bool]) -> Option[_TSource]: +# """Filter option. + +# Returns the input if the predicate evaluates to true, +# otherwise returns `Nothing`. +# """ +# return self if predicate(self._value) else Nothing + +# def to_list(self) -> list[_TSource]: +# return [self._value] + +# def to_seq(self) -> Seq[_TSource]: +# # deferred import to avoid circular dependencies +# from expression.collections.seq import Seq + +# return Seq.of(self._value) + +# def to_optional(self) -> _TSource | None: +# """Convert option to an optional.""" +# return self._value + +# def to_result(self, error: _TError) -> Result[_TSource, _TError]: +# """Convert option to a result.""" +# from expression.core.result import Ok + +# return Ok(self._value) + +# def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TError]: +# """Convert option to a result.""" +# from expression.core.result import Ok + +# return Ok(self._value) + +# def dict(self) -> _TSource: +# attr = getattr(self._value, "dict", None) or getattr(self._value, "dict", None) +# if attr and callable(attr): +# value = attr() +# else: +# value = self._value + +# return value + +# @property +# def value(self) -> _TSource: +# """Returns the value wrapped by the option. + +# A `ValueError` is raised if the option is `Nothing`. +# """ +# return self._value + +# def __lt__(self, other: Any) -> bool: +# if isinstance(other, Some): +# return self._value < other._value # type: ignore +# return False + +# def __eq__(self, o: Any) -> bool: +# if isinstance(o, Some): +# return self._value == o._value # type: ignore +# return False + +# def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: +# return (yield self._value) + +# def __str__(self) -> str: +# return f"Some {self._value}" + +# def __hash__(self) -> int: +# return hash(self._value) + +# @classmethod +# def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: +# print("Some:__get_pydantic_core_schema__", source_type, handler) +# origin = get_origin(source_type) +# if origin is None: # used as `x: Owner` without params +# origin = source_type +# item_tp = Any +# else: +# item_tp = get_args(source_type)[0] + +# value_schema = handler.generate_schema(item_tp) + +# def validate(v: Any, handler: ValidatorFunctionWrapHandler) -> Some[Any]: +# value = handler(v) +# return Some(value) + +# python_schema = core_schema.union_schema( +# [ +# core_schema.is_instance_schema(Some), +# core_schema.chain_schema( +# [ +# # Ensure the value is an instance of _T +# core_schema.is_instance_schema(item_tp), +# # Use the value_schema to validate `values` +# core_schema.no_info_wrap_validator_function(validate, value_schema), +# ] +# ), +# ] +# ) + +# return core_schema.json_or_python_schema( +# json_schema=core_schema.chain_schema( +# [ +# core_schema.any_schema(), +# # after validating the json data convert it to python +# core_schema.no_info_before_validator_function( +# lambda data: Some(data), +# python_schema, +# ), +# ] +# ), +# python_schema=python_schema, +# serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.value), +# ) + + +# class Nothing_(BaseOption[_TSource], EffectError): +# """The None option case class. + +# Do not use. Use the singleton `Nothing` instead. Since Nothing is a +# singleton it can be tested e.g using `is`: +# >>> if xs is Nothing: +# ... return True +# """ + +# def default_value(self, value: _TSource) -> _TSource: +# """Get value or default value. + +# Gets the value of the option if the option is Some, otherwise +# returns the specified default value. +# """ +# return value + +# def default_with(self, getter: Callable[[], _TSource]) -> _TSource: +# """Get with default value. + +# Gets the value of the option if the option is Some, otherwise +# returns the value produced by the getter +# """ +# return getter() + +# def is_some(self) -> bool: +# """Returns `False`.""" +# return False + +# def is_none(self) -> bool: +# """Returns `True`.""" +# return True + +# def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: +# return Nothing + +# def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: +# return Nothing + +# def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: +# """Bind option. + +# Applies and returns the result of the mapper if the value is +# `Some`. If the value is `Nothing` then `Nothing` is returned. + +# Args: +# mapper: A function that takes the value of type TSource from +# an option and transforms it into an option containing a +# value of type TResult. + +# Returns: +# An option of the output type of the mapper. +# """ +# return Nothing + +# def or_else(self, if_none: Option[_TSource]) -> Option[_TSource]: +# """Returns `if_none`.""" +# return if_none + +# def or_else_with(self, if_none: Callable[[], Option[_TSource]]) -> Option[_TSource]: +# """Evaluates `if_none` and returns the result.""" +# return if_none() + +# def filter(self, predicate: Callable[[_TSource], bool]) -> Option[_TSource]: +# return Nothing + +# def to_list(self) -> list[_TSource]: +# return [] + +# def to_seq(self) -> Seq[_TSource]: +# # deferred import to avoid circular dependencies +# from expression.collections.seq import Seq + +# return Seq() + +# def to_optional(self) -> _TSource | None: +# """Convert option to an optional.""" +# return None + +# def to_result(self, error: _TError) -> Result[_TSource, _TError]: +# """Convert option to a result.""" +# from expression.core.result import Error + +# return Error(error) + +# def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TError]: +# """Convert option to a result.""" +# from expression.core.result import Error + +# return Error(error()) + +# def dict(self) -> builtins.dict[str, Any]: +# return {} # Pydantic cannot handle None or other types than Optional + +# @property +# def value(self) -> _TSource: +# """Returns the value wrapped by the option. + +# A `ValueError` is raised if the option is `Nothing`. +# """ +# raise ValueError("There is no value.") + +# def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: +# """Return iterator for the `Nothing` case. + +# We basically want to return nothing, but we have to return +# something to signal fail. +# """ +# raise Nothing +# while False: +# yield + +# def __lt__(self, other: Any) -> bool: +# return True + +# def __eq__(self, o: Any) -> bool: +# if o is Nothing: +# return True +# return False + +# def __str__(self): +# return "Nothing" + +# def __hash__(self) -> int: +# return 0 + +# @classmethod +# def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: +# print("Nothing:__get_pydantic_core_schema__", source_type, handler) +# value_schema = handler.generate_schema(None) + +# def validate(v: None, handler: ValidatorFunctionWrapHandler) -> Nothing_[Any]: +# print("Nothing_:val_item, nothing", v, handler) +# v = handler(v) +# print("Nothing_:val_item, value:", v) +# return Nothing + +# python_schema = core_schema.union_schema( +# [ +# core_schema.is_instance_schema(Nothing_), +# core_schema.chain_schema( +# [ +# # Ensure the value is an instance of Owner +# # core_schema.is_instance_schema(None), +# # Use the item_schema to validate `items` +# core_schema.no_info_wrap_validator_function(validate, value_schema), +# ] +# ), +# ] +# ) + +# return core_schema.json_or_python_schema( +# # for JSON accept null object +# json_schema=core_schema.chain_schema( +# [ +# core_schema.any_schema(), +# # after validating the json data convert it to python +# core_schema.no_info_before_validator_function( +# lambda data: Some(data), +# python_schema, +# ), +# ] +# ), +# python_schema=python_schema, +# serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: None), +# ) + + +# # The singleton None class. We use the name 'Nothing' here instead of `None` to +# # avoid conflicts with the builtin `None` value in Python. +# TODO: also allow None here? +Nothing: Option[Any] = Option[Any].Nothing() """Singleton `Nothing` object. Since Nothing is a singleton it can be tested e.g using `is`: @@ -481,6 +709,11 @@ def __hash__(self) -> int: """ +def Some(value: _TSource) -> Option[_TSource]: + """Create a Some option.""" + return Option.Some(value) + + @curry_flip(1) def bind(option: Option[_TSource], mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: """Bind option. @@ -524,11 +757,11 @@ def _default_with(option: Option[_TSource]) -> _TSource: return _default_with -def is_none(option: Option[_TSource]) -> TypeGuard[Nothing_[_TSource]]: +def is_none(option: Option[_TSource]) -> TypeGuard[Option[_TSource]]: return option.is_none() -def is_some(option: Option[_TSource]) -> TypeGuard[Some[_TSource]]: +def is_some(option: Option[_TSource]) -> TypeGuard[Option[_TSource]]: return option.is_some() @@ -600,10 +833,10 @@ def of_obj(value: Any) -> Option[Any]: def of_result(result: Result[_TSource, _TError]) -> Option[_TSource]: - from expression.core.result import Ok + from expression.core.result import Result match result: - case Ok(value): + case Result(tag="ok", ok=value): return Some(value) case _: return Nothing @@ -617,8 +850,8 @@ def to_result_with(value: Option[_TSource], error: Callable[[], _TError]) -> Res return value.to_result_with(error) -def dict(value: Option[_TSource]) -> _TSource | builtins.dict[Any, Any] | None: - return value.dict() +def model_dump(value: Option[_TSource]) -> _TSource | builtins.dict[Any, Any] | None: + return value.model_dump() def default_arg(value: Option[_TSource], default_value: _TSource) -> _TSource: @@ -631,13 +864,10 @@ def default_arg(value: Option[_TSource], default_value: _TSource) -> _TSource: return value.default_value(default_value) -Option: TypeAlias = Some[_TSource] | Nothing_[_TSource] - __all__ = [ "Option", "Some", "Nothing", - "Nothing_", "bind", "default_arg", "default_value", @@ -648,7 +878,7 @@ def default_arg(value: Option[_TSource], default_value: _TSource) -> _TSource: "is_some", "or_else", "to_list", - "dict", + "model_dump", "to_seq", "to_optional", "of_optional", diff --git a/expression/core/result.py b/expression/core/result.py index 3d133ccd..7b15a332 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -11,20 +11,21 @@ from __future__ import annotations import builtins -from abc import ABC, abstractmethod -from collections.abc import Callable, Generator, Iterable, Iterator +from collections.abc import Callable, Generator, Iterable from typing import ( TYPE_CHECKING, Any, - ClassVar, Generic, - TypeAlias, + Literal, TypeGuard, TypeVar, - cast, + get_args, get_origin, ) +from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler +from pydantic_core import CoreSchema, core_schema + if TYPE_CHECKING: from expression.core.option import Option @@ -32,7 +33,9 @@ from .curry import curry_flip from .error import EffectError from .pipe import PipeMixin -from .typing import GenericValidator, ModelField, SupportsValidation + +# from .typing import GenericValidator, ModelField, SupportsValidation +from .union import case, tag, tagged_union _TSource = TypeVar("_TSource") @@ -41,111 +44,154 @@ _TError = TypeVar("_TError") -def _validate(result: Any, field: ModelField) -> Result[Any, Any]: - if isinstance(result, BaseResult): - return cast(Result[Any, Any], result) - - if not isinstance(result, builtins.dict): - raise ValueError("not result type") - - try: - value: Any = result["ok"] - if field.sub_fields: - sub_field = field.sub_fields[0] - value, err = sub_field.validate(value, {}, loc="Result") - if err: - raise ValueError(str(err)) - return Ok(value) - except KeyError: - try: - error: Any = result["error"] - sub_field = field.sub_fields[1] - error, err = sub_field.validate(error, {}, loc="Result") - if err: - raise ValueError(str(err)) - return Error(error) - except KeyError: - raise ValueError("not a result") - - -class BaseResult( +@tagged_union +class Result( Iterable[_TSource], PipeMixin, - SupportsValidation["BaseResult[_TSource, _TError]"], Generic[_TSource, _TError], - ABC, ): - """The result abstract base class.""" + """The result class.""" + + tag: Literal["ok", "error"] = tag() + + ok: _TSource = case() + error: _TError = case() - __validators__: ClassVar = [_validate] + @staticmethod + def Ok(value: _TSource) -> Result[_TSource, _TError]: + """Create a new Ok result.""" + return Result(tag="ok", ok=value) + + @staticmethod + def Error(error: _TError) -> Result[_TSource, _TError]: + """Create a new Error result.""" + return Result(tag="error", error=error) - @abstractmethod def default_value(self, value: _TSource) -> _TSource: """Get with default value. Gets the value of the result if the result is Ok, otherwise returns the specified default value. """ - raise NotImplementedError + match self: + case Result(tag="ok", ok=value): + return value + case _: + return value - @abstractmethod def default_with(self, getter: Callable[[_TError], _TSource]) -> _TSource: """Get with default value lazily. Gets the value of the result if the result is Ok, otherwise returns the value produced by the getter """ - raise NotImplementedError + match self: + case Result(tag="ok", ok=value): + return value + case Result(error=error): + return getter(error) - @abstractmethod def map(self, mapper: Callable[[_TSource], _TResult]) -> Result[_TResult, _TError]: - raise NotImplementedError + """Map result. + + Return a result of the value after applying the mapping + function, or Error if the input is Error. + """ + match self: + case Result(tag="ok", ok=value): + return Result.Ok(mapper(value)) + case Result(error=error): + return Result[_TResult, _TError].Error(error) - @abstractmethod def map2( self, - other: Ok[_TOther, _TError] | Error[_TOther, _TError], + other: Result[_TOther, _TError], mapper: Callable[[_TSource, _TOther], _TResult], ) -> Result[_TResult, _TError]: - raise NotImplementedError + """Map result. + + Return a result of the value after applying the mapping + function, or Error if the input is Error. + """ + match self: + case Result(tag="ok", ok=value): + return other.map(lambda value_: mapper(value, value_)) + case Result(error=error): + return Result(error=error) - @abstractmethod def map_error(self, mapper: Callable[[_TError], _TResult]) -> Result[_TSource, _TResult]: """Map error. Return a result of the error value after applying the mapping function, or Ok if the input is Ok. """ - raise NotImplementedError + match self: + case Result(tag="ok", ok=value): + return Result[_TSource, _TResult].Ok(value) + case Result(error=error): + return Result.Error(mapper(error)) - @abstractmethod def bind(self, mapper: Callable[[_TSource], Result[_TResult, _TError]]) -> Result[_TResult, _TError]: - raise NotImplementedError + """Bind result. + + Return a result of the value after applying the mapping + function, or Error if the input is Error. + """ + match self: + case Result(tag="ok", ok=value): + return mapper(value) + case Result(error=error): + return Result[_TResult, _TError].Error(error) - @abstractmethod def is_error(self) -> bool: """Returns `True` if the result is an `Error` value.""" - raise NotImplementedError + match self: + case Result(tag="ok"): + return False + case _: + return True - @abstractmethod def is_ok(self) -> bool: """Return `True` if the result is an `Ok` value.""" - raise NotImplementedError + match self: + case Result(tag="ok"): + return True + case _: + return False - @abstractmethod - def dict(self) -> builtins.dict[str, _TSource | _TError]: + def model_dump(self) -> builtins.dict[str, _TSource | _TError]: """Return a json serializable representation of the result.""" - raise NotImplementedError + match self: + case Result(tag="ok", ok=value): + attr = getattr(value, "model_dump", None) + if attr and callable(attr): + value = attr() + return {"ok": value} + case Result(error=error): + attr = getattr(error, "model_dump", None) + if attr and callable(attr): + error = attr() + return {"error": error} - @abstractmethod def swap(self) -> Result[_TError, _TSource]: """Swaps the value in the result so an Ok becomes an Error and an Error becomes an Ok.""" - raise NotImplementedError + match self: + case Result(tag="ok", ok=value): + return Result(error=value) + case Result(error=error): + return Result(ok=error) - @abstractmethod def to_option(self) -> Option[_TSource]: """Convert result to an option.""" - raise NotImplementedError + match self: + case Result(tag="ok", ok=value): + from expression.core.option import Some + + return Some(value) + case _: + from expression.core.option import Nothing + + return Nothing @classmethod def of_option(cls, value: Option[_TSource], error: _TError) -> Result[_TSource, _TError]: @@ -158,130 +204,110 @@ def of_option_with(cls, value: Option[_TSource], error: Callable[[], _TError]) - return of_option_with(value, error) def __eq__(self, o: Any) -> bool: - raise NotImplementedError + return isinstance(o, Result) and self.tag == o.tag and getattr(self, self.tag) == getattr(o, self.tag) # type: ignore - @abstractmethod def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: - raise NotImplementedError + match self: + case Result(tag="ok", ok=value): + return (yield value) + case _: + raise EffectError(self) + + def __str__(self) -> str: + match self: + case Result(tag="ok", ok=value): + return f"Ok {value}" + case Result(error=error): + return f"Error {error}" def __repr__(self) -> str: return str(self) - @classmethod - def __get_validators__( - cls, - ) -> Iterator[GenericValidator[BaseResult[_TSource, _TError]]]: - yield from cls.__validators__ - - @abstractmethod def __hash__(self) -> int: - raise NotImplementedError - - -class Ok(BaseResult[_TSource, _TError]): - """The Ok result case class.""" - - __match_args__ = ("value",) - - def default_value(self, value: _TSource) -> _TSource: - """Get with default value. - - Gets the value of the option if the option is Some, otherwise - returns the specified default value. - """ - return self._value - - def default_with(self, getter: Callable[[_TError], _TSource]) -> _TSource: - """Get with default value lazily. - - Gets the value of the option if the option is Some, otherwise - returns the value produced by the getter - """ - return self._value - - def __init__(self, value: _TSource) -> None: - self._value = value + return hash(repr(self)) - @property - def value(self) -> _TSource: - return self._value - - def map(self, mapper: Callable[[_TSource], _TResult]) -> Result[_TResult, _TError]: - return Ok(mapper(self._value)) - - def map2( - self, - other: Ok[_TOther, _TError] | Error[_TOther, _TError], - mapper: Callable[[_TSource, _TOther], _TResult], - ) -> Result[_TResult, _TError]: - return other.map(lambda value: mapper(self._value, value)) - - def bind(self, mapper: Callable[[_TSource], Result[_TResult, _TError]]) -> Result[_TResult, _TError]: - return mapper(self._value) - - def map_error(self, mapper: Callable[[_TError], _TResult]) -> Result[_TSource, _TResult]: - """Map error. - - Return a result of the error value after applying the mapping - function, or Ok if the input is Ok. - """ - return Ok(self._value) - - def is_error(self) -> bool: - """Returns `True` if the result is an `Ok` value.""" - return False - - def is_ok(self) -> bool: - """Returns `True` if the result is an `Ok` value.""" - return True - - def dict(self) -> builtins.dict[str, _TSource | _TError]: - """Returns a json string representation of the ok value.""" - attr = getattr(self._value, "dict", None) or getattr(self._value, "dict", None) - if attr and callable(attr): - value = attr() + @classmethod + def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: + origin = get_origin(source_type) + if origin is None: # used as `x: Result` without params + origin = source_type + type_vars = (Any, Any) else: - value = self._value - - return {"ok": value} - - def swap(self) -> Result[_TError, _TSource]: - """Swaps the value in the result so an Ok becomes an Error and an Error becomes an Ok.""" - return Error(self._value) - - def to_option(self) -> Option[_TSource]: - """Convert result to an option.""" - from expression.core.option import Some - - return Some(self._value) - - def __match__(self, pattern: Any) -> Iterable[_TSource]: - if self is pattern or self == pattern: - return [self.value] - - try: - origin: Any = get_origin(pattern) - if isinstance(self, origin or pattern): - return [self.value] - except TypeError: - pass - - return [] - - def __eq__(self, o: Any) -> bool: - if isinstance(o, Ok): - return self.value == o.value # type: ignore - return False - - def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: - """Return iterator for Ok case.""" - return (yield self._value) - - def __str__(self): - return f"Ok {self._value}" - - def __hash__(self) -> int: - return hash(self._value) + type_vars = get_args(source_type) + + ok_schema = handler.generate_schema(type_vars[0]) + error_schema = handler.generate_schema(type_vars[1]) + + def validate_ok(v: Any, handler: ValidatorFunctionWrapHandler) -> Result[_TSource, _TError]: + if "ok" not in v: + raise ValueError("Missing ok field") + value = handler(v["ok"]) + return cls(ok=value) + + def validate_error(v: Any, handler: ValidatorFunctionWrapHandler) -> Result[_TSource, _TError]: + if "error" not in v: + raise ValueError("Missing error field") + + value = handler(v["error"]) + return cls(error=value) + + python_schema = core_schema.union_schema( + [ + core_schema.is_instance_schema(cls), + core_schema.no_info_wrap_validator_function(validate_error, error_schema), + core_schema.no_info_wrap_validator_function(validate_ok, ok_schema), + ] + ) + json_schema = core_schema.chain_schema( + [ + core_schema.union_schema( + [ + core_schema.typed_dict_schema( + { + "tag": core_schema.typed_dict_field(core_schema.str_schema()), + "ok": core_schema.typed_dict_field(ok_schema), + } + ), + core_schema.typed_dict_schema( + { + "tag": core_schema.typed_dict_field(core_schema.str_schema()), + "error": core_schema.typed_dict_field(error_schema), + } + ), + ] + ), + # after validating the json data convert it to python + core_schema.no_info_before_validator_function( + lambda data: cls(data), + python_schema, + ), + ] + ) + + return core_schema.json_or_python_schema( + json_schema=json_schema, + python_schema=python_schema, + serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.model_dump()), + ) + + +def Error(error: _TError) -> Result[Any, _TError]: + return Result[Any, _TError].Error(error) + + +def Ok(value: _TSource) -> Result[_TSource, Any]: + return Result[_TSource, Any].Ok(value) + + +# class Ok(Result[_TSource, Any]): +# ok: _TSource = case() +# tag = "ok" + + +# class Error(Result[Any, _TError]): +# error: _TError = case() + +# tag = "error" class ResultException(EffectError): @@ -294,108 +320,6 @@ def __init__(self, message: str): self.message = message -class Error( - ResultException, - BaseResult[_TSource, _TError], -): - """The Error result case class.""" - - __match_args__ = ("error",) - - def __init__(self, error: _TError) -> None: - super().__init__(str(error)) - self._error = error - - def default_value(self, value: _TSource) -> _TSource: - """Get with default value. - - Gets the value of the option if the option is Some, otherwise - returns the specified default value. - """ - return value - - def default_with(self, getter: Callable[[_TError], _TSource]) -> _TSource: - """Get with default value lazily. - - Gets the value of the option if the option is Some, otherwise - returns the value produced by the getter - """ - return getter(self._error) - - @property - def error(self) -> _TError: - return self._error - - def map(self, mapper: Callable[[_TSource], _TResult]) -> Result[_TResult, _TError]: - return Error(self._error) - - def map2( - self, - other: Result[_TOther, _TError], - mapper: Callable[[_TSource, _TOther], _TResult], - ) -> Result[_TResult, _TError]: - return Error(self._error) - - def bind(self, mapper: Callable[[_TSource], Result[_TResult, _TError]]) -> Result[_TResult, _TError]: - return Error(self._error) - - def map_error(self, mapper: Callable[[_TError], _TResult]) -> Result[_TSource, _TResult]: - """Map error. - - Return a result of the error value after applying the mapping - function, or Ok if the input is Ok. - """ - return Error(mapper(self._error)) - - def is_error(self) -> bool: - """Returns `True` if the result is an `Ok` value.""" - return True - - def is_ok(self) -> bool: - """Returns `True` if the result is an `Ok` value.""" - return False - - def dict(self) -> builtins.dict[str, Any]: - """Returns a json serializable representation of the error value.""" - attr = getattr(self._error, "dict") or getattr(self._error, "dict") - if callable(attr): - error = attr() - else: - error = self._error - - return {"error": error} - - def swap(self) -> Result[_TError, _TSource]: - """Swaps the value in the result so an Ok becomes an Error and an Error becomes an Ok.""" - return Ok(self._error) - - def to_option(self) -> Option[_TSource]: - """Convert result to an option.""" - from expression.core.option import Nothing - - return Nothing - - def __eq__(self, o: Any) -> bool: - if isinstance(o, Error): - return self.error == o.error # type: ignore - return False - - def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: - """Return iterator for Error case.""" - # Raise class here so sub-classes like Failure works as well. - raise self.__class__(self._error) - - # We're a generator - while False: - yield - - def __str__(self): - return f"Error {self._error}" - - def __hash__(self) -> int: - return hash(self._error) - - def default_value(value: _TSource) -> Callable[[Result[_TSource, Any]], _TSource]: """Get the value or default value. @@ -429,8 +353,8 @@ def map(result: Result[_TSource, _TError], mapper: Callable[[_TSource], _TResult @curry_flip(2) def map2( - x: Ok[_TSource, _TError] | Error[_TSource, _TError], - y: Ok[_TOther, _TError] | Error[_TOther, _TError], + x: Result[_TSource, _TError], + y: Result[_TOther, _TError], mapper: Callable[[_TSource, _TOther], _TResult], ) -> Result[_TResult, _TError]: return x.map2(y, mapper) @@ -445,15 +369,15 @@ def bind( def dict(source: Result[_TSource, _TError]) -> builtins.dict[str, _TSource | _TError]: - return source.dict() + return source.model_dump() -def is_ok(result: Result[_TSource, _TError]) -> TypeGuard[Ok[_TSource, _TError]]: +def is_ok(result: Result[_TSource, _TError]) -> TypeGuard[Result[_TSource, _TError]]: """Returns `True` if the result is an `Ok` value.""" return result.is_ok() -def is_error(result: Result[_TSource, _TError]) -> TypeGuard[Error[_TSource, _TError]]: +def is_error(result: Result[_TSource, _TError]) -> TypeGuard[Result[_TSource, _TError]]: """Returns `True` if the result is an `Error` value.""" return result.is_error() @@ -463,11 +387,11 @@ def swap(result: Result[_TSource, _TError]) -> Result[_TError, _TSource]: return result.swap() -def to_option(result: Result[_TSource, _TError]) -> Option[_TSource]: +def to_option(result: Result[_TSource, Any]) -> Option[_TSource]: from expression.core.option import Nothing, Some match result: - case Ok(value): + case Result(tag="ok", ok=value): return Some(value) case _: return Nothing @@ -481,8 +405,6 @@ def of_option_with(value: Option[_TSource], error: Callable[[], _TError]) -> Res return value.to_result_with(error) -Result: TypeAlias = Ok[_TSource, _TError] | Error[_TSource, _TError] - __all__ = [ "Result", "Ok", diff --git a/expression/core/try_.py b/expression/core/try_.py index 13e2c9d8..53abfc6d 100644 --- a/expression/core/try_.py +++ b/expression/core/try_.py @@ -6,31 +6,32 @@ Everything else is the same as `Result`, just simpler to use. """ -from typing import TypeVar +from typing import Any, TypeVar from .result import Error, Ok, Result +from .union import case _TSource = TypeVar("_TSource") -Try = Result[_TSource, Exception] +class Try(Result[_TSource, Exception]): + pass -class Success(Ok[_TSource, Exception]): + +def Success(value: _TSource) -> Try[_TSource]: """The successful Try case. Same as result `Ok` but with error type pinned to an exception, i.e: `Ok[TSource, Exception]` """ - - ... + return Try[_TSource](ok=value) -class Failure(Error[_TSource, Exception]): +def Failure(error: Exception) -> Try[Any]: """The failure Try case. Same as result `Error` but with error type pinned to an exception, i.e: `Error[TSource, Exception]` """ - - ... + return Try[Any](error=error) diff --git a/expression/core/union.py b/expression/core/union.py index 7d2ac5dc..47a84b34 100644 --- a/expression/core/union.py +++ b/expression/core/union.py @@ -1,133 +1,93 @@ -from __future__ import annotations - -import itertools -from abc import ABC -from collections.abc import Iterator -from typing import Any, Generic, TypeVar, cast - -from .pipe import PipeMixin -from .typing import GenericValidator, ModelField, SupportsValidation +from copy import deepcopy +from dataclasses import dataclass, field, fields +from typing import Any, TypeVar, dataclass_transform _T = TypeVar("_T") -class Tag(Generic[_T]): - """For creating tagged union cases. - - Args: - tag: Optional tag number. If not set it will be generated - automatically. - - """ - - __match_args__ = ("tag",) - - INITIAL_TAG = 1000 - _count = itertools.count(start=INITIAL_TAG) - - def __init__(self, tag: int | None = None) -> None: - self.tag = tag or next(Tag._count) - - def __eq__(self, other: Any) -> bool: - if self is other: - return True - - if not isinstance(other, Tag): - return False - - return self.tag == other.tag - - def __str__(self) -> str: - return f"tag: {self.tag}" - - def __repr__(self) -> str: - return f"tag: {self.tag}" - - -def tag(tag: int | None = None) -> Tag[None]: - """Convenience from creating tags. - - Less and simpler syntax since the type is given as an argument. - """ - return Tag(tag) - - -class TypedTaggedUnion(SupportsValidation["TypedTaggedUnion[_T]"], Generic[_T], PipeMixin, ABC): - """A discriminated (tagged) union. - - Takes a value, and an optional tag that may be used for matching. - """ - - __match_args__ = ("tag", "value") - - def __init__(self, tag: Tag[_T], value: _T = None) -> None: - self.value = value - self.tag = tag +@dataclass_transform() +def tagged_union(cls: type[_T]) -> type[_T]: + cls = dataclass(cls) # TODO: decide if we should be a dataclass or not + fields_ = fields(cls) # type: ignore + field_names = {f.name for f in fields_} + field_names.add("tag") + original_init = cls.__init__ - if not hasattr(self.__class__, "_tags"): - tags = {tag.tag: name for (name, tag) in self.__class__.__dict__.items() if isinstance(tag, Tag)} - setattr(self.__class__, "_tags", tags) + def __init__(self: Any, *args: Any, **kwargs: Any) -> None: + tag = kwargs.pop("tag", None) + if len(kwargs) != 1: + raise TypeError(f"One and only one case can be specified. Not {kwargs}") + name, value = next(iter(kwargs.items())) + if name not in field_names: + raise TypeError(f"Unknown case name: {name}") + if tag is not None and tag != name: + raise TypeError(f"Tag {tag} does not match case name {name}") - self.name = getattr(self.__class__, "_tags")[tag.tag] + # Cannot use setattr because it is overridden + object.__setattr__(self, "tag", name) + object.__setattr__(self, name, value) - def dict(self) -> Any: - tags: dict[str, Any] = {k: v for (k, v) in self.__class__.__dict__.items() if v is self.tag} - if self.value and hasattr(self.value, "dict"): - value: Any = self.value.dict() # type: ignore - else: - value = self.value - return dict(tag=next(iter(tags.keys())), value=value) + # Enables the use of dataclasses.asdict + union_fields = dict((f.name, f) for f in fields_ if f.name in [name, "tag"]) + object.__setattr__(self, "__dataclass_fields__", union_fields) # type: ignore + # print("original_init: ", original_init) + original_init(self) - def __str__(self) -> str: - return f"{self.__class__.__name__}: {self.name} {self.value}" + def __repr__(self: Any) -> str: + return f"{cls.__name__}({self.tag}={getattr(self, self.tag)})" - def __repr__(self) -> str: - return str(self) + def __hash__(self: Any) -> int: + return hash((cls.__name__, self.tag, getattr(self, self.tag))) - @classmethod - def __get_validators__(cls) -> Iterator[GenericValidator[TypedTaggedUnion[_T]]]: - def _validate(union: Any, field: ModelField) -> TypedTaggedUnion[_T]: - if isinstance(union, TypedTaggedUnion): - return cast(TypedTaggedUnion[_T], union) + def __setattr__(self: Any, name: str, value: Any) -> None: + if name in field_names: + raise TypeError("Cannot change the value of a tagged union case") - tags: dict[str, Any] = {k: v for (k, v) in cls.__dict__.items() if k == union["tag"]} - if field.sub_fields: - sub_field = field.sub_fields[0] - value, error = sub_field.validate(union["value"], {}, loc=union["tag"]) - if error: - raise ValueError(str(error)) - else: - value = union["value"] - return cls(tags[union["tag"]], value) + object.__setattr__(self, name, value) - yield _validate + def __delattr__(self: Any, name: str) -> None: + if name in field_names: + raise TypeError("Cannot delete a tagged union case") - def __eq__(self, other: Any) -> bool: - if not isinstance(other, TypedTaggedUnion): - return False + object.__delattr__(self, name) - return self.tag == other.tag and self.value == other.value # type: ignore + def __eq__(self: Any, other: Any) -> bool: + return ( + isinstance(other, cls) + and self.tag == getattr(other, "tag") + and getattr(self, self.tag) == getattr(other, self.tag) + ) + def __copy__(self: Any) -> Any: + mapping = {self.tag: getattr(self, self.tag)} + return cls(**mapping) -class TaggedUnion(TypedTaggedUnion[Any]): - ... + def __deepcopy__(self: Any, memo: Any) -> Any: + value = deepcopy(getattr(self, self.tag), memo) + mapping = {self.tag: value} + return cls(**mapping) + cls.__eq__ = __eq__ + cls.__init__ = __init__ # type: ignore + cls.__repr__ = __repr__ + cls.__hash__ = __hash__ + cls.__setattr__ = __setattr__ + cls.__delattr__ = __delattr__ + cls.__match_args__ = tuple(field_names) # type: ignore -class SingleCaseUnion(TypedTaggedUnion[_T]): - """Single case union. + # We need to handle copy and deepcopy ourselves because they are needed by Pydantic + cls.__copy__ = __copy__ # type: ignore + cls.__deepcopy__ = __deepcopy__ # type: ignore - Helper class to make single case tagged unions without having to - declare the tag which is needed to make a tagged union. The name of - the tag for a single case union is `VALUE` and may be used for - matching purposes. - """ + return cls - VALUE = Tag[_T]() - def __init__(self, value: Any) -> None: - setattr(self.__class__, "_tags", {SingleCaseUnion.VALUE.tag: "VALUE"}) - super().__init__(SingleCaseUnion.VALUE, value) +def case() -> Any: + """A case in a tagged union.""" + return field(init=False, kw_only=True) -__all__ = ["SingleCaseUnion", "Tag", "TaggedUnion", "tag"] +def tag() -> Any: + """The tag of a tagged union.""" + return field(init=False, kw_only=True) diff --git a/expression/extra/parser.py b/expression/extra/parser.py index e1e44060..8e2fc41b 100644 --- a/expression/extra/parser.py +++ b/expression/extra/parser.py @@ -130,15 +130,15 @@ def and_then(p2: Parser[_B], p1: Parser[_A]) -> Parser[tuple[_A, _B]]: def run(input: Remaining) -> ParseResult[tuple[_A, _B]]: result1 = p1.run(input) match result1: - case Error(error): + case Result(tag="error", error=error): return Error(error) - case Ok((value1, remaining1)): + case Result(ok=(value1, remaining1)): result2 = p2.run(remaining1) match result2: - case Error(error): + case Result(tag="error", error=error): return Error(error) - case Ok((value2, remaining2)): + case Result(ok=(value2, remaining2)): return Ok(((value1, value2), remaining2)) return Parser(run, f"and_then({p2}, {p1}") @@ -149,8 +149,8 @@ def or_else(p1: Parser[_A], p2: Parser[_A]) -> Parser[_A]: def run(input: Remaining) -> ParseResult[_A]: result1 = p1.run(input) match result1: - case Ok(): - return cast(ParseResult[_A], result1) + case Result(tag="ok"): + return result1 case _: result2 = p2.run(input) return result2 @@ -184,14 +184,14 @@ def run(input: Remaining) -> ParseResult[_B]: # test the result for Failure/Success match result: - case Ok((value, remaining)): + case Result(tag="ok", ok=(value, remaining)): # if success, return the value transformed by f new_value = mapper(value) - return Ok[tuple[_B, Remaining], str]((new_value, remaining)) + return Ok((new_value, remaining)) - case Error(error): + case Result(error=error): # if failed, return the error - return Error[tuple[_B, Remaining], str](error) + return Error(error) return Parser(run, f"map(A => B, {parser})") @@ -287,7 +287,7 @@ def parse_zero_or_more(parser: Parser[_A], input: Remaining) -> tuple[Block[_A], # test the result for Failure/Success match first_result: - case Ok((first_value, input_after_first_parse)): + case Result(tag="ok", ok=(first_value, input_after_first_parse)): # if parse succeeds, call recursively # to get the subsequent values subsequent_values, remaining_input = parse_zero_or_more(parser, input_after_first_parse) @@ -301,7 +301,7 @@ def many(parser: Parser[_A]) -> Parser[Block[_A]]: def run(input: Remaining) -> ParseResult[Block[_A]]: # parse the input -- wrap in Success as it always succeeds ok = parse_zero_or_more(parser, input) - return Ok[tuple[Block[_A], Remaining], str](ok) + return Ok(ok) return Parser(run, f"many({parser})") @@ -312,13 +312,13 @@ def run(input: Remaining) -> ParseResult[Block[_A]]: firstResult = parser.run(input) # test the result for Failure/Success match firstResult: - case Ok((first_value, input_after_first_parse)): + case Result(tag="ok", ok=(first_value, input_after_first_parse)): # if first found, look for zeroOrMore now subsequent_values, remaining_input = parse_zero_or_more(parser, input_after_first_parse) values = subsequent_values.cons(first_value) - return Ok[tuple[Block[_A], Remaining], str]((values, remaining_input)) + return Ok((values, remaining_input)) - case Error(err): + case Result(error=err): return Error(err) # failed return Parser(run, f"many({parser})") @@ -509,10 +509,10 @@ def bind(f: Callable[[_A], Parser[_B]], p: Parser[_A]) -> Parser[_B]: def run(input: Remaining) -> ParseResult[_B]: result1 = p.run(input) match result1: - case Ok((value1, remaning_input)): + case Result(tag="ok", ok=(value1, remaning_input)): p2 = f(value1) return p2.run(remaning_input) - case Error(err): + case Result(error=err): return Error(err) # failed case _: # type: ignore return Error("parser error") diff --git a/expression/extra/result/catch.py b/expression/extra/result/catch.py index c02fa4e6..df74e69e 100644 --- a/expression/extra/result/catch.py +++ b/expression/extra/result/catch.py @@ -5,7 +5,6 @@ from typing import Any, TypeVar, cast, overload from expression.core import Error, Ok, Result -from expression.core.result import BaseResult _TSource = TypeVar("_TSource") @@ -42,7 +41,7 @@ def wrapper(*args: Any, **kwargs: Any) -> Result[_TSource, _TError]: except exception as exn: return Error(cast(_TError, exn)) else: - if isinstance(out, BaseResult): + if isinstance(out, Result): return cast(Result[_TSource, _TError], out) return Ok(out) diff --git a/poetry.lock b/poetry.lock index 984c4aa7..832a24e8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -25,6 +25,17 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + [[package]] name = "appnope" version = "0.1.3" @@ -89,18 +100,15 @@ tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} [[package]] name = "babel" -version = "2.13.1" +version = "2.14.0" description = "Internationalization utilities" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, - {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, ] -[package.dependencies] -setuptools = {version = "*", markers = "python_version >= \"3.12\""} - [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] @@ -124,29 +132,33 @@ lxml = ["lxml"] [[package]] name = "black" -version = "23.10.1" +version = "23.12.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.10.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69"}, - {file = "black-23.10.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916"}, - {file = "black-23.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc"}, - {file = "black-23.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173"}, - {file = "black-23.10.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0"}, - {file = "black-23.10.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace"}, - {file = "black-23.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb"}, - {file = "black-23.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce"}, - {file = "black-23.10.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a"}, - {file = "black-23.10.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1"}, - {file = "black-23.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad"}, - {file = "black-23.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884"}, - {file = "black-23.10.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9"}, - {file = "black-23.10.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7"}, - {file = "black-23.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d"}, - {file = "black-23.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982"}, - {file = "black-23.10.1-py3-none-any.whl", hash = "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe"}, - {file = "black-23.10.1.tar.gz", hash = "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"}, + {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, + {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, + {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, + {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, + {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, + {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, + {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, + {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, + {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, + {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, + {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, + {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, + {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, + {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, + {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, + {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, + {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, + {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, + {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, + {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, + {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, + {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, ] [package.dependencies] @@ -160,19 +172,19 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2023.7.22" +version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, ] [[package]] @@ -376,22 +388,20 @@ files = [ [[package]] name = "comm" -version = "0.1.4" +version = "0.2.0" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "comm-0.1.4-py3-none-any.whl", hash = "sha256:6d52794cba11b36ed9860999cd10fd02d6b2eac177068fdd585e1e2f8a96e67a"}, - {file = "comm-0.1.4.tar.gz", hash = "sha256:354e40a59c9dd6db50c5cc6b4acc887d82e9603787f83b68c01a80a923984d15"}, + {file = "comm-0.2.0-py3-none-any.whl", hash = "sha256:2da8d9ebb8dd7bfc247adaff99f24dce705638a8042b85cb995066793e391001"}, + {file = "comm-0.2.0.tar.gz", hash = "sha256:a517ea2ca28931c7007a7a99c562a0fa5883cfb48963140cf642c41c948498be"}, ] [package.dependencies] traitlets = ">=4" [package.extras] -lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"] test = ["pytest"] -typing = ["mypy (>=0.990)"] [[package]] name = "coverage" @@ -514,13 +524,13 @@ files = [ [[package]] name = "distlib" -version = "0.3.7" +version = "0.3.8" description = "Distribution utilities" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, - {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] [[package]] @@ -535,13 +545,13 @@ files = [ [[package]] name = "docutils" -version = "0.17.1" +version = "0.18.1" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, + {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, + {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] [[package]] @@ -560,13 +570,13 @@ packaging = ">=20.9" [[package]] name = "exceptiongroup" -version = "1.1.3" +version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, - {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, ] [package.extras] @@ -588,13 +598,13 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "fastjsonschema" -version = "2.18.1" +version = "2.19.1" description = "Fastest Python implementation of JSON schema" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.18.1-py3-none-any.whl", hash = "sha256:aec6a19e9f66e9810ab371cc913ad5f4e9e479b63a7072a2cd060a9369e329a8"}, - {file = "fastjsonschema-2.18.1.tar.gz", hash = "sha256:06dc8680d937628e993fa0cd278f196d20449a1adc087640710846b324d422ea"}, + {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, + {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, ] [package.extras] @@ -634,87 +644,88 @@ pyflakes = ">=3.1.0,<3.2.0" [[package]] name = "greenlet" -version = "3.0.1" +version = "3.0.3" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" files = [ - {file = "greenlet-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63"}, - {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e"}, - {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846"}, - {file = "greenlet-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9"}, - {file = "greenlet-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234"}, - {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884"}, - {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94"}, - {file = "greenlet-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c"}, - {file = "greenlet-3.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5"}, - {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d"}, - {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445"}, - {file = "greenlet-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80ac992f25d10aaebe1ee15df45ca0d7571d0f70b645c08ec68733fb7a020206"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:337322096d92808f76ad26061a8f5fccb22b0809bea39212cd6c406f6a7060d2"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9934adbd0f6e476f0ecff3c94626529f344f57b38c9a541f87098710b18af0a"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4d815b794fd8868c4d67602692c21bf5293a75e4b607bb92a11e821e2b859a"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41bdeeb552d814bcd7fb52172b304898a35818107cc8778b5101423c9017b3de"}, - {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6e6061bf1e9565c29002e3c601cf68569c450be7fc3f7336671af7ddb4657166"}, - {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa24255ae3c0ab67e613556375a4341af04a084bd58764731972bcbc8baeba36"}, - {file = "greenlet-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:b489c36d1327868d207002391f662a1d163bdc8daf10ab2e5f6e41b9b96de3b1"}, - {file = "greenlet-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f33f3258aae89da191c6ebaa3bc517c6c4cbc9b9f689e5d8452f7aedbb913fa8"}, - {file = "greenlet-3.0.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d2905ce1df400360463c772b55d8e2518d0e488a87cdea13dd2c71dcb2a1fa16"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a02d259510b3630f330c86557331a3b0e0c79dac3d166e449a39363beaae174"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55d62807f1c5a1682075c62436702aaba941daa316e9161e4b6ccebbbf38bda3"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3fcc780ae8edbb1d050d920ab44790201f027d59fdbd21362340a85c79066a74"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eddd98afc726f8aee1948858aed9e6feeb1758889dfd869072d4465973f6bfd"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eabe7090db68c981fca689299c2d116400b553f4b713266b130cfc9e2aa9c5a9"}, - {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f2f6d303f3dee132b322a14cd8765287b8f86cdc10d2cb6a6fae234ea488888e"}, - {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d923ff276f1c1f9680d32832f8d6c040fe9306cbfb5d161b0911e9634be9ef0a"}, - {file = "greenlet-3.0.1-cp38-cp38-win32.whl", hash = "sha256:0b6f9f8ca7093fd4433472fd99b5650f8a26dcd8ba410e14094c1e44cd3ceddd"}, - {file = "greenlet-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:990066bff27c4fcf3b69382b86f4c99b3652bab2a7e685d968cd4d0cfc6f67c6"}, - {file = "greenlet-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ce85c43ae54845272f6f9cd8320d034d7a946e9773c693b27d620edec825e376"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ee2e967bd7ff85d84a2de09df10e021c9b38c7d91dead95b406ed6350c6997"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87c8ceb0cf8a5a51b8008b643844b7f4a8264a2c13fcbcd8a8316161725383fe"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6a8c9d4f8692917a3dc7eb25a6fb337bff86909febe2f793ec1928cd97bedfc"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fbc5b8f3dfe24784cee8ce0be3da2d8a79e46a276593db6868382d9c50d97b1"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85d2b77e7c9382f004b41d9c72c85537fac834fb141b0296942d52bf03fe4a3d"}, - {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:696d8e7d82398e810f2b3622b24e87906763b6ebfd90e361e88eb85b0e554dc8"}, - {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:329c5a2e5a0ee942f2992c5e3ff40be03e75f745f48847f118a3cfece7a28546"}, - {file = "greenlet-3.0.1-cp39-cp39-win32.whl", hash = "sha256:cf868e08690cb89360eebc73ba4be7fb461cfbc6168dd88e2fbbe6f31812cd57"}, - {file = "greenlet-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac4a39d1abae48184d420aa8e5e63efd1b75c8444dd95daa3e03f6c6310e9619"}, - {file = "greenlet-3.0.1.tar.gz", hash = "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b"}, -] - -[package.extras] -docs = ["Sphinx"] + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] [[package]] name = "hypothesis" -version = "6.88.1" +version = "6.92.2" description = "A library for property-based testing" optional = false python-versions = ">=3.8" files = [ - {file = "hypothesis-6.88.1-py3-none-any.whl", hash = "sha256:b45b8a651dfe4ce26f900ce6ccbce997d4fbec39ba03dd243516bf81fea8c0b8"}, - {file = "hypothesis-6.88.1.tar.gz", hash = "sha256:f4c2c004b9ec3e0e25332ad2cb6b91eba477a855557a7b5c6e79068809ff8b51"}, + {file = "hypothesis-6.92.2-py3-none-any.whl", hash = "sha256:d335044492acb03fa1fdb4edacb81cca2e578049fc7306345bc0e8947fef15a9"}, + {file = "hypothesis-6.92.2.tar.gz", hash = "sha256:841f89a486c43bdab55698de8929bd2635639ec20bf6ce98ccd75622d7ee6d41"}, ] [package.dependencies] -attrs = ">=19.2.0" +attrs = ">=22.2.0" exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} sortedcontainers = ">=2.1.0,<3.0.0" @@ -736,13 +747,13 @@ zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2023.3)"] [[package]] name = "identify" -version = "2.5.31" +version = "2.5.33" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.31-py2.py3-none-any.whl", hash = "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d"}, - {file = "identify-2.5.31.tar.gz", hash = "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75"}, + {file = "identify-2.5.33-py2.py3-none-any.whl", hash = "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34"}, + {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"}, ] [package.extras] @@ -750,13 +761,13 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] [[package]] @@ -772,20 +783,20 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.8.0" +version = "7.0.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, + {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, + {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] @@ -802,13 +813,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.26.0" +version = "6.28.0" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.26.0-py3-none-any.whl", hash = "sha256:3ba3dc97424b87b31bb46586b5167b3161b32d7820b9201a9e698c71e271602c"}, - {file = "ipykernel-6.26.0.tar.gz", hash = "sha256:553856658eb8430bbe9653ea041a41bff63e9606fc4628873fc92a6cf3abd404"}, + {file = "ipykernel-6.28.0-py3-none-any.whl", hash = "sha256:c6e9a9c63a7f4095c0a22a79f765f079f9ec7be4f2430a898ddea889e8665661"}, + {file = "ipykernel-6.28.0.tar.gz", hash = "sha256:69c11403d26de69df02225916f916b37ea4b9af417da0a8c827f84328d88e5f3"}, ] [package.dependencies] @@ -822,7 +833,7 @@ matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" psutil = "*" -pyzmq = ">=20" +pyzmq = ">=24" tornado = ">=6.1" traitlets = ">=5.4.0" @@ -835,24 +846,23 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.17.2" +version = "8.18.1" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" files = [ - {file = "ipython-8.17.2-py3-none-any.whl", hash = "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444"}, - {file = "ipython-8.17.2.tar.gz", hash = "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb"}, + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, ] [package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +prompt-toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" @@ -873,20 +883,17 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pa [[package]] name = "isort" -version = "5.12.0" +version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +colors = ["colorama (>=0.4.6)"] [[package]] name = "jedi" @@ -926,13 +933,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.19.2" +version = "4.20.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.19.2-py3-none-any.whl", hash = "sha256:eee9e502c788e89cb166d4d37f43084e3b64ab405c795c03d343a4dbc2c810fc"}, - {file = "jsonschema-4.19.2.tar.gz", hash = "sha256:c9ff4d7447eed9592c23a12ccee508baf0dd0d59650615e847feb6cdca74f392"}, + {file = "jsonschema-4.20.0-py3-none-any.whl", hash = "sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3"}, + {file = "jsonschema-4.20.0.tar.gz", hash = "sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa"}, ] [package.dependencies] @@ -947,17 +954,17 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "jsonschema-specifications" -version = "2023.7.1" +version = "2023.12.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, - {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, ] [package.dependencies] -referencing = ">=0.28.0" +referencing = ">=0.31.0" [[package]] name = "jupyter-book" @@ -1025,13 +1032,13 @@ testing = ["coverage", "ipykernel", "jupytext", "matplotlib", "nbdime", "nbforma [[package]] name = "jupyter-client" -version = "8.5.0" +version = "8.6.0" description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.5.0-py3-none-any.whl", hash = "sha256:c3877aac7257ec68d79b5c622ce986bd2a992ca42f6ddc9b4dd1da50e89f7028"}, - {file = "jupyter_client-8.5.0.tar.gz", hash = "sha256:e8754066510ce456358df363f97eae64b50860f30dc1fe8c6771440db3be9a63"}, + {file = "jupyter_client-8.6.0-py3-none-any.whl", hash = "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99"}, + {file = "jupyter_client-8.6.0.tar.gz", hash = "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7"}, ] [package.dependencies] @@ -1048,13 +1055,13 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.5.0" +version = "5.5.1" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.5.0-py3-none-any.whl", hash = "sha256:e11e02cd8ae0a9de5c6c44abf5727df9f2581055afe00b22183f621ba3585805"}, - {file = "jupyter_core-5.5.0.tar.gz", hash = "sha256:880b86053bf298a8724994f95e99b99130659022a4f7f45f563084b6223861d3"}, + {file = "jupyter_core-5.5.1-py3-none-any.whl", hash = "sha256:220dfb00c45f0d780ce132bb7976b58263f81a3ada6e90a9b6823785a424f739"}, + {file = "jupyter_core-5.5.1.tar.gz", hash = "sha256:1553311a97ccd12936037f36b9ab4d6ae8ceea6ad2d5c90d94a909e752178e40"}, ] [package.dependencies] @@ -1409,24 +1416,24 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.11.2" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] name = "pexpect" -version = "4.8.0" +version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" files = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, ] [package.dependencies] @@ -1434,13 +1441,13 @@ ptyprocess = ">=0.5" [[package]] name = "platformdirs" -version = "3.11.0" +version = "4.1.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, - {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, ] [package.extras] @@ -1464,13 +1471,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.5.0" +version = "3.6.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, - {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, + {file = "pre_commit-3.6.0-py2.py3-none-any.whl", hash = "sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376"}, + {file = "pre_commit-3.6.0.tar.gz", hash = "sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d"}, ] [package.dependencies] @@ -1482,13 +1489,13 @@ virtualenv = ">=20.10.0" [[package]] name = "prompt-toolkit" -version = "3.0.39" +version = "3.0.43" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, - {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, ] [package.dependencies] @@ -1496,27 +1503,27 @@ wcwidth = "*" [[package]] name = "psutil" -version = "5.9.6" +version = "5.9.7" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "psutil-5.9.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d"}, - {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c"}, - {file = "psutil-5.9.6-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28"}, - {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017"}, - {file = "psutil-5.9.6-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c"}, - {file = "psutil-5.9.6-cp27-none-win32.whl", hash = "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9"}, - {file = "psutil-5.9.6-cp27-none-win_amd64.whl", hash = "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac"}, - {file = "psutil-5.9.6-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a"}, - {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c"}, - {file = "psutil-5.9.6-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4"}, - {file = "psutil-5.9.6-cp36-cp36m-win32.whl", hash = "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602"}, - {file = "psutil-5.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa"}, - {file = "psutil-5.9.6-cp37-abi3-win32.whl", hash = "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c"}, - {file = "psutil-5.9.6-cp37-abi3-win_amd64.whl", hash = "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a"}, - {file = "psutil-5.9.6-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57"}, - {file = "psutil-5.9.6.tar.gz", hash = "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a"}, + {file = "psutil-5.9.7-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0bd41bf2d1463dfa535942b2a8f0e958acf6607ac0be52265ab31f7923bcd5e6"}, + {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5794944462509e49d4d458f4dbfb92c47539e7d8d15c796f141f474010084056"}, + {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:fe361f743cb3389b8efda21980d93eb55c1f1e3898269bc9a2a1d0bb7b1f6508"}, + {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:e469990e28f1ad738f65a42dcfc17adaed9d0f325d55047593cb9033a0ab63df"}, + {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:3c4747a3e2ead1589e647e64aad601981f01b68f9398ddf94d01e3dc0d1e57c7"}, + {file = "psutil-5.9.7-cp27-none-win32.whl", hash = "sha256:1d4bc4a0148fdd7fd8f38e0498639ae128e64538faa507df25a20f8f7fb2341c"}, + {file = "psutil-5.9.7-cp27-none-win_amd64.whl", hash = "sha256:4c03362e280d06bbbfcd52f29acd79c733e0af33d707c54255d21029b8b32ba6"}, + {file = "psutil-5.9.7-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ea36cc62e69a13ec52b2f625c27527f6e4479bca2b340b7a452af55b34fcbe2e"}, + {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1132704b876e58d277168cd729d64750633d5ff0183acf5b3c986b8466cd0284"}, + {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8b7f07948f1304497ce4f4684881250cd859b16d06a1dc4d7941eeb6233bfe"}, + {file = "psutil-5.9.7-cp36-cp36m-win32.whl", hash = "sha256:b27f8fdb190c8c03914f908a4555159327d7481dac2f01008d483137ef3311a9"}, + {file = "psutil-5.9.7-cp36-cp36m-win_amd64.whl", hash = "sha256:44969859757f4d8f2a9bd5b76eba8c3099a2c8cf3992ff62144061e39ba8568e"}, + {file = "psutil-5.9.7-cp37-abi3-win32.whl", hash = "sha256:c727ca5a9b2dd5193b8644b9f0c883d54f1248310023b5ad3e92036c5e2ada68"}, + {file = "psutil-5.9.7-cp37-abi3-win_amd64.whl", hash = "sha256:f37f87e4d73b79e6c5e749440c3113b81d1ee7d26f21c19c47371ddea834f414"}, + {file = "psutil-5.9.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:032f4f2c909818c86cea4fe2cc407f1c0f0cde8e6c6d702b28b8ce0c0d143340"}, + {file = "psutil-5.9.7.tar.gz", hash = "sha256:3f02134e82cfb5d089fddf20bb2e03fd5cd52395321d1c8458a9e58500ff417c"}, ] [package.extras] @@ -1605,65 +1612,149 @@ files = [ [[package]] name = "pydantic" -version = "1.10.13" -description = "Data validation and settings management using python type hints" +version = "2.5.3" +description = "Data validation using Python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, - {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, - {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, - {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, - {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, - {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, - {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, - {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, - {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, - {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, + {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, + {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.14.6" +typing-extensions = ">=4.6.1" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.14.6" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"}, + {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"}, + {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"}, + {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"}, + {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"}, + {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"}, + {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, + {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, + {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, + {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, + {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"}, + {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"}, + {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"}, + {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"}, + {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"}, + {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydata-sphinx-theme" -version = "0.13.3" +version = "0.14.4" description = "Bootstrap-based Sphinx theme from the PyData community" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydata_sphinx_theme-0.13.3-py3-none-any.whl", hash = "sha256:bf41ca6c1c6216e929e28834e404bfc90e080b51915bbe7563b5e6fda70354f0"}, - {file = "pydata_sphinx_theme-0.13.3.tar.gz", hash = "sha256:827f16b065c4fd97e847c11c108bf632b7f2ff53a3bca3272f63f3f3ff782ecc"}, + {file = "pydata_sphinx_theme-0.14.4-py3-none-any.whl", hash = "sha256:ac15201f4c2e2e7042b0cad8b30251433c1f92be762ddcefdb4ae68811d918d9"}, + {file = "pydata_sphinx_theme-0.14.4.tar.gz", hash = "sha256:f5d7a2cb7a98e35b9b49d3b02cec373ad28958c2ed5c9b1ffe6aff6c56e9de5b"}, ] [package.dependencies] @@ -1673,13 +1764,14 @@ beautifulsoup4 = "*" docutils = "!=0.17.0" packaging = "*" pygments = ">=2.7" -sphinx = ">=4.2" +sphinx = ">=5.0" typing-extensions = "*" [package.extras] +a11y = ["pytest-playwright"] dev = ["nox", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml"] -doc = ["ablog (>=0.11.0rc2)", "colorama", "ipyleaflet", "jupyter_sphinx", "linkify-it-py", "matplotlib", "myst-nb", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube", "sphinxext-rediraffe", "xarray"] -test = ["codecov", "pytest", "pytest-cov", "pytest-regressions"] +doc = ["ablog (>=0.11.0rc2)", "colorama", "ipykernel", "ipyleaflet", "jupyter_sphinx", "jupyterlite-sphinx", "linkify-it-py", "matplotlib", "myst-parser", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-autoapi (>=3.0.0)", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube (<1.4)", "sphinxext-rediraffe", "xarray"] +test = ["pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "pyflakes" @@ -1694,17 +1786,18 @@ files = [ [[package]] name = "pygments" -version = "2.16.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pytest" @@ -1844,104 +1937,104 @@ files = [ [[package]] name = "pyzmq" -version = "25.1.1" +version = "25.1.2" description = "Python bindings for 0MQ" optional = false python-versions = ">=3.6" files = [ - {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:381469297409c5adf9a0e884c5eb5186ed33137badcbbb0560b86e910a2f1e76"}, - {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:955215ed0604dac5b01907424dfa28b40f2b2292d6493445dd34d0dfa72586a8"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:985bbb1316192b98f32e25e7b9958088431d853ac63aca1d2c236f40afb17c83"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:afea96f64efa98df4da6958bae37f1cbea7932c35878b185e5982821bc883369"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76705c9325d72a81155bb6ab48d4312e0032bf045fb0754889133200f7a0d849"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:77a41c26205d2353a4c94d02be51d6cbdf63c06fbc1295ea57dad7e2d3381b71"}, - {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:12720a53e61c3b99d87262294e2b375c915fea93c31fc2336898c26d7aed34cd"}, - {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:57459b68e5cd85b0be8184382cefd91959cafe79ae019e6b1ae6e2ba8a12cda7"}, - {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:292fe3fc5ad4a75bc8df0dfaee7d0babe8b1f4ceb596437213821f761b4589f9"}, - {file = "pyzmq-25.1.1-cp310-cp310-win32.whl", hash = "sha256:35b5ab8c28978fbbb86ea54958cd89f5176ce747c1fb3d87356cf698048a7790"}, - {file = "pyzmq-25.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:11baebdd5fc5b475d484195e49bae2dc64b94a5208f7c89954e9e354fc609d8f"}, - {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:d20a0ddb3e989e8807d83225a27e5c2eb2260eaa851532086e9e0fa0d5287d83"}, - {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e1c1be77bc5fb77d923850f82e55a928f8638f64a61f00ff18a67c7404faf008"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d89528b4943d27029a2818f847c10c2cecc79fa9590f3cb1860459a5be7933eb"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90f26dc6d5f241ba358bef79be9ce06de58d477ca8485e3291675436d3827cf8"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2b92812bd214018e50b6380ea3ac0c8bb01ac07fcc14c5f86a5bb25e74026e9"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:2f957ce63d13c28730f7fd6b72333814221c84ca2421298f66e5143f81c9f91f"}, - {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:047a640f5c9c6ade7b1cc6680a0e28c9dd5a0825135acbd3569cc96ea00b2505"}, - {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7f7e58effd14b641c5e4dec8c7dab02fb67a13df90329e61c869b9cc607ef752"}, - {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c2910967e6ab16bf6fbeb1f771c89a7050947221ae12a5b0b60f3bca2ee19bca"}, - {file = "pyzmq-25.1.1-cp311-cp311-win32.whl", hash = "sha256:76c1c8efb3ca3a1818b837aea423ff8a07bbf7aafe9f2f6582b61a0458b1a329"}, - {file = "pyzmq-25.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:44e58a0554b21fc662f2712814a746635ed668d0fbc98b7cb9d74cb798d202e6"}, - {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:e1ffa1c924e8c72778b9ccd386a7067cddf626884fd8277f503c48bb5f51c762"}, - {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1af379b33ef33757224da93e9da62e6471cf4a66d10078cf32bae8127d3d0d4a"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cff084c6933680d1f8b2f3b4ff5bbb88538a4aac00d199ac13f49d0698727ecb"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2400a94f7dd9cb20cd012951a0cbf8249e3d554c63a9c0cdfd5cbb6c01d2dec"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d81f1ddae3858b8299d1da72dd7d19dd36aab654c19671aa8a7e7fb02f6638a"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:255ca2b219f9e5a3a9ef3081512e1358bd4760ce77828e1028b818ff5610b87b"}, - {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a882ac0a351288dd18ecae3326b8a49d10c61a68b01419f3a0b9a306190baf69"}, - {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:724c292bb26365659fc434e9567b3f1adbdb5e8d640c936ed901f49e03e5d32e"}, - {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ca1ed0bb2d850aa8471387882247c68f1e62a4af0ce9c8a1dbe0d2bf69e41fb"}, - {file = "pyzmq-25.1.1-cp312-cp312-win32.whl", hash = "sha256:b3451108ab861040754fa5208bca4a5496c65875710f76789a9ad27c801a0075"}, - {file = "pyzmq-25.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:eadbefd5e92ef8a345f0525b5cfd01cf4e4cc651a2cffb8f23c0dd184975d787"}, - {file = "pyzmq-25.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:db0b2af416ba735c6304c47f75d348f498b92952f5e3e8bff449336d2728795d"}, - {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c133e93b405eb0d36fa430c94185bdd13c36204a8635470cccc200723c13bb"}, - {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:273bc3959bcbff3f48606b28229b4721716598d76b5aaea2b4a9d0ab454ec062"}, - {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cbc8df5c6a88ba5ae385d8930da02201165408dde8d8322072e3e5ddd4f68e22"}, - {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:18d43df3f2302d836f2a56f17e5663e398416e9dd74b205b179065e61f1a6edf"}, - {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:73461eed88a88c866656e08f89299720a38cb4e9d34ae6bf5df6f71102570f2e"}, - {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:34c850ce7976d19ebe7b9d4b9bb8c9dfc7aac336c0958e2651b88cbd46682123"}, - {file = "pyzmq-25.1.1-cp36-cp36m-win32.whl", hash = "sha256:d2045d6d9439a0078f2a34b57c7b18c4a6aef0bee37f22e4ec9f32456c852c71"}, - {file = "pyzmq-25.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:458dea649f2f02a0b244ae6aef8dc29325a2810aa26b07af8374dc2a9faf57e3"}, - {file = "pyzmq-25.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7cff25c5b315e63b07a36f0c2bab32c58eafbe57d0dce61b614ef4c76058c115"}, - {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1579413ae492b05de5a6174574f8c44c2b9b122a42015c5292afa4be2507f28"}, - {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3d0a409d3b28607cc427aa5c30a6f1e4452cc44e311f843e05edb28ab5e36da0"}, - {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21eb4e609a154a57c520e3d5bfa0d97e49b6872ea057b7c85257b11e78068222"}, - {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:034239843541ef7a1aee0c7b2cb7f6aafffb005ede965ae9cbd49d5ff4ff73cf"}, - {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f8115e303280ba09f3898194791a153862cbf9eef722ad8f7f741987ee2a97c7"}, - {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1a5d26fe8f32f137e784f768143728438877d69a586ddeaad898558dc971a5ae"}, - {file = "pyzmq-25.1.1-cp37-cp37m-win32.whl", hash = "sha256:f32260e556a983bc5c7ed588d04c942c9a8f9c2e99213fec11a031e316874c7e"}, - {file = "pyzmq-25.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:abf34e43c531bbb510ae7e8f5b2b1f2a8ab93219510e2b287a944432fad135f3"}, - {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:87e34f31ca8f168c56d6fbf99692cc8d3b445abb5bfd08c229ae992d7547a92a"}, - {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c9c6c9b2c2f80747a98f34ef491c4d7b1a8d4853937bb1492774992a120f475d"}, - {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5619f3f5a4db5dbb572b095ea3cb5cc035335159d9da950830c9c4db2fbb6995"}, - {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a34d2395073ef862b4032343cf0c32a712f3ab49d7ec4f42c9661e0294d106f"}, - {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f0e6b78220aba09815cd1f3a32b9c7cb3e02cb846d1cfc526b6595f6046618"}, - {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3669cf8ee3520c2f13b2e0351c41fea919852b220988d2049249db10046a7afb"}, - {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2d163a18819277e49911f7461567bda923461c50b19d169a062536fffe7cd9d2"}, - {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:df27ffddff4190667d40de7beba4a950b5ce78fe28a7dcc41d6f8a700a80a3c0"}, - {file = "pyzmq-25.1.1-cp38-cp38-win32.whl", hash = "sha256:a382372898a07479bd34bda781008e4a954ed8750f17891e794521c3e21c2e1c"}, - {file = "pyzmq-25.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:52533489f28d62eb1258a965f2aba28a82aa747202c8fa5a1c7a43b5db0e85c1"}, - {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:03b3f49b57264909aacd0741892f2aecf2f51fb053e7d8ac6767f6c700832f45"}, - {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:330f9e188d0d89080cde66dc7470f57d1926ff2fb5576227f14d5be7ab30b9fa"}, - {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2ca57a5be0389f2a65e6d3bb2962a971688cbdd30b4c0bd188c99e39c234f414"}, - {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d457aed310f2670f59cc5b57dcfced452aeeed77f9da2b9763616bd57e4dbaae"}, - {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c56d748ea50215abef7030c72b60dd723ed5b5c7e65e7bc2504e77843631c1a6"}, - {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8f03d3f0d01cb5a018debeb412441996a517b11c5c17ab2001aa0597c6d6882c"}, - {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:820c4a08195a681252f46926de10e29b6bbf3e17b30037bd4250d72dd3ddaab8"}, - {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17ef5f01d25b67ca8f98120d5fa1d21efe9611604e8eb03a5147360f517dd1e2"}, - {file = "pyzmq-25.1.1-cp39-cp39-win32.whl", hash = "sha256:04ccbed567171579ec2cebb9c8a3e30801723c575601f9a990ab25bcac6b51e2"}, - {file = "pyzmq-25.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:e61f091c3ba0c3578411ef505992d356a812fb200643eab27f4f70eed34a29ef"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ade6d25bb29c4555d718ac6d1443a7386595528c33d6b133b258f65f963bb0f6"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0c95ddd4f6e9fca4e9e3afaa4f9df8552f0ba5d1004e89ef0a68e1f1f9807c7"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48e466162a24daf86f6b5ca72444d2bf39a5e58da5f96370078be67c67adc978"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abc719161780932c4e11aaebb203be3d6acc6b38d2f26c0f523b5b59d2fc1996"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ccf825981640b8c34ae54231b7ed00271822ea1c6d8ba1090ebd4943759abf5"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c2f20ce161ebdb0091a10c9ca0372e023ce24980d0e1f810f519da6f79c60800"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:deee9ca4727f53464daf089536e68b13e6104e84a37820a88b0a057b97bba2d2"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aa8d6cdc8b8aa19ceb319aaa2b660cdaccc533ec477eeb1309e2a291eaacc43a"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019e59ef5c5256a2c7378f2fb8560fc2a9ff1d315755204295b2eab96b254d0a"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b9af3757495c1ee3b5c4e945c1df7be95562277c6e5bccc20a39aec50f826cd0"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:548d6482dc8aadbe7e79d1b5806585c8120bafa1ef841167bc9090522b610fa6"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:057e824b2aae50accc0f9a0570998adc021b372478a921506fddd6c02e60308e"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2243700cc5548cff20963f0ca92d3e5e436394375ab8a354bbea2b12911b20b0"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79986f3b4af059777111409ee517da24a529bdbd46da578b33f25580adcff728"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:11d58723d44d6ed4dd677c5615b2ffb19d5c426636345567d6af82be4dff8a55"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:49d238cf4b69652257db66d0c623cd3e09b5d2e9576b56bc067a396133a00d4a"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fedbdc753827cf014c01dbbee9c3be17e5a208dcd1bf8641ce2cd29580d1f0d4"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc16ac425cc927d0a57d242589f87ee093884ea4804c05a13834d07c20db203c"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11c1d2aed9079c6b0c9550a7257a836b4a637feb334904610f06d70eb44c56d2"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e8a701123029cc240cea61dd2d16ad57cab4691804143ce80ecd9286b464d180"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:61706a6b6c24bdece85ff177fec393545a3191eeda35b07aaa1458a027ad1304"}, - {file = "pyzmq-25.1.1.tar.gz", hash = "sha256:259c22485b71abacdfa8bf79720cd7bcf4b9d128b30ea554f01ae71fdbfdaa23"}, + {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4"}, + {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0"}, + {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e"}, + {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872"}, + {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d"}, + {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75"}, + {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6"}, + {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979"}, + {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08"}, + {file = "pyzmq-25.1.2-cp310-cp310-win32.whl", hash = "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886"}, + {file = "pyzmq-25.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6"}, + {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c"}, + {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1"}, + {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348"}, + {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642"}, + {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840"}, + {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d"}, + {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b"}, + {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b"}, + {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3"}, + {file = "pyzmq-25.1.2-cp311-cp311-win32.whl", hash = "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097"}, + {file = "pyzmq-25.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9"}, + {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a"}, + {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e"}, + {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27"}, + {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30"}, + {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee"}, + {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537"}, + {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181"}, + {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe"}, + {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737"}, + {file = "pyzmq-25.1.2-cp312-cp312-win32.whl", hash = "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d"}, + {file = "pyzmq-25.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7"}, + {file = "pyzmq-25.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7b6d09a8962a91151f0976008eb7b29b433a560fde056ec7a3db9ec8f1075438"}, + {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967668420f36878a3c9ecb5ab33c9d0ff8d054f9c0233d995a6d25b0e95e1b6b"}, + {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5edac3f57c7ddaacdb4d40f6ef2f9e299471fc38d112f4bc6d60ab9365445fb0"}, + {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0dabfb10ef897f3b7e101cacba1437bd3a5032ee667b7ead32bbcdd1a8422fe7"}, + {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2c6441e0398c2baacfe5ba30c937d274cfc2dc5b55e82e3749e333aabffde561"}, + {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:16b726c1f6c2e7625706549f9dbe9b06004dfbec30dbed4bf50cbdfc73e5b32a"}, + {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a86c2dd76ef71a773e70551a07318b8e52379f58dafa7ae1e0a4be78efd1ff16"}, + {file = "pyzmq-25.1.2-cp36-cp36m-win32.whl", hash = "sha256:359f7f74b5d3c65dae137f33eb2bcfa7ad9ebefd1cab85c935f063f1dbb245cc"}, + {file = "pyzmq-25.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:55875492f820d0eb3417b51d96fea549cde77893ae3790fd25491c5754ea2f68"}, + {file = "pyzmq-25.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8c8a419dfb02e91b453615c69568442e897aaf77561ee0064d789705ff37a92"}, + {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8807c87fa893527ae8a524c15fc505d9950d5e856f03dae5921b5e9aa3b8783b"}, + {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5e319ed7d6b8f5fad9b76daa0a68497bc6f129858ad956331a5835785761e003"}, + {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3c53687dde4d9d473c587ae80cc328e5b102b517447456184b485587ebd18b62"}, + {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9add2e5b33d2cd765ad96d5eb734a5e795a0755f7fc49aa04f76d7ddda73fd70"}, + {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e690145a8c0c273c28d3b89d6fb32c45e0d9605b2293c10e650265bf5c11cfec"}, + {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:00a06faa7165634f0cac1abb27e54d7a0b3b44eb9994530b8ec73cf52e15353b"}, + {file = "pyzmq-25.1.2-cp37-cp37m-win32.whl", hash = "sha256:0f97bc2f1f13cb16905a5f3e1fbdf100e712d841482b2237484360f8bc4cb3d7"}, + {file = "pyzmq-25.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6cc0020b74b2e410287e5942e1e10886ff81ac77789eb20bec13f7ae681f0fdd"}, + {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:bef02cfcbded83473bdd86dd8d3729cd82b2e569b75844fb4ea08fee3c26ae41"}, + {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e10a4b5a4b1192d74853cc71a5e9fd022594573926c2a3a4802020360aa719d8"}, + {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8c5f80e578427d4695adac6fdf4370c14a2feafdc8cb35549c219b90652536ae"}, + {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5dde6751e857910c1339890f3524de74007958557593b9e7e8c5f01cd919f8a7"}, + {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea1608dd169da230a0ad602d5b1ebd39807ac96cae1845c3ceed39af08a5c6df"}, + {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0f513130c4c361201da9bc69df25a086487250e16b5571ead521b31ff6b02220"}, + {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:019744b99da30330798bb37df33549d59d380c78e516e3bab9c9b84f87a9592f"}, + {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2e2713ef44be5d52dd8b8e2023d706bf66cb22072e97fc71b168e01d25192755"}, + {file = "pyzmq-25.1.2-cp38-cp38-win32.whl", hash = "sha256:07cd61a20a535524906595e09344505a9bd46f1da7a07e504b315d41cd42eb07"}, + {file = "pyzmq-25.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb7e49a17fb8c77d3119d41a4523e432eb0c6932187c37deb6fbb00cc3028088"}, + {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:94504ff66f278ab4b7e03e4cba7e7e400cb73bfa9d3d71f58d8972a8dc67e7a6"}, + {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6dd0d50bbf9dca1d0bdea219ae6b40f713a3fb477c06ca3714f208fd69e16fd8"}, + {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:004ff469d21e86f0ef0369717351073e0e577428e514c47c8480770d5e24a565"}, + {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c0b5ca88a8928147b7b1e2dfa09f3b6c256bc1135a1338536cbc9ea13d3b7add"}, + {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9a79f1d2495b167119d02be7448bfba57fad2a4207c4f68abc0bab4b92925b"}, + {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:518efd91c3d8ac9f9b4f7dd0e2b7b8bf1a4fe82a308009016b07eaa48681af82"}, + {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1ec23bd7b3a893ae676d0e54ad47d18064e6c5ae1fadc2f195143fb27373f7f6"}, + {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db36c27baed588a5a8346b971477b718fdc66cf5b80cbfbd914b4d6d355e44e2"}, + {file = "pyzmq-25.1.2-cp39-cp39-win32.whl", hash = "sha256:39b1067f13aba39d794a24761e385e2eddc26295826530a8c7b6c6c341584289"}, + {file = "pyzmq-25.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:8e9f3fabc445d0ce320ea2c59a75fe3ea591fdbdeebec5db6de530dd4b09412e"}, + {file = "pyzmq-25.1.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05"}, + {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8"}, + {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e"}, + {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4"}, + {file = "pyzmq-25.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d"}, + {file = "pyzmq-25.1.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:df0c7a16ebb94452d2909b9a7b3337940e9a87a824c4fc1c7c36bb4404cb0cde"}, + {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:45999e7f7ed5c390f2e87ece7f6c56bf979fb213550229e711e45ecc7d42ccb8"}, + {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ac170e9e048b40c605358667aca3d94e98f604a18c44bdb4c102e67070f3ac9b"}, + {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b604734bec94f05f81b360a272fc824334267426ae9905ff32dc2be433ab96"}, + {file = "pyzmq-25.1.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a793ac733e3d895d96f865f1806f160696422554e46d30105807fdc9841b9f7d"}, + {file = "pyzmq-25.1.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0806175f2ae5ad4b835ecd87f5f85583316b69f17e97786f7443baaf54b9bb98"}, + {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ef12e259e7bc317c7597d4f6ef59b97b913e162d83b421dd0db3d6410f17a244"}, + {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea253b368eb41116011add00f8d5726762320b1bda892f744c91997b65754d73"}, + {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b9b1f2ad6498445a941d9a4fee096d387fee436e45cc660e72e768d3d8ee611"}, + {file = "pyzmq-25.1.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8b14c75979ce932c53b79976a395cb2a8cd3aaf14aef75e8c2cb55a330b9b49d"}, + {file = "pyzmq-25.1.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:889370d5174a741a62566c003ee8ddba4b04c3f09a97b8000092b7ca83ec9c49"}, + {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a18fff090441a40ffda8a7f4f18f03dc56ae73f148f1832e109f9bffa85df15"}, + {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99a6b36f95c98839ad98f8c553d8507644c880cf1e0a57fe5e3a3f3969040882"}, + {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4345c9a27f4310afbb9c01750e9461ff33d6fb74cd2456b107525bbeebcb5be3"}, + {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3516e0b6224cf6e43e341d56da15fd33bdc37fa0c06af4f029f7d7dfceceabbc"}, + {file = "pyzmq-25.1.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:146b9b1f29ead41255387fb07be56dc29639262c0f7344f570eecdcd8d683314"}, + {file = "pyzmq-25.1.2.tar.gz", hash = "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226"}, ] [package.dependencies] @@ -1949,13 +2042,13 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "referencing" -version = "0.30.2" +version = "0.32.0" description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, - {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, + {file = "referencing-0.32.0-py3-none-any.whl", hash = "sha256:bdcd3efb936f82ff86f993093f6da7435c7de69a3b3a5a06678a6050184bee99"}, + {file = "referencing-0.32.0.tar.gz", hash = "sha256:689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161"}, ] [package.dependencies] @@ -1985,151 +2078,151 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rpds-py" -version = "0.10.6" +version = "0.16.2" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.10.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:6bdc11f9623870d75692cc33c59804b5a18d7b8a4b79ef0b00b773a27397d1f6"}, - {file = "rpds_py-0.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26857f0f44f0e791f4a266595a7a09d21f6b589580ee0585f330aaccccb836e3"}, - {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7f5e15c953ace2e8dde9824bdab4bec50adb91a5663df08d7d994240ae6fa31"}, - {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61fa268da6e2e1cd350739bb61011121fa550aa2545762e3dc02ea177ee4de35"}, - {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c48f3fbc3e92c7dd6681a258d22f23adc2eb183c8cb1557d2fcc5a024e80b094"}, - {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0503c5b681566e8b722fe8c4c47cce5c7a51f6935d5c7012c4aefe952a35eed"}, - {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:734c41f9f57cc28658d98270d3436dba65bed0cfc730d115b290e970150c540d"}, - {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a5d7ed104d158c0042a6a73799cf0eb576dfd5fc1ace9c47996e52320c37cb7c"}, - {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e3df0bc35e746cce42579826b89579d13fd27c3d5319a6afca9893a9b784ff1b"}, - {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:73e0a78a9b843b8c2128028864901f55190401ba38aae685350cf69b98d9f7c9"}, - {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ed505ec6305abd2c2c9586a7b04fbd4baf42d4d684a9c12ec6110deefe2a063"}, - {file = "rpds_py-0.10.6-cp310-none-win32.whl", hash = "sha256:d97dd44683802000277bbf142fd9f6b271746b4846d0acaf0cefa6b2eaf2a7ad"}, - {file = "rpds_py-0.10.6-cp310-none-win_amd64.whl", hash = "sha256:b455492cab07107bfe8711e20cd920cc96003e0da3c1f91297235b1603d2aca7"}, - {file = "rpds_py-0.10.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e8cdd52744f680346ff8c1ecdad5f4d11117e1724d4f4e1874f3a67598821069"}, - {file = "rpds_py-0.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66414dafe4326bca200e165c2e789976cab2587ec71beb80f59f4796b786a238"}, - {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc435d059f926fdc5b05822b1be4ff2a3a040f3ae0a7bbbe672babb468944722"}, - {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8e7f2219cb72474571974d29a191714d822e58be1eb171f229732bc6fdedf0ac"}, - {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3953c6926a63f8ea5514644b7afb42659b505ece4183fdaaa8f61d978754349e"}, - {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2bb2e4826be25e72013916eecd3d30f66fd076110de09f0e750163b416500721"}, - {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bf347b495b197992efc81a7408e9a83b931b2f056728529956a4d0858608b80"}, - {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:102eac53bb0bf0f9a275b438e6cf6904904908562a1463a6fc3323cf47d7a532"}, - {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40f93086eef235623aa14dbddef1b9fb4b22b99454cb39a8d2e04c994fb9868c"}, - {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e22260a4741a0e7a206e175232867b48a16e0401ef5bce3c67ca5b9705879066"}, - {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4e56860a5af16a0fcfa070a0a20c42fbb2012eed1eb5ceeddcc7f8079214281"}, - {file = "rpds_py-0.10.6-cp311-none-win32.whl", hash = "sha256:0774a46b38e70fdde0c6ded8d6d73115a7c39d7839a164cc833f170bbf539116"}, - {file = "rpds_py-0.10.6-cp311-none-win_amd64.whl", hash = "sha256:4a5ee600477b918ab345209eddafde9f91c0acd931f3776369585a1c55b04c57"}, - {file = "rpds_py-0.10.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:5ee97c683eaface61d38ec9a489e353d36444cdebb128a27fe486a291647aff6"}, - {file = "rpds_py-0.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0713631d6e2d6c316c2f7b9320a34f44abb644fc487b77161d1724d883662e31"}, - {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5a53f5998b4bbff1cb2e967e66ab2addc67326a274567697379dd1e326bded7"}, - {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a555ae3d2e61118a9d3e549737bb4a56ff0cec88a22bd1dfcad5b4e04759175"}, - {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:945eb4b6bb8144909b203a88a35e0a03d22b57aefb06c9b26c6e16d72e5eb0f0"}, - {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:52c215eb46307c25f9fd2771cac8135d14b11a92ae48d17968eda5aa9aaf5071"}, - {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1b3cd23d905589cb205710b3988fc8f46d4a198cf12862887b09d7aaa6bf9b9"}, - {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64ccc28683666672d7c166ed465c09cee36e306c156e787acef3c0c62f90da5a"}, - {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:516a611a2de12fbea70c78271e558f725c660ce38e0006f75139ba337d56b1f6"}, - {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9ff93d3aedef11f9c4540cf347f8bb135dd9323a2fc705633d83210d464c579d"}, - {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d858532212f0650be12b6042ff4378dc2efbb7792a286bee4489eaa7ba010586"}, - {file = "rpds_py-0.10.6-cp312-none-win32.whl", hash = "sha256:3c4eff26eddac49d52697a98ea01b0246e44ca82ab09354e94aae8823e8bda02"}, - {file = "rpds_py-0.10.6-cp312-none-win_amd64.whl", hash = "sha256:150eec465dbc9cbca943c8e557a21afdcf9bab8aaabf386c44b794c2f94143d2"}, - {file = "rpds_py-0.10.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:cf693eb4a08eccc1a1b636e4392322582db2a47470d52e824b25eca7a3977b53"}, - {file = "rpds_py-0.10.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4134aa2342f9b2ab6c33d5c172e40f9ef802c61bb9ca30d21782f6e035ed0043"}, - {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e782379c2028a3611285a795b89b99a52722946d19fc06f002f8b53e3ea26ea9"}, - {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f6da6d842195fddc1cd34c3da8a40f6e99e4a113918faa5e60bf132f917c247"}, - {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a9fe992887ac68256c930a2011255bae0bf5ec837475bc6f7edd7c8dfa254e"}, - {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b788276a3c114e9f51e257f2a6f544c32c02dab4aa7a5816b96444e3f9ffc336"}, - {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa1afc70a02645809c744eefb7d6ee8fef7e2fad170ffdeacca267fd2674f13"}, - {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bddd4f91eede9ca5275e70479ed3656e76c8cdaaa1b354e544cbcf94c6fc8ac4"}, - {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:775049dfa63fb58293990fc59473e659fcafd953bba1d00fc5f0631a8fd61977"}, - {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c6c45a2d2b68c51fe3d9352733fe048291e483376c94f7723458cfd7b473136b"}, - {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0699ab6b8c98df998c3eacf51a3b25864ca93dab157abe358af46dc95ecd9801"}, - {file = "rpds_py-0.10.6-cp38-none-win32.whl", hash = "sha256:ebdab79f42c5961682654b851f3f0fc68e6cc7cd8727c2ac4ffff955154123c1"}, - {file = "rpds_py-0.10.6-cp38-none-win_amd64.whl", hash = "sha256:24656dc36f866c33856baa3ab309da0b6a60f37d25d14be916bd3e79d9f3afcf"}, - {file = "rpds_py-0.10.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:0898173249141ee99ffcd45e3829abe7bcee47d941af7434ccbf97717df020e5"}, - {file = "rpds_py-0.10.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9e9184fa6c52a74a5521e3e87badbf9692549c0fcced47443585876fcc47e469"}, - {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5752b761902cd15073a527b51de76bbae63d938dc7c5c4ad1e7d8df10e765138"}, - {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99a57006b4ec39dbfb3ed67e5b27192792ffb0553206a107e4aadb39c5004cd5"}, - {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09586f51a215d17efdb3a5f090d7cbf1633b7f3708f60a044757a5d48a83b393"}, - {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e225a6a14ecf44499aadea165299092ab0cba918bb9ccd9304eab1138844490b"}, - {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2039f8d545f20c4e52713eea51a275e62153ee96c8035a32b2abb772b6fc9e5"}, - {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:34ad87a831940521d462ac11f1774edf867c34172010f5390b2f06b85dcc6014"}, - {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dcdc88b6b01015da066da3fb76545e8bb9a6880a5ebf89e0f0b2e3ca557b3ab7"}, - {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:25860ed5c4e7f5e10c496ea78af46ae8d8468e0be745bd233bab9ca99bfd2647"}, - {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7854a207ef77319ec457c1eb79c361b48807d252d94348305db4f4b62f40f7f3"}, - {file = "rpds_py-0.10.6-cp39-none-win32.whl", hash = "sha256:e6fcc026a3f27c1282c7ed24b7fcac82cdd70a0e84cc848c0841a3ab1e3dea2d"}, - {file = "rpds_py-0.10.6-cp39-none-win_amd64.whl", hash = "sha256:e98c4c07ee4c4b3acf787e91b27688409d918212dfd34c872201273fdd5a0e18"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:68fe9199184c18d997d2e4293b34327c0009a78599ce703e15cd9a0f47349bba"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3339eca941568ed52d9ad0f1b8eb9fe0958fa245381747cecf2e9a78a5539c42"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a360cfd0881d36c6dc271992ce1eda65dba5e9368575663de993eeb4523d895f"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:031f76fc87644a234883b51145e43985aa2d0c19b063e91d44379cd2786144f8"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f36a9d751f86455dc5278517e8b65580eeee37d61606183897f122c9e51cef3"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:052a832078943d2b2627aea0d19381f607fe331cc0eb5df01991268253af8417"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:023574366002bf1bd751ebaf3e580aef4a468b3d3c216d2f3f7e16fdabd885ed"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:defa2c0c68734f4a82028c26bcc85e6b92cced99866af118cd6a89b734ad8e0d"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879fb24304ead6b62dbe5034e7b644b71def53c70e19363f3c3be2705c17a3b4"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:53c43e10d398e365da2d4cc0bcaf0854b79b4c50ee9689652cdc72948e86f487"}, - {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3777cc9dea0e6c464e4b24760664bd8831738cc582c1d8aacf1c3f546bef3f65"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:40578a6469e5d1df71b006936ce95804edb5df47b520c69cf5af264d462f2cbb"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:cf71343646756a072b85f228d35b1d7407da1669a3de3cf47f8bbafe0c8183a4"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10f32b53f424fc75ff7b713b2edb286fdbfc94bf16317890260a81c2c00385dc"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:81de24a1c51cfb32e1fbf018ab0bdbc79c04c035986526f76c33e3f9e0f3356c"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac17044876e64a8ea20ab132080ddc73b895b4abe9976e263b0e30ee5be7b9c2"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8a78bd4879bff82daef48c14d5d4057f6856149094848c3ed0ecaf49f5aec2"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78ca33811e1d95cac8c2e49cb86c0fb71f4d8409d8cbea0cb495b6dbddb30a55"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c63c3ef43f0b3fb00571cff6c3967cc261c0ebd14a0a134a12e83bdb8f49f21f"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:7fde6d0e00b2fd0dbbb40c0eeec463ef147819f23725eda58105ba9ca48744f4"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:79edd779cfc46b2e15b0830eecd8b4b93f1a96649bcb502453df471a54ce7977"}, - {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9164ec8010327ab9af931d7ccd12ab8d8b5dc2f4c6a16cbdd9d087861eaaefa1"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d29ddefeab1791e3c751e0189d5f4b3dbc0bbe033b06e9c333dca1f99e1d523e"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:30adb75ecd7c2a52f5e76af50644b3e0b5ba036321c390b8e7ec1bb2a16dd43c"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd609fafdcdde6e67a139898196698af37438b035b25ad63704fd9097d9a3482"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6eef672de005736a6efd565577101277db6057f65640a813de6c2707dc69f396"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cf4393c7b41abbf07c88eb83e8af5013606b1cdb7f6bc96b1b3536b53a574b8"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad857f42831e5b8d41a32437f88d86ead6c191455a3499c4b6d15e007936d4cf"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7360573f1e046cb3b0dceeb8864025aa78d98be4bb69f067ec1c40a9e2d9df"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d08f63561c8a695afec4975fae445245386d645e3e446e6f260e81663bfd2e38"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:f0f17f2ce0f3529177a5fff5525204fad7b43dd437d017dd0317f2746773443d"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:442626328600bde1d09dc3bb00434f5374948838ce75c41a52152615689f9403"}, - {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e9616f5bd2595f7f4a04b67039d890348ab826e943a9bfdbe4938d0eba606971"}, - {file = "rpds_py-0.10.6.tar.gz", hash = "sha256:4ce5a708d65a8dbf3748d2474b580d606b1b9f91b5c6ab2a316e0b0cf7a4ba50"}, + {file = "rpds_py-0.16.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:509b617ac787cd1149600e731db9274ebbef094503ca25158e6f23edaba1ca8f"}, + {file = "rpds_py-0.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:413b9c17388bbd0d87a329d8e30c1a4c6e44e2bb25457f43725a8e6fe4161e9e"}, + {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2946b120718eba9af2b4dd103affc1164a87b9e9ebff8c3e4c05d7b7a7e274e2"}, + {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35ae5ece284cf36464eb160880018cf6088a9ac5ddc72292a6092b6ef3f4da53"}, + {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc6a7620ba7639a3db6213da61312cb4aa9ac0ca6e00dc1cbbdc21c2aa6eb57"}, + {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8cb6fe8ecdfffa0e711a75c931fb39f4ba382b4b3ccedeca43f18693864fe850"}, + {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dace7b26a13353e24613417ce2239491b40a6ad44e5776a18eaff7733488b44"}, + {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1bdbc5fcb04a7309074de6b67fa9bc4b418ab3fc435fec1f2779a0eced688d04"}, + {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f42e25c016927e2a6b1ce748112c3ab134261fc2ddc867e92d02006103e1b1b7"}, + {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:eab36eae3f3e8e24b05748ec9acc66286662f5d25c52ad70cadab544e034536b"}, + {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0474df4ade9a3b4af96c3d36eb81856cb9462e4c6657d4caecfd840d2a13f3c9"}, + {file = "rpds_py-0.16.2-cp310-none-win32.whl", hash = "sha256:84c5a4d1f9dd7e2d2c44097fb09fffe728629bad31eb56caf97719e55575aa82"}, + {file = "rpds_py-0.16.2-cp310-none-win_amd64.whl", hash = "sha256:2bd82db36cd70b3628c0c57d81d2438e8dd4b7b32a6a9f25f24ab0e657cb6c4e"}, + {file = "rpds_py-0.16.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:adc0c3d6fc6ae35fee3e4917628983f6ce630d513cbaad575b4517d47e81b4bb"}, + {file = "rpds_py-0.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ec23fcad480e77ede06cf4127a25fc440f7489922e17fc058f426b5256ee0edb"}, + {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07aab64e2808c3ebac2a44f67e9dc0543812b715126dfd6fe4264df527556cb6"}, + {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a4ebb8b20bd09c5ce7884c8f0388801100f5e75e7f733b1b6613c713371feefc"}, + {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3d7e2ea25d3517c6d7e5a1cc3702cffa6bd18d9ef8d08d9af6717fc1c700eed"}, + {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f28ac0e8e7242d140f99402a903a2c596ab71550272ae9247ad78f9a932b5698"}, + {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19f00f57fdd38db4bb5ad09f9ead1b535332dbf624200e9029a45f1f35527ebb"}, + {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3da5a4c56953bdbf6d04447c3410309616c54433146ccdb4a277b9cb499bc10e"}, + {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec2e1cf025b2c0f48ec17ff3e642661da7ee332d326f2e6619366ce8e221f018"}, + {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e0441fb4fdd39a230477b2ca9be90868af64425bfe7b122b57e61e45737a653b"}, + {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9f0350ef2fba5f34eb0c9000ea328e51b9572b403d2f7f3b19f24085f6f598e8"}, + {file = "rpds_py-0.16.2-cp311-none-win32.whl", hash = "sha256:5a80e2f83391ad0808b4646732af2a7b67550b98f0cae056cb3b40622a83dbb3"}, + {file = "rpds_py-0.16.2-cp311-none-win_amd64.whl", hash = "sha256:e04e56b4ca7a770593633556e8e9e46579d66ec2ada846b401252a2bdcf70a6d"}, + {file = "rpds_py-0.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5e6caa3809e50690bd92fa490f5c38caa86082c8c3315aa438bce43786d5e90d"}, + {file = "rpds_py-0.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e53b9b25cac9065328901713a7e9e3b12e4f57ef4280b370fbbf6fef2052eef"}, + {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af27423662f32d7501a00c5e7342f7dbd1e4a718aea7a239781357d15d437133"}, + {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43d4dd5fb16eb3825742bad8339d454054261ab59fed2fbac84e1d84d5aae7ba"}, + {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e061de3b745fe611e23cd7318aec2c8b0e4153939c25c9202a5811ca911fd733"}, + {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b811d182ad17ea294f2ec63c0621e7be92a1141e1012383461872cead87468f"}, + {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5552f328eaef1a75ff129d4d0c437bf44e43f9436d3996e8eab623ea0f5fcf73"}, + {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dcbe1f8dd179e4d69b70b1f1d9bb6fd1e7e1bdc9c9aad345cdeb332e29d40748"}, + {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8aad80645a011abae487d356e0ceb359f4938dfb6f7bcc410027ed7ae4f7bb8b"}, + {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6f5549d6ed1da9bfe3631ca9483ae906f21410be2445b73443fa9f017601c6f"}, + {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d452817e0d9c749c431a1121d56a777bd7099b720b3d1c820f1725cb40928f58"}, + {file = "rpds_py-0.16.2-cp312-none-win32.whl", hash = "sha256:888a97002e986eca10d8546e3c8b97da1d47ad8b69726dcfeb3e56348ebb28a3"}, + {file = "rpds_py-0.16.2-cp312-none-win_amd64.whl", hash = "sha256:d8dda2a806dfa4a9b795950c4f5cc56d6d6159f7d68080aedaff3bdc9b5032f5"}, + {file = "rpds_py-0.16.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:071980663c273bf3d388fe5c794c547e6f35ba3335477072c713a3176bf14a60"}, + {file = "rpds_py-0.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:726ac36e8a3bb8daef2fd482534cabc5e17334052447008405daca7ca04a3108"}, + {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9e557db6a177470316c82f023e5d571811c9a4422b5ea084c85da9aa3c035fc"}, + {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:90123853fc8b1747f80b0d354be3d122b4365a93e50fc3aacc9fb4c2488845d6"}, + {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a61f659665a39a4d17d699ab3593d7116d66e1e2e3f03ef3fb8f484e91908808"}, + {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc97f0640e91d7776530f06e6836c546c1c752a52de158720c4224c9e8053cad"}, + {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a54e99a2b9693a37ebf245937fd6e9228b4cbd64b9cc961e1f3391ec6c7391"}, + {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4b677d929cf1f6bac07ad76e0f2d5de367e6373351c01a9c0a39f6b21b4a8b"}, + {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5ef00873303d678aaf8b0627e111fd434925ca01c657dbb2641410f1cdaef261"}, + {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:349cb40897fd529ca15317c22c0eab67f5ac5178b5bd2c6adc86172045210acc"}, + {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2ddef620e70eaffebed5932ce754d539c0930f676aae6212f8e16cd9743dd365"}, + {file = "rpds_py-0.16.2-cp38-none-win32.whl", hash = "sha256:882ce6e25e585949c3d9f9abd29202367175e0aab3aba0c58c9abbb37d4982ff"}, + {file = "rpds_py-0.16.2-cp38-none-win_amd64.whl", hash = "sha256:f4bd4578e44f26997e9e56c96dedc5f1af43cc9d16c4daa29c771a00b2a26851"}, + {file = "rpds_py-0.16.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:69ac7ea9897ec201ce68b48582f3eb34a3f9924488a5432a93f177bf76a82a7e"}, + {file = "rpds_py-0.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a9880b4656efe36ccad41edc66789e191e5ee19a1ea8811e0aed6f69851a82f4"}, + {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee94cb58c0ba2c62ee108c2b7c9131b2c66a29e82746e8fa3aa1a1effbd3dcf1"}, + {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24f7a2eb3866a9e91f4599851e0c8d39878a470044875c49bd528d2b9b88361c"}, + {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca57468da2d9a660bcf8961637c85f2fbb2aa64d9bc3f9484e30c3f9f67b1dd7"}, + {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccd4e400309e1f34a5095bf9249d371f0fd60f8a3a5c4a791cad7b99ce1fd38d"}, + {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80443fe2f7b3ea3934c5d75fb0e04a5dbb4a8e943e5ff2de0dec059202b70a8b"}, + {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4d6a9f052e72d493efd92a77f861e45bab2f6be63e37fa8ecf0c6fd1a58fedb0"}, + {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:35953f4f2b3216421af86fd236b7c0c65935936a94ea83ddbd4904ba60757773"}, + {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:981d135c7cdaf6cd8eadae1c950de43b976de8f09d8e800feed307140d3d6d00"}, + {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d0dd7ed2f16df2e129496e7fbe59a34bc2d7fc8db443a606644d069eb69cbd45"}, + {file = "rpds_py-0.16.2-cp39-none-win32.whl", hash = "sha256:703d95c75a72e902544fda08e965885525e297578317989fd15a6ce58414b41d"}, + {file = "rpds_py-0.16.2-cp39-none-win_amd64.whl", hash = "sha256:e93ec1b300acf89730cf27975ef574396bc04edecc358e9bd116fb387a123239"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:44627b6ca7308680a70766454db5249105fa6344853af6762eaad4158a2feebe"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3f91df8e6dbb7360e176d1affd5fb0246d2b88d16aa5ebc7db94fd66b68b61da"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d904c5693e08bad240f16d79305edba78276be87061c872a4a15e2c301fa2c0"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:290a81cfbe4673285cdf140ec5cd1658ffbf63ab359f2b352ebe172e7cfa5bf0"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b634c5ec0103c5cbebc24ebac4872b045cccb9456fc59efdcf6fe39775365bd2"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a297a4d08cc67c7466c873c78039d87840fb50d05473db0ec1b7b03d179bf322"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2e75e17bd0bb66ee34a707da677e47c14ee51ccef78ed6a263a4cc965a072a1"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f1b9d9260e06ea017feb7172976ab261e011c1dc2f8883c7c274f6b2aabfe01a"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:162d7cd9cd311c1b0ff1c55a024b8f38bd8aad1876b648821da08adc40e95734"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:9b32f742ce5b57201305f19c2ef7a184b52f6f9ba6871cc042c2a61f0d6b49b8"}, + {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac08472f41ea77cd6a5dae36ae7d4ed3951d6602833af87532b556c1b4601d63"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:495a14b72bbe217f2695dcd9b5ab14d4f8066a00f5d209ed94f0aca307f85f6e"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d6b6937ae9eac6d6c0ca3c42774d89fa311f55adff3970fb364b34abde6ed3d"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a61226465bda9283686db8f17d02569a98e4b13c637be5a26d44aa1f1e361c2"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5cf6af100ffb5c195beec11ffaa8cf8523057f123afa2944e6571d54da84cdc9"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6df15846ee3fb2e6397fe25d7ca6624af9f89587f3f259d177b556fed6bebe2c"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1be2f033df1b8be8c3167ba3c29d5dca425592ee31e35eac52050623afba5772"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96f957d6ab25a78b9e7fc9749d754b98eac825a112b4e666525ce89afcbd9ed5"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:088396c7c70e59872f67462fcac3ecbded5233385797021976a09ebd55961dfe"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4c46ad6356e1561f2a54f08367d1d2e70a0a1bb2db2282d2c1972c1d38eafc3b"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:47713dc4fce213f5c74ca8a1f6a59b622fc1b90868deb8e8e4d993e421b4b39d"}, + {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:f811771019f063bbd0aa7bb72c8a934bc13ebacb4672d712fc1639cfd314cccc"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f19afcfc0dd0dca35694df441e9b0f95bc231b512f51bded3c3d8ca32153ec19"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a4b682c5775d6a3d21e314c10124599976809455ee67020e8e72df1769b87bc3"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c647ca87fc0ebe808a41de912e9a1bfef9acb85257e5d63691364ac16b81c1f0"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:302bd4983bbd47063e452c38be66153760112f6d3635c7eeefc094299fa400a9"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf721ede3eb7b829e4a9b8142bd55db0bdc82902720548a703f7e601ee13bdc3"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:358dafc89ce3894c7f486c615ba914609f38277ef67f566abc4c854d23b997fa"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cad0f59ee3dc35526039f4bc23642d52d5f6616b5f687d846bfc6d0d6d486db0"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cffa76b385dfe1e38527662a302b19ffb0e7f5cf7dd5e89186d2c94a22dd9d0c"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:83640a5d7cd3bff694747d50436b8b541b5b9b9782b0c8c1688931d6ee1a1f2d"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:ed99b4f7179d2111702020fd7d156e88acd533f5a7d3971353e568b6051d5c97"}, + {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4022b9dc620e14f30201a8a73898a873c8e910cb642bcd2f3411123bc527f6ac"}, + {file = "rpds_py-0.16.2.tar.gz", hash = "sha256:781ef8bfc091b19960fc0142a23aedadafa826bc32b433fdfe6fd7f964d7ef44"}, ] [[package]] name = "ruff" -version = "0.1.3" -description = "An extremely fast Python linter, written in Rust." +version = "0.1.9" +description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.3-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:b46d43d51f7061652eeadb426a9e3caa1e0002470229ab2fc19de8a7b0766901"}, - {file = "ruff-0.1.3-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:b8afeb9abd26b4029c72adc9921b8363374f4e7edb78385ffaa80278313a15f9"}, - {file = "ruff-0.1.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca3cf365bf32e9ba7e6db3f48a4d3e2c446cd19ebee04f05338bc3910114528b"}, - {file = "ruff-0.1.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4874c165f96c14a00590dcc727a04dca0cfd110334c24b039458c06cf78a672e"}, - {file = "ruff-0.1.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eec2dd31eed114e48ea42dbffc443e9b7221976554a504767ceaee3dd38edeb8"}, - {file = "ruff-0.1.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:dc3ec4edb3b73f21b4aa51337e16674c752f1d76a4a543af56d7d04e97769613"}, - {file = "ruff-0.1.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e3de9ed2e39160800281848ff4670e1698037ca039bda7b9274f849258d26ce"}, - {file = "ruff-0.1.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c595193881922cc0556a90f3af99b1c5681f0c552e7a2a189956141d8666fe8"}, - {file = "ruff-0.1.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f75e670d529aa2288cd00fc0e9b9287603d95e1536d7a7e0cafe00f75e0dd9d"}, - {file = "ruff-0.1.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:76dd49f6cd945d82d9d4a9a6622c54a994689d8d7b22fa1322983389b4892e20"}, - {file = "ruff-0.1.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:918b454bc4f8874a616f0d725590277c42949431ceb303950e87fef7a7d94cb3"}, - {file = "ruff-0.1.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8859605e729cd5e53aa38275568dbbdb4fe882d2ea2714c5453b678dca83784"}, - {file = "ruff-0.1.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0b6c55f5ef8d9dd05b230bb6ab80bc4381ecb60ae56db0330f660ea240cb0d4a"}, - {file = "ruff-0.1.3-py3-none-win32.whl", hash = "sha256:3e7afcbdcfbe3399c34e0f6370c30f6e529193c731b885316c5a09c9e4317eef"}, - {file = "ruff-0.1.3-py3-none-win_amd64.whl", hash = "sha256:7a18df6638cec4a5bd75350639b2bb2a2366e01222825562c7346674bdceb7ea"}, - {file = "ruff-0.1.3-py3-none-win_arm64.whl", hash = "sha256:12fd53696c83a194a2db7f9a46337ce06445fb9aa7d25ea6f293cf75b21aca9f"}, - {file = "ruff-0.1.3.tar.gz", hash = "sha256:3ba6145369a151401d5db79f0a47d50e470384d0d89d0d6f7fab0b589ad07c34"}, + {file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e6a212f436122ac73df851f0cf006e0c6612fe6f9c864ed17ebefce0eff6a5fd"}, + {file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:28d920e319783d5303333630dae46ecc80b7ba294aeffedf946a02ac0b7cc3db"}, + {file = "ruff-0.1.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:104aa9b5e12cb755d9dce698ab1b97726b83012487af415a4512fedd38b1459e"}, + {file = "ruff-0.1.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e63bf5a4a91971082a4768a0aba9383c12392d0d6f1e2be2248c1f9054a20da"}, + {file = "ruff-0.1.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d0738917c203246f3e275b37006faa3aa96c828b284ebfe3e99a8cb413c8c4b"}, + {file = "ruff-0.1.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69dac82d63a50df2ab0906d97a01549f814b16bc806deeac4f064ff95c47ddf5"}, + {file = "ruff-0.1.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2aec598fb65084e41a9c5d4b95726173768a62055aafb07b4eff976bac72a592"}, + {file = "ruff-0.1.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:744dfe4b35470fa3820d5fe45758aace6269c578f7ddc43d447868cfe5078bcb"}, + {file = "ruff-0.1.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:479ca4250cab30f9218b2e563adc362bd6ae6343df7c7b5a7865300a5156d5a6"}, + {file = "ruff-0.1.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:aa8344310f1ae79af9ccd6e4b32749e93cddc078f9b5ccd0e45bd76a6d2e8bb6"}, + {file = "ruff-0.1.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:837c739729394df98f342319f5136f33c65286b28b6b70a87c28f59354ec939b"}, + {file = "ruff-0.1.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:e6837202c2859b9f22e43cb01992373c2dbfeae5c0c91ad691a4a2e725392464"}, + {file = "ruff-0.1.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:331aae2cd4a0554667ac683243b151c74bd60e78fb08c3c2a4ac05ee1e606a39"}, + {file = "ruff-0.1.9-py3-none-win32.whl", hash = "sha256:8151425a60878e66f23ad47da39265fc2fad42aed06fb0a01130e967a7a064f4"}, + {file = "ruff-0.1.9-py3-none-win_amd64.whl", hash = "sha256:c497d769164df522fdaf54c6eba93f397342fe4ca2123a2e014a5b8fc7df81c7"}, + {file = "ruff-0.1.9-py3-none-win_arm64.whl", hash = "sha256:0e17f53bcbb4fff8292dfd84cf72d767b5e146f009cccd40c2fad27641f8a7a9"}, + {file = "ruff-0.1.9.tar.gz", hash = "sha256:b041dee2734719ddbb4518f762c982f2e912e7f28b8ee4fe1dee0b15d1b6e800"}, ] [[package]] name = "setuptools" -version = "68.2.2" +version = "69.0.3" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, - {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, + {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, + {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] @@ -2179,20 +2272,20 @@ files = [ [[package]] name = "sphinx" -version = "4.5.0" +version = "5.0.2" description = "Python documentation generator" optional = false python-versions = ">=3.6" files = [ - {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, - {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, + {file = "Sphinx-5.0.2-py3-none-any.whl", hash = "sha256:d3e57663eed1d7c5c50895d191fdeda0b54ded6f44d5621b50709466c338d1e8"}, + {file = "Sphinx-5.0.2.tar.gz", hash = "sha256:b18e978ea7565720f26019c702cd85c84376e948370f1cd43d60265010e1c7b0"}, ] [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=1.3" colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" +docutils = ">=0.14,<0.19" imagesize = "*" importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} Jinja2 = ">=2.3" @@ -2209,8 +2302,8 @@ sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.950)", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest (>=4.6)", "typed-ast"] [[package]] name = "sphinx-autodoc-typehints" @@ -2410,15 +2503,18 @@ sphinx = ["matplotlib", "myst-nb", "numpy", "sphinx-book-theme", "sphinx-design" [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.4" +version = "1.0.7" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, - {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, + {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"}, + {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] @@ -2443,30 +2539,36 @@ Sphinx = ">=2.1" [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +version = "1.0.5" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, + {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"}, + {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.1" +version = "2.0.4" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, - {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, + {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"}, + {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] @@ -2487,90 +2589,96 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +version = "1.0.6" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, + {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"}, + {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +version = "1.1.9" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, + {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"}, + {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.23" +version = "2.0.24" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:638c2c0b6b4661a4fd264f6fb804eccd392745c5887f9317feb64bb7cb03b3ea"}, - {file = "SQLAlchemy-2.0.23-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3b5036aa326dc2df50cba3c958e29b291a80f604b1afa4c8ce73e78e1c9f01d"}, - {file = "SQLAlchemy-2.0.23-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:787af80107fb691934a01889ca8f82a44adedbf5ef3d6ad7d0f0b9ac557e0c34"}, - {file = "SQLAlchemy-2.0.23-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c14eba45983d2f48f7546bb32b47937ee2cafae353646295f0e99f35b14286ab"}, - {file = "SQLAlchemy-2.0.23-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0666031df46b9badba9bed00092a1ffa3aa063a5e68fa244acd9f08070e936d3"}, - {file = "SQLAlchemy-2.0.23-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:89a01238fcb9a8af118eaad3ffcc5dedaacbd429dc6fdc43fe430d3a941ff965"}, - {file = "SQLAlchemy-2.0.23-cp310-cp310-win32.whl", hash = "sha256:cabafc7837b6cec61c0e1e5c6d14ef250b675fa9c3060ed8a7e38653bd732ff8"}, - {file = "SQLAlchemy-2.0.23-cp310-cp310-win_amd64.whl", hash = "sha256:87a3d6b53c39cd173990de2f5f4b83431d534a74f0e2f88bd16eabb5667e65c6"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d5578e6863eeb998980c212a39106ea139bdc0b3f73291b96e27c929c90cd8e1"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62d9e964870ea5ade4bc870ac4004c456efe75fb50404c03c5fd61f8bc669a72"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c80c38bd2ea35b97cbf7c21aeb129dcbebbf344ee01a7141016ab7b851464f8e"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75eefe09e98043cff2fb8af9796e20747ae870c903dc61d41b0c2e55128f958d"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd45a5b6c68357578263d74daab6ff9439517f87da63442d244f9f23df56138d"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a86cb7063e2c9fb8e774f77fbf8475516d270a3e989da55fa05d08089d77f8c4"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-win32.whl", hash = "sha256:b41f5d65b54cdf4934ecede2f41b9c60c9f785620416e8e6c48349ab18643855"}, - {file = "SQLAlchemy-2.0.23-cp311-cp311-win_amd64.whl", hash = "sha256:9ca922f305d67605668e93991aaf2c12239c78207bca3b891cd51a4515c72e22"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d0f7fb0c7527c41fa6fcae2be537ac137f636a41b4c5a4c58914541e2f436b45"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7c424983ab447dab126c39d3ce3be5bee95700783204a72549c3dceffe0fc8f4"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f508ba8f89e0a5ecdfd3761f82dda2a3d7b678a626967608f4273e0dba8f07ac"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6463aa765cf02b9247e38b35853923edbf2f6fd1963df88706bc1d02410a5577"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e599a51acf3cc4d31d1a0cf248d8f8d863b6386d2b6782c5074427ebb7803bda"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fd54601ef9cc455a0c61e5245f690c8a3ad67ddb03d3b91c361d076def0b4c60"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-win32.whl", hash = "sha256:42d0b0290a8fb0165ea2c2781ae66e95cca6e27a2fbe1016ff8db3112ac1e846"}, - {file = "SQLAlchemy-2.0.23-cp312-cp312-win_amd64.whl", hash = "sha256:227135ef1e48165f37590b8bfc44ed7ff4c074bf04dc8d6f8e7f1c14a94aa6ca"}, - {file = "SQLAlchemy-2.0.23-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:14aebfe28b99f24f8a4c1346c48bc3d63705b1f919a24c27471136d2f219f02d"}, - {file = "SQLAlchemy-2.0.23-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e983fa42164577d073778d06d2cc5d020322425a509a08119bdcee70ad856bf"}, - {file = "SQLAlchemy-2.0.23-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e0dc9031baa46ad0dd5a269cb7a92a73284d1309228be1d5935dac8fb3cae24"}, - {file = "SQLAlchemy-2.0.23-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5f94aeb99f43729960638e7468d4688f6efccb837a858b34574e01143cf11f89"}, - {file = "SQLAlchemy-2.0.23-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:63bfc3acc970776036f6d1d0e65faa7473be9f3135d37a463c5eba5efcdb24c8"}, - {file = "SQLAlchemy-2.0.23-cp37-cp37m-win32.whl", hash = "sha256:f48ed89dd11c3c586f45e9eec1e437b355b3b6f6884ea4a4c3111a3358fd0c18"}, - {file = "SQLAlchemy-2.0.23-cp37-cp37m-win_amd64.whl", hash = "sha256:1e018aba8363adb0599e745af245306cb8c46b9ad0a6fc0a86745b6ff7d940fc"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:64ac935a90bc479fee77f9463f298943b0e60005fe5de2aa654d9cdef46c54df"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c4722f3bc3c1c2fcc3702dbe0016ba31148dd6efcd2a2fd33c1b4897c6a19693"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4af79c06825e2836de21439cb2a6ce22b2ca129bad74f359bddd173f39582bf5"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:683ef58ca8eea4747737a1c35c11372ffeb84578d3aab8f3e10b1d13d66f2bc4"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d4041ad05b35f1f4da481f6b811b4af2f29e83af253bf37c3c4582b2c68934ab"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aeb397de65a0a62f14c257f36a726945a7f7bb60253462e8602d9b97b5cbe204"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-win32.whl", hash = "sha256:42ede90148b73fe4ab4a089f3126b2cfae8cfefc955c8174d697bb46210c8306"}, - {file = "SQLAlchemy-2.0.23-cp38-cp38-win_amd64.whl", hash = "sha256:964971b52daab357d2c0875825e36584d58f536e920f2968df8d581054eada4b"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:616fe7bcff0a05098f64b4478b78ec2dfa03225c23734d83d6c169eb41a93e55"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e680527245895aba86afbd5bef6c316831c02aa988d1aad83c47ffe92655e74"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9585b646ffb048c0250acc7dad92536591ffe35dba624bb8fd9b471e25212a35"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4895a63e2c271ffc7a81ea424b94060f7b3b03b4ea0cd58ab5bb676ed02f4221"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cc1d21576f958c42d9aec68eba5c1a7d715e5fc07825a629015fe8e3b0657fb0"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:967c0b71156f793e6662dd839da54f884631755275ed71f1539c95bbada9aaab"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-win32.whl", hash = "sha256:0a8c6aa506893e25a04233bc721c6b6cf844bafd7250535abb56cb6cc1368884"}, - {file = "SQLAlchemy-2.0.23-cp39-cp39-win_amd64.whl", hash = "sha256:f3420d00d2cb42432c1d0e44540ae83185ccbbc67a6054dcc8ab5387add6620b"}, - {file = "SQLAlchemy-2.0.23-py3-none-any.whl", hash = "sha256:31952bbc527d633b9479f5f81e8b9dfada00b91d6baba021a869095f1a97006d"}, - {file = "SQLAlchemy-2.0.23.tar.gz", hash = "sha256:c1bda93cbbe4aa2aa0aa8655c5aeda505cd219ff3e8da91d1d329e143e4aff69"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f801d85ba4753d4ed97181d003e5d3fa330ac7c4587d131f61d7f968f416862"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b35c35e3923ade1e7ac44e150dec29f5863513246c8bf85e2d7d313e3832bcfb"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d9b3fd5eca3c0b137a5e0e468e24ca544ed8ca4783e0e55341b7ed2807518ee"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a6209e689d0ff206c40032b6418e3cfcfc5af044b3f66e381d7f1ae301544b4"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:37e89d965b52e8b20571b5d44f26e2124b26ab63758bf1b7598a0e38fb2c4005"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6910eb4ea90c0889f363965cd3c8c45a620ad27b526a7899f0054f6c1b9219e"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-win32.whl", hash = "sha256:d8e7e8a150e7b548e7ecd6ebb9211c37265991bf2504297d9454e01b58530fc6"}, + {file = "SQLAlchemy-2.0.24-cp310-cp310-win_amd64.whl", hash = "sha256:396f05c552f7fa30a129497c41bef5b4d1423f9af8fe4df0c3dcd38f3e3b9a14"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:adbd67dac4ebf54587198b63cd30c29fd7eafa8c0cab58893d9419414f8efe4b"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a0f611b431b84f55779cbb7157257d87b4a2876b067c77c4f36b15e44ced65e2"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56a0e90a959e18ac5f18c80d0cad9e90cb09322764f536e8a637426afb1cae2f"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6db686a1d9f183c639f7e06a2656af25d4ed438eda581de135d15569f16ace33"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f0cc0b486a56dff72dddae6b6bfa7ff201b0eeac29d4bc6f0e9725dc3c360d71"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a1d4856861ba9e73bac05030cec5852eabfa9ef4af8e56c19d92de80d46fc34"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-win32.whl", hash = "sha256:a3c2753bf4f48b7a6024e5e8a394af49b1b12c817d75d06942cae03d14ff87b3"}, + {file = "SQLAlchemy-2.0.24-cp311-cp311-win_amd64.whl", hash = "sha256:38732884eabc64982a09a846bacf085596ff2371e4e41d20c0734f7e50525d01"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9f992e0f916201731993eab8502912878f02287d9f765ef843677ff118d0e0b1"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2587e108463cc2e5b45a896b2e7cc8659a517038026922a758bde009271aed11"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bb7cedcddffca98c40bb0becd3423e293d1fef442b869da40843d751785beb3"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83fa6df0e035689df89ff77a46bf8738696785d3156c2c61494acdcddc75c69d"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:cc889fda484d54d0b31feec409406267616536d048a450fc46943e152700bb79"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57ef6f2cb8b09a042d0dbeaa46a30f2df5dd1e1eb889ba258b0d5d7d6011b81c"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-win32.whl", hash = "sha256:ea490564435b5b204d8154f0e18387b499ea3cedc1e6af3b3a2ab18291d85aa7"}, + {file = "SQLAlchemy-2.0.24-cp312-cp312-win_amd64.whl", hash = "sha256:ccfd336f96d4c9bbab0309f2a565bf15c468c2d8b2d277a32f89c5940f71fcf9"}, + {file = "SQLAlchemy-2.0.24-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9aaaaa846b10dfbe1bda71079d0e31a7e2cebedda9409fa7dba3dfed1ae803e8"}, + {file = "SQLAlchemy-2.0.24-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95bae3d38f8808d79072da25d5e5a6095f36fe1f9d6c614dd72c59ca8397c7c0"}, + {file = "SQLAlchemy-2.0.24-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a04191a7c8d77e63f6fc1e8336d6c6e93176c0c010833e74410e647f0284f5a1"}, + {file = "SQLAlchemy-2.0.24-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:acc58b7c2e40235712d857fdfc8f2bda9608f4a850d8d9ac0dd1fc80939ca6ac"}, + {file = "SQLAlchemy-2.0.24-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:00d76fe5d7cdb5d84d625ce002ce29fefba0bfd98e212ae66793fed30af73931"}, + {file = "SQLAlchemy-2.0.24-cp37-cp37m-win32.whl", hash = "sha256:29e51f848f843bbd75d74ae64ab1ab06302cb1dccd4549d1f5afe6b4a946edb2"}, + {file = "SQLAlchemy-2.0.24-cp37-cp37m-win_amd64.whl", hash = "sha256:e9d036e343a604db3f5a6c33354018a84a1d3f6dcae3673358b404286204798c"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9bafaa05b19dc07fa191c1966c5e852af516840b0d7b46b7c3303faf1a349bc9"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e69290b921b7833c04206f233d6814c60bee1d135b09f5ae5d39229de9b46cd4"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8398593ccc4440ce6dffcc4f47d9b2d72b9fe7112ac12ea4a44e7d4de364db1"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f073321a79c81e1a009218a21089f61d87ee5fa3c9563f6be94f8b41ff181812"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9036ebfd934813990c5b9f71f297e77ed4963720db7d7ceec5a3fdb7cd2ef6ce"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcf84fe93397a0f67733aa2a38ed4eab9fc6348189fc950e656e1ea198f45668"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-win32.whl", hash = "sha256:6f5e75de91c754365c098ac08c13fdb267577ce954fa239dd49228b573ca88d7"}, + {file = "SQLAlchemy-2.0.24-cp38-cp38-win_amd64.whl", hash = "sha256:9f29c7f0f4b42337ec5a779e166946a9f86d7d56d827e771b69ecbdf426124ac"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:07cc423892f2ceda9ae1daa28c0355757f362ecc7505b1ab1a3d5d8dc1c44ac6"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2a479aa1ab199178ff1956b09ca8a0693e70f9c762875d69292d37049ffd0d8f"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b8d0e8578e7f853f45f4512b5c920f6a546cd4bed44137460b2a56534644205"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17e7e27af178d31b436dda6a596703b02a89ba74a15e2980c35ecd9909eea3a"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1ca7903d5e7db791a355b579c690684fac6304478b68efdc7f2ebdcfe770d8d7"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db09e424d7bb89b6215a184ca93b4f29d7f00ea261b787918a1af74143b98c06"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-win32.whl", hash = "sha256:a5cd7d30e47f87b21362beeb3e86f1b5886e7d9b0294b230dde3d3f4a1591375"}, + {file = "SQLAlchemy-2.0.24-cp39-cp39-win_amd64.whl", hash = "sha256:7ae5d44517fe81079ce75cf10f96978284a6db2642c5932a69c82dbae09f009a"}, + {file = "SQLAlchemy-2.0.24-py3-none-any.whl", hash = "sha256:8f358f5cfce04417b6ff738748ca4806fe3d3ae8040fb4e6a0c9a6973ccf9b6e"}, + {file = "SQLAlchemy-2.0.24.tar.gz", hash = "sha256:6db97656fd3fe3f7e5b077f12fa6adb5feb6e0b567a3e99f47ecf5f7ea0a09e3"}, ] [package.dependencies] @@ -2580,7 +2688,7 @@ typing-extensions = ">=4.2.0" [package.extras] aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] asyncio = ["greenlet (!=0.4.17)"] asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] @@ -2590,7 +2698,7 @@ mssql-pyodbc = ["pyodbc"] mypy = ["mypy (>=0.910)"] mysql = ["mysqlclient (>=1.4.0)"] mysql-connector = ["mysql-connector-python"] -oracle = ["cx-oracle (>=8)"] +oracle = ["cx_oracle (>=8)"] oracle-oracledb = ["oracledb (>=1.0.1)"] postgresql = ["psycopg2 (>=2.7)"] postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] @@ -2600,7 +2708,7 @@ postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2cffi = ["psycopg2cffi"] postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3-binary"] +sqlcipher = ["sqlcipher3_binary"] [[package]] name = "stack-data" @@ -2648,48 +2756,48 @@ files = [ [[package]] name = "tornado" -version = "6.3.3" +version = "6.4" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">= 3.8" files = [ - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, - {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, - {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, - {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, + {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, + {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, + {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, ] [[package]] name = "traitlets" -version = "5.13.0" +version = "5.14.0" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.13.0-py3-none-any.whl", hash = "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619"}, - {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"}, + {file = "traitlets-5.14.0-py3-none-any.whl", hash = "sha256:f14949d23829023013c47df20b4a76ccd1a85effb786dc060f34de7948361b33"}, + {file = "traitlets-5.14.0.tar.gz", hash = "sha256:fcdaa8ac49c04dfa0ed3ee3384ef6dfdb5d6f3741502be247279407679296772"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.6.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "typing-extensions" -version = "4.8.0" +version = "4.9.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] [[package]] @@ -2708,36 +2816,35 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "urllib3" -version = "2.0.7" +version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, - {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, + {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, + {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.24.6" +version = "20.25.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"}, - {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"}, + {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, + {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<4" +platformdirs = ">=3.9.1,<5" [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] @@ -2745,24 +2852,24 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "wcwidth" -version = "0.2.9" +version = "0.2.12" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.9-py2.py3-none-any.whl", hash = "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223"}, - {file = "wcwidth-0.2.9.tar.gz", hash = "sha256:a675d1a4a2d24ef67096a04b85b02deeecd8e226f57b5e3a72dbb9ed99d27da8"}, + {file = "wcwidth-0.2.12-py2.py3-none-any.whl", hash = "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c"}, + {file = "wcwidth-0.2.12.tar.gz", hash = "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02"}, ] [[package]] name = "wheel" -version = "0.41.3" +version = "0.42.0" description = "A built-package format for Python" optional = false python-versions = ">=3.7" files = [ - {file = "wheel-0.41.3-py3-none-any.whl", hash = "sha256:488609bc63a29322326e05560731bf7bfea8e48ad646e1f5e40d366607de0942"}, - {file = "wheel-0.41.3.tar.gz", hash = "sha256:4d4987ce51a49370ea65c0bfd2234e8ce80a12780820d9dc462597a6e60d0841"}, + {file = "wheel-0.42.0-py3-none-any.whl", hash = "sha256:177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d"}, + {file = "wheel-0.42.0.tar.gz", hash = "sha256:c45be39f7882c9d34243236f2d63cbd58039e360f85d0913425fbd7ceea617a8"}, ] [package.extras] @@ -2786,4 +2893,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 4" -content-hash = "5d9f4696cece7fa12acf3fac835727eb0057344529a6461ea3e6143ccafce22d" +content-hash = "3a9a88c923c0c2acbff96c969831444e3c556d92cc91ba45e790e9f782ad3ea7" diff --git a/pyproject.toml b/pyproject.toml index 665fcee1..1c1d5969 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,9 @@ dunamai = "^1.12.0" hypothesis = "^6.54.2" jupyter-book = "^0.15.0" sphinx-autodoc-typehints = "^1.17.0" -pydantic = "^1.10.0" + +# Make optional dependency +pydantic = "^2.5.0" [tool.poetry.group.dev.dependencies] ruff = "^0.1.3" diff --git a/tests/test_catch.py b/tests/test_catch.py index 2cc3e228..17307326 100644 --- a/tests/test_catch.py +++ b/tests/test_catch.py @@ -21,7 +21,7 @@ def fn() -> Any: result = fn() match result: - case Error(ex): + case Result(tag="error", error=ex): assert isinstance(ex, ValueError) assert str(ex) == "error" @@ -49,7 +49,7 @@ def fn(ex: Exception) -> Any: result = fn(ValueError("error")) match result: - case Error(ex): + case Result(tag="error", error=ex): assert isinstance(ex, ValueError) assert str(ex) == "error" case _: @@ -57,7 +57,7 @@ def fn(ex: Exception) -> Any: result = fn(KeyError("error")) match result: - case Error(ex): + case Result(tag="error", error=ex): assert isinstance(ex, KeyError) assert str(ex) == "'error'" case _: @@ -79,12 +79,12 @@ def test_catch_with_effect_error(): @catch(exception=TypeError) @effect.try_[int]() def fn(a: int) -> Generator[int, int, int]: - b = yield from Error[int, Exception](ValueError("failure")) + b = yield from Error(ValueError("failure")) return a + b result = fn(1) match result: - case Error(ex): + case Result(tag="error", error=ex): assert isinstance(ex, ValueError) assert str(ex) == "failure" case _: @@ -100,7 +100,7 @@ def fn(a: int) -> Generator[str, str, str]: result = fn(1) match result: - case Error(ex): + case Result(tag="error", error=ex): assert isinstance(ex, TypeError) case _: assert False diff --git a/tests/test_option.py b/tests/test_option.py index b132ffeb..b0e7018e 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -18,14 +18,14 @@ pipe, pipe2, ) -from expression.core.option import BaseOption, Nothing_ +from expression.core.option import Option, Nothing, Some from expression.extra.option import pipeline def test_option_some(): xs = Some(42) - assert isinstance(xs, BaseOption) + assert isinstance(xs, Option) assert pipe(xs, option.is_some) is True assert pipe(xs, option.is_none) is False @@ -34,10 +34,10 @@ def test_option_some_match(): xs = Some(42) match xs: - case Some(x): + case Option(tag="some", some=x): assert x == 42 - case _: # type: ignore + case _: assert False @@ -46,7 +46,7 @@ def test_option_some_match_fluent(): ys = xs.map(lambda x: x + 1) match ys: - case Some(value): + case Option(tag="some", some=value): assert value == 43 case _: assert False @@ -65,7 +65,7 @@ def test_option_some_iterate(): def test_option_none(): xs = Nothing - assert isinstance(xs, BaseOption) + assert isinstance(xs, Option) assert xs.pipe(option.is_some) is False assert xs.pipe(option.is_none) is True @@ -74,7 +74,7 @@ def test_option_none_match(): xs = Nothing match xs: - case Some(): # type: ignore + case Option(tag="some"): assert False case x if x is Nothing: @@ -167,7 +167,7 @@ def test_option_some_map_piped(): ys: Option[int] = xs.pipe(option.map(mapper)) match ys: - case Some(y): + case Option(tag="some", some=y): assert y == 43 case _: assert False @@ -187,7 +187,7 @@ def test_option_some_map_fluent(): ys = xs.map(lambda x: x + 1) match ys: - case Some(value): + case Option(tag="some", some=value): assert value == 43 case _: assert False @@ -208,7 +208,7 @@ def test_option_some_map2_piped(x: int, y: int): zs = pipe2((xs, ys), option.map2(mapper)) match zs: - case Some(value): + case Option(tag="some", some=value): assert value == x + y case _: assert False @@ -219,7 +219,7 @@ def test_option_some_bind_fluent(): ys = xs.bind(lambda x: Some(x + 1)) match ys: - case Some(value): + case Option(tag="some", some=value): assert value == 43 case _: assert False @@ -230,7 +230,7 @@ def test_option_some_bind_none_fluent(): ys = xs.bind(lambda x: Nothing) match ys: - case Nothing_(): + case Option(tag="none"): assert True case _: assert False @@ -241,7 +241,7 @@ def test_option_none_bind_none_fluent(): ys = xs.bind(lambda x: Nothing) match ys: - case Some(): + case Option(tag="some"): assert False case _: assert True @@ -255,7 +255,7 @@ def test_option_some_bind_piped(): ) match ys: - case Some(value): + case Option(tag="some", some=value): assert value == 43 case _: assert False @@ -393,7 +393,7 @@ def fn(): xs = fn() match xs: - case Some(value): + case Option(tag="some", some=value): assert value == 42 case _: assert False @@ -406,7 +406,7 @@ def fn(): xs = fn() match xs: - case Some(value): + case Option(tag="some", some=value): assert value == 42 case _: assert False @@ -420,7 +420,7 @@ def fn() -> Generator[Option[int], Option[int], Option[int]]: xs = fn() match xs: - case Some(value): + case Option(tag="some", some=value): assert value == Some(42) case _: assert False @@ -434,7 +434,7 @@ def fn() -> Generator[int, int, int]: xs = fn() match xs: - case Some(value): + case Option(tag="some", some=value): assert value == 42 case _: assert False @@ -448,7 +448,7 @@ def fn(): xs = fn() match xs: - case Some(value): + case Option(tag="some", some=value): assert value is Nothing case _: assert False @@ -462,7 +462,7 @@ def fn() -> Generator[int, int, int]: xs = fn() match xs: - case Some(value): + case Option(tag="some", some=value): assert value == 43 case _: assert False @@ -489,7 +489,7 @@ def fn() -> Generator[int, int, int]: xs = fn() match xs: - case Some(value): + case Option(tag="some", some=value): assert value == 85 case _: assert False @@ -556,13 +556,11 @@ class Model(BaseModel): two: Option[str] = Nothing three: Option[float] = Nothing - class Config: - json_encoders: Dict[Type[Any], Callable[[Any], Any]] = {BaseOption: option.dict} - - def test_parse_option_works(): - obj = dict(one=10) - model = Model.parse_obj(obj) + obj = dict(one=10, two=None) + model = Model.model_validate(obj) + + print("model: ", model) assert model.one.is_some() assert model.one.value == 10 @@ -571,9 +569,9 @@ def test_parse_option_works(): def test_serialize_option_works(): - model = Model(one=Some(10), two=Nothing) - json = model.json() - model_ = Model.parse_raw(json) + model = Model(one=Some(10)) + json = model.model_dump_json() + model_ = Model.model_validate_json(json) assert model_.one.is_some() assert model_.one.value == 10 diff --git a/tests/test_parser.py b/tests/test_parser.py index c08cc2d5..ddb16712 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -2,9 +2,9 @@ import string from dataclasses import dataclass -from typing import Any +from typing import Any, Literal -from expression import Error, Ok, Option, Some, Tag, TaggedUnion, pipe, tag +from expression import Option, case, tagged_union, pipe, tag, Result from expression.collections import Block from expression.extra.parser import ( Parser, @@ -28,7 +28,7 @@ def test_parse_pchar(): assert result.is_ok() match result: - case Ok(a): + case Result(tag="ok", ok=a): assert a == "A" case _: assert False @@ -42,7 +42,7 @@ def test_parse_pchar_fluent(): assert result.is_ok() match result: - case Ok(a): + case Result(tag="ok", ok=a): assert a == "A" case _: assert False @@ -61,7 +61,7 @@ def test_parse_a_then_b(): result = parseAB(input) assert result.is_ok() match result: - case Ok((a, b)): + case Result(tag="ok", ok=(a, b)): assert (a, b) == ("A", "B") case _: assert False @@ -74,7 +74,7 @@ def test_parse_a_then_b_fluent(): result = parseAB(input) assert result.is_ok() match result: - case Ok((a, b)): + case Result(tag="ok", ok=(a, b)): assert (a, b) == ("A", "B") case _: assert False @@ -86,7 +86,7 @@ def test_pstring(): ret = parse_abc("ABCDE") # Success ("ABC", "DE") assert ret.is_ok() match ret: - case Ok(success): + case Result(tag="ok", ok=success): assert success == "ABC" case _: assert False @@ -94,7 +94,7 @@ def test_pstring(): ret = parse_abc("A|CDE") # Failure "Expecting 'B'. Got '|'" assert ret.is_error() match ret: - case Error(error): + case Result(tag="error", error=error): assert error == "Expecting 'B'. Got '|'" case _: assert False @@ -102,7 +102,7 @@ def test_pstring(): ret = parse_abc("AB|DE") # Failure "Expecting 'C'. Got '|'" assert ret.is_error() match ret: - case Error(error): + case Result(tag="error", error=error): assert error == "Expecting 'C'. Got '|'" case _: assert False @@ -112,7 +112,7 @@ def test_int(): ret = pint("123C") match ret: - case Ok(success): + case Result(tag="ok", ok=success): assert success == 123 case _: assert False @@ -122,7 +122,7 @@ def test_int_negative(): ret = pint("-123C") match ret: - case Ok(success): + case Result(tag="ok", ok=success): assert success == -123 case _: assert False @@ -132,7 +132,7 @@ def test_float(): ret = pfloat("123C") match ret: - case Ok(success): + case Result(tag="ok", ok=success): assert success == 123 case _: assert False @@ -142,7 +142,7 @@ def test_float_with_decimal(): ret = pfloat("123.45C") match ret: - case Ok(success): + case Result(tag="ok", ok=success): assert success == 123.45 case _: assert False @@ -152,31 +152,33 @@ def test_negative_float_with_decimal(): ret = pfloat("-123.45C") match ret: - case Ok(success): + case Result(tag="ok", ok=success): assert success == -123.45 case _: assert False - -class ComparisonOperator(TaggedUnion): - EQ = tag() - NOT_EQ = tag() - LT = tag() - LT_E = tag() - GT = tag() - GT_E = tag() - IS = tag() - IS_NOT = tag() - IN = tag() - NOT_IN = tag() +@tagged_union +class ComparisonOperator: + tag: Literal["EQ", "NOT_EQ", "LT", "LT_E", "GT", "GT_E", "IS", "IS_NOT", "IN", "NOT_IN"] = tag() + + EQ: bool = case() + NOT_EQ: bool = case() + LT: bool = case() + LT_E: bool = case() + GT: bool = case() + GT_E: bool = case() + IS: bool = case() + IS_NOT: bool = case() + IN: bool = case() + NOT_IN: None = case() @staticmethod def eq() -> ComparisonOperator: - return ComparisonOperator(ComparisonOperator.EQ) + return ComparisonOperator(EQ=True) @staticmethod def not_eq() -> ComparisonOperator: - return ComparisonOperator(ComparisonOperator.NOT_EQ) + return ComparisonOperator(NOT_EQ=True) @dataclass @@ -185,37 +187,40 @@ class Compare: comparators: Block[Expression] ops: Block[ComparisonOperator] - -class BoolOp(TaggedUnion): - AND = tag() - OR = tag() +@tagged_union +class BoolOp: + AND: None = case() + OR: None = case() @staticmethod def and_() -> BoolOp: - return BoolOp(BoolOp.AND) + return BoolOp(AND=None) @staticmethod def or_() -> BoolOp: - return BoolOp(BoolOp.OR) + return BoolOp(OR=None) + +@tagged_union +class Expression: + tag: Literal["NAME", "CONSTANT", "BOOL_OP", "COMPARE"] = tag() -class Expression(TaggedUnion): - CONSTANT = tag() - NAME = Tag[str]() - BOOL_OP = Tag[BoolOp]() - COMPARE = Tag[Compare]() + CONSTANT: bool = case() + NAME: str = case() + BOOL_OP: BoolOp = case() + COMPARE: Compare = case() @staticmethod def name(name: str) -> Expression: - return Expression(Expression.NAME, name) + return Expression(NAME=name) @staticmethod def compare(compare: Compare) -> Expression: - return Expression(Expression.COMPARE, compare) + return Expression(COMPARE=compare) @staticmethod def constant(value: Any) -> Expression: - return Expression(Expression.CONSTANT, value) + return Expression(CONSTANT=value) def pname() -> Parser[Expression]: @@ -228,7 +233,7 @@ def pname() -> Parser[Expression]: def mapper(first: str, rest: Option[Block[str]]) -> str: match rest: - case Some(letters): + case Option(tag="some", some=letters): return first + "".join(letters) case _: return first @@ -255,7 +260,7 @@ def test_parse_name_expr(): assert result.is_ok() match result: - case Ok(Expression(Expression.NAME, name)): + case Result(tag="ok", ok=Expression(NAME=name)): assert name == "test" case _: diff --git a/tests/test_result.py b/tests/test_result.py index 87132eb4..e95038a9 100644 --- a/tests/test_result.py +++ b/tests/test_result.py @@ -1,41 +1,47 @@ -from typing import Any, Callable, Dict, Generator, List, Type +from typing import Any, Callable, Generator, List import pytest from hypothesis import given # type: ignore from hypothesis import strategies as st -from pydantic import BaseModel, parse_obj_as +from pydantic import BaseModel, TypeAdapter -from expression import Error, Nothing, Ok, Option, Result, Some, effect, result +from expression import Nothing, Option, Result, Some, effect, result, Ok, Error from expression.collections import Block -from expression.core.result import BaseResult from expression.extra.result import pipeline, sequence from .utils import CustomException +def test_pattern_match_with_alias(): + xs: Result[int, str] = Ok(42) + + match xs: + case Result(tag="ok", ok=x): + assert x == 42 + case _: + assert False def test_result_ok(): - xs: Result[int, str] = Ok(42) + xs: Result[int, str] = Result.Ok(42) - assert isinstance(xs, BaseResult) + assert isinstance(xs, Result) assert xs.is_ok() assert not xs.is_error() assert str(xs) == "Ok 42" match xs: - case Ok(x): + case Result(tag="ok", ok=x): assert x == 42 - - case _: # type: ignore + case _: assert False def test_result_match_ok(): - xs: Result[int, str] = Ok(42) + xs: Result[int, str] = Result.Ok(42) match xs: - case Ok(x): + case Result(tag="ok", ok=x): assert x == 42 - case _: # type: ignore + case _: assert False @@ -43,7 +49,7 @@ def test_result_match_error(): xs: Result[int, str] = Error("err") match xs: - case Error(err): + case Result(tag="error", error=err): assert err == "err" case _: # type: ignore assert False @@ -58,26 +64,26 @@ def test_result_error(): error = CustomException("d'oh!") xs: Result[str, Exception] = Error(error) - assert isinstance(xs, BaseResult) + assert isinstance(xs, Result) assert not xs.is_ok() assert xs.is_error() assert str(xs) == f"Error {error}" match xs: - case Ok(): # type: ignore + case Result(tag="ok"): assert False - case Error(ex): + case Result(error=ex): assert ex == error -def test_result_error_iterate(): - with pytest.raises(Error) as excinfo: # type: ignore - error: Error[int, str] = Error("err") - for _ in error: - assert False +# def test_result_error_iterate(): +# with pytest.raises(Exception) as excinfo: +# error: Result[int, str] = Error("err") +# for _ in error: +# assert False - assert excinfo.value.error == "err" # type: ignore +# assert excinfo.value.error == "err" # type: ignore @given(st.integers(), st.integers()) @@ -109,7 +115,7 @@ def test_result_map_piped(x: int, y: int): ys = xs.pipe(result.map(mapper)) # NOTE: shows type error for mypy match ys: - case Ok(value): + case Result(tag="ok", ok=value): assert value == mapper(x) case _: assert False @@ -122,7 +128,7 @@ def test_result_map_ok_fluent(x: int, y: int): ys = xs.map(mapper) match ys: - case Ok(value): + case Result(tag="ok", ok=value): assert value == mapper(x) case _: assert False @@ -137,7 +143,7 @@ def test_result_ok_chained_map(x: int, y: int): ys = xs.map(mapper1).map(mapper2) match ys: - case Ok(value): + case Result(tag="ok", ok=value): assert value == mapper2(mapper1(x)) case _: assert False @@ -151,7 +157,7 @@ def test_result_map_error_piped(msg: str, y: int): ys = xs.pipe(result.map(mapper)) match ys: - case Error(err): + case Result(tag="error", error=err): assert err == msg case _: assert False @@ -164,7 +170,7 @@ def test_result_map_error_fluent(msg: str, y: int): ys = xs.map(mapper) match ys: - case Error(err): + case Result(tag="error", error=err): assert err == msg case _: assert False @@ -178,7 +184,7 @@ def test_result_error_chained_map(msg: str, y: int): ys = xs.map(mapper1).map(mapper2) match ys: - case Error(err): + case Result(tag="error", error=err): assert err == msg case _: assert False @@ -191,7 +197,7 @@ def test_result_bind_piped(x: int, y: int): ys = xs.pipe(result.bind(mapper)) match ys: - case Ok(value): + case Result(tag="ok", ok=value): assert Ok(value) == mapper(x) case _: assert False @@ -202,7 +208,7 @@ def test_result_traverse_ok(xs: List[int]): ys: Block[Result[int, str]] = Block([Ok(x) for x in xs]) zs = sequence(ys) match zs: - case Ok(value): + case Result(tag="ok", ok=value): assert sum(value) == sum(xs) case _: assert False @@ -217,7 +223,7 @@ def test_result_traverse_error(xs: List[int]): zs = sequence(ys) match zs: - case Error(err): + case Result(tag="error", error=err): assert err == error case _: assert False @@ -252,7 +258,7 @@ def fn() -> Generator[int, int, int]: xs = fn() match xs: - case Ok(x): + case Result(tag="ok", ok=x): assert x == 42 case _: assert False @@ -266,7 +272,7 @@ def fn() -> Generator[int, int, int]: xs = fn() match xs: - case Ok(x): + case Result(tag="ok", ok=x): assert x == 43 case _: assert False @@ -286,7 +292,7 @@ def fn() -> Generator[int, int, int]: xs = fn() match xs: - case Error(err): + case Result(tag="error", error=err): assert err == error case _: assert False, "Should not happen" @@ -302,7 +308,7 @@ def fn() -> Generator[int, int, int]: xs = fn() match xs: - case Ok(value): + case Result(tag="ok", ok=value): assert value == 85 case _: assert False @@ -362,52 +368,63 @@ class Model(BaseModel): two: Result[str, MyError] = Error(MyError(message="error")) three: Result[float, MyError] = Error(MyError(message="error")) - class Config: - json_encoders: Dict[Type[Any], Callable[[Any], Any]] = { - BaseResult: result.dict, - } - def test_parse_block_works(): obj = dict(one=dict(ok=42)) - model = Model.parse_obj(obj) + model = Model.model_validate(obj) - assert isinstance(model.one, BaseResult) + assert isinstance(model.one, Result) assert model.one == Ok(42) assert model.two == Error(MyError(message="error")) assert model.three == Error(MyError(message="error")) def test_ok_to_dict_works(): - result = Ok[int, MyError](10) - obj = result.dict() + result = Ok(10) + obj = result.model_dump() assert obj == dict(ok=10) def test_error_to_dict_works(): error = MyError(message="got error") - result = Error[int, MyError](error) - obj = result.dict() + result = Error(error) + obj = result.model_dump() assert obj == dict(error=dict(message="got error")) def test_ok_from_from_dict_works(): obj = dict(ok=10) - result = parse_obj_as(Result[int, MyError], obj) + adapter = TypeAdapter(Result[int, MyError]) + result = adapter.validate_python(obj) assert result - assert isinstance(result, Ok) - assert result.value == 10 + assert isinstance(result, Result) + match result: + case Result(tag="ok", ok=x): + assert x == 10 + case _: + assert False def test_error_from_dict_works(): obj = dict(error=dict(message="got error")) - result = parse_obj_as(Result[int, MyError], obj) + adapter = TypeAdapter(Result[int, MyError]) + result = adapter.validate_python(obj) assert result - assert isinstance(result, Error) - assert result.error == MyError(message="got error") + assert isinstance(result, Result) + match result: + case Result(tag="error", error=error): + assert error.message == "got error" + case _: + assert False + +def test_model_to_json_works(): + model = Model(one=Ok(10)) + obj = model.model_dump_json() + print(f"obj: {obj}") + assert obj == '{"one":{"ok":10},"two":{"error":{"message":"error"}},"three":{"error":{"message":"error"}}}' def test_error_default_value(): xs: Result[int, int] = Error(0) diff --git a/tests/test_try.py b/tests/test_try.py index 64b67bca..4af576a7 100644 --- a/tests/test_try.py +++ b/tests/test_try.py @@ -16,16 +16,10 @@ def test_can_create_failure(): def test_try_success(): xs: Try[int] = Success(10) - for x in xs: - assert x == 10 - - -def test_try_failure(): - error = CustomException("err") - xs: Try[int] = Failure(error) - - with pytest.raises(Failure): # type: ignore - for _ in xs: + match xs: + case Try(tag="ok", ok=x): + assert x == 10 + case _: assert False @@ -34,7 +28,7 @@ def test_try_match_failure(): xs: Try[int] = Failure(error) match xs: - case Failure(err): + case Try(tag="error", error=err): assert err == error - case _: # type: ignore + case _: assert False diff --git a/tests/test_union.py b/tests/test_union.py index d3c2a23f..1ece554f 100644 --- a/tests/test_union.py +++ b/tests/test_union.py @@ -1,308 +1,281 @@ from __future__ import annotations -from dataclasses import dataclass -from typing import Generic, Tuple, TypeVar, final +from dataclasses import asdict, dataclass +from typing import Generic, Literal, TypeVar -from pydantic import parse_obj_as +import pytest -from expression import SingleCaseUnion, Tag, TaggedUnion, tag +from expression import case, tag, tagged_union _T = TypeVar("_T") -@dataclass -class Rectangle: - width: float - length: float - - -@dataclass +@dataclass(unsafe_hash=True) class Circle: radius: float -@final -class Shape(TaggedUnion): - RECTANGLE = Tag[Rectangle]() - CIRCLE = Tag[Circle]() - - @staticmethod - def rectangle(width: float, length: float) -> Shape: - return Shape(Shape.RECTANGLE, Rectangle(width, length)) - - @staticmethod - def circle(radius: float) -> Shape: - return Shape(Shape.CIRCLE, Circle(radius)) +@tagged_union +class Shape: + tag: Literal["circle", "rectangle", "triangle"] = tag() + circle: Circle = case() + rectangle: tuple[float, float] = case() + triangle: tuple[float, float] = case() -def test_union_create(): - shape = Shape.circle(2.3) - assert shape.tag == Shape.CIRCLE - assert shape.value == Circle(2.3) +def test_union_create_shape_works(): + shape = Shape(circle=Circle(10.0)) + assert shape.circle.radius == 10.0 -def test_union_match_tag(): - shape = Shape.rectangle(2.3, 3.3) - match shape.tag: - case Shape.CIRCLE: - assert False - case Shape.RECTANGLE: - assert True - case _: - assert False +def test_union_shape_tag_is_set(): + shape = Shape(circle=Circle(10.0)) + assert shape.tag == "circle" -def test_union_match_type(): - shape = Shape.rectangle(2.3, 3.3) +def test_union_shape_circle_pattern_matching_works(): + shape = Shape(circle=Circle(10.0)) match shape: - case Shape(value=Rectangle(length=length)): - assert length == 3.3 + case Shape(tag="rectangle", rectangle=(w, h)): + raise AssertionError("Should not match") + case Shape(tag="circle", circle=Circle(radius=r)): + assert r == 10.0 case _: assert False -def test_union_match_value(): - shape = Shape.rectangle(2.3, 3.3) +def test_shape_rectangle_pattern_matching_works(): + shape = Shape(rectangle=(10.0, 20.0)) match shape: - case Shape(value=Rectangle(width=2.3)): - assert shape.value.width == 2.3 + case Shape(tag="circle", circle=Circle(radius=r)): + raise AssertionError("Should not match") + case Shape(tag="rectangle", rectangle=(w, h)): + assert w == 10.0 + assert h == 20.0 case _: assert False -def test_union_no_match_value(): - shape = Shape.rectangle(2.3, 3.3) +def test_union_shape_hash_works(): + shape = Shape(circle=Circle(10.0)) + assert hash(shape) == hash(("Shape", "circle", Circle(10.0))) - match shape: - case Shape(Rectangle(width=12.3)): # type: ignore - assert False - case _: - assert True +def test_union_shape_repr_works(): + shape = Shape(circle=Circle(10.0)) + assert repr(shape) == "Shape(circle=Circle(radius=10.0))" -@final -class Weather(TaggedUnion): - SUNNY = tag() - RAINY = tag() - @staticmethod - def sunny() -> Weather: - return Weather(Weather.SUNNY) +def test_union_can_add_custom_attributes_to_shape(): + shape = Shape(circle=Circle(10.0)) + setattr(shape, "custom", "rectangle") + assert getattr(shape, "custom") == "rectangle" - @staticmethod - def rainy() -> Weather: - return Weather(Weather.RAINY) +def test_union_cannot_change_case_value(): + shape = Shape(circle=Circle(10.0)) + with pytest.raises(TypeError): + shape.circle = Circle(20.0) -def test_union_wether_match(): - rainy = Weather.sunny() - match rainy: - case Weather(Weather.RAINY): - assert False - case Weather(Weather.SUNNY): - assert True - case _: - assert False +def test_union_compare_shapes(): + shape1 = Shape(circle=Circle(10.0)) + shape2 = Shape(circle=Circle(10.0)) + assert shape1 == shape2 + shape3 = Shape(rectangle=(10.0, 20.0)) + assert shape1 != shape3 -class Maybe(TaggedUnion, Generic[_T]): - NOTHING = tag() - JUST = Tag[_T]() - @staticmethod - def just(value: _T) -> Maybe[_T]: - return Maybe[_T](Maybe.JUST, value) +def test_union_compare_shapes_with_different_tags(): + shape1 = Shape(circle=Circle(10.0)) + shape2 = Shape(rectangle=(10.0, 20.0)) + assert shape1 != shape2 - @staticmethod - def nothing() -> Maybe[None]: - return Maybe[None](Maybe.NOTHING) +@tagged_union +class Maybe(Generic[_T]): + tag: Literal["just", "nothing"] = tag() -def test_union_maybe_match(): - maybe = Maybe.just(10) - value: int + just: _T = case() + nothing: None = case() - match maybe: - case Maybe(Maybe.NOTHING): - assert False - case Maybe(Maybe.JUST, value=value): - assert value == 10 + +def test_maybe_works(): + xs = Maybe(just=1) + match xs: + case Maybe(tag="just", just=x): + assert x == 1 case _: assert False -@final -class Suit(TaggedUnion): - HEARTS = tag(1) - SPADES = tag(2) - CLUBS = tag(3) - DIAMONDS = tag(4) - - @staticmethod - def hearts() -> Suit: - return Suit(Suit.HEARTS) - - @staticmethod - def spades() -> Suit: - return Suit(Suit.SPADES) - - @staticmethod - def clubs() -> Suit: - return Suit(Suit.CLUBS) - - @staticmethod - def diamonds() -> Suit: - return Suit(Suit.DIAMONDS) +def test_maybe_just_works(): + xs = Maybe(just=1) + match xs: + case Maybe(tag="just", just=x): + assert x == 1 + case Maybe(tag="nothing", nothing=None): + assert False + case _: + assert False +def test_maybe_nothing_works(): + xs = Maybe[int](nothing=None) + match xs: + case Maybe(tag="nothing", nothing=None): + assert True + case _: + assert False -@final -class Face(TaggedUnion): - JACK = tag() - QUEEN = tag() - KIND = tag() - ACE = tag() - @staticmethod - def jack() -> Face: - return Face(Face.JACK) +def test_nested_unions_works(): + xs = Maybe(just=Shape(circle=Circle(10.0))) + match xs: + case Maybe(tag="just", just=Shape(tag="circle", circle=Circle(radius=r))): + assert r == 10.0 + case _: + assert False - @staticmethod - def queen() -> Face: - return Face(Face.QUEEN) - @staticmethod - def king() -> Face: - return Face(Face.KIND) +def test_union_maybe_asdict_works(): + xs = Maybe(just=1) + assert asdict(xs) == {"tag": "just", "just": 1} - @staticmethod - def ace() -> Face: - return Face(Face.ACE) +def test_unions_can_be_composed(): + @tagged_union + class Weather: + tag: Literal["sunny", "rainy"] = tag() -@final -class Card(TaggedUnion): - FACE_CARD = Tag[Tuple[Suit, Face]]() - VALUE_CARD = Tag[Tuple[Suit, int]]() - JOKER = tag() + sunny: bool = case() + rainy: bool = case() - @staticmethod - def face_card(suit: Suit, face: Face) -> Card: - return Card(Card.FACE_CARD, (suit, face)) + @tagged_union + class Day: + tag: Literal["weekday", "weekend"] = tag() - @staticmethod - def value_card(suit: Suit, value: int) -> Card: - return Card(Card.VALUE_CARD, (suit, value)) + weekday: Weather = case() + weekend: Weather = case() - @staticmethod - def Joker() -> Card: - return Card(Card.JOKER) - - -jack_of_hearts = Card.face_card(Suit.hearts(), Face.jack()) -three_of_clubs = Card.value_card(Suit.clubs(), 3) -joker = Card.Joker() - - -def calculate_value(card: Card) -> int: - match card: - case Card(Card.JOKER): - return 0 - case Card(value=Face(suit=Suit.SPADES, face=Face.QUEEN)): - return 40 - case Card(value=Face(face=Face.ACE)): - return 15 - case Card(Card.FACE_CARD): - return 10 - case Card(tag=Card.FACE_CARD, value=(_, 10)): - return 10 + today = Day(weekday=Weather(sunny=True)) + match today: + case Day(tag="weekday", weekday=Weather(tag="sunny", sunny=s)): + assert s is True case _: - return 5 - - -def test_union_cards(): - rummy_score = calculate_value(jack_of_hearts) - assert rummy_score == 10 - - rummy_score = calculate_value(three_of_clubs) - assert rummy_score == 5 - - rummy_score = calculate_value(joker) - assert rummy_score == 0 + assert False -class EmailAddress(SingleCaseUnion[str]): - ... +@tagged_union +class Email: + email: str = case() -def test_single_case_union_create(): - addr = "foo@bar.com" - email = EmailAddress(addr) +def test_single_case_union_works(): + email = Email(email="test@test.com") + match email: + case Email(e): + assert e == "test@test.com" + case _: # pyright: ignore + assert False - assert email.VALUE.tag == 1000 - assert email.value == addr +@tagged_union +class Suit: + tag: Literal["spades", "hearts", "clubs", "diamonds"] = tag() -def test_single_case_union_match(): - addr = "foo@bar.com" - email = EmailAddress(addr) + spades: None = case() + hearts: None = case() + clubs: None = case() + diamonds: None = case() - match email: - case EmailAddress(): - assert True - case _: # type: ignore - assert False + @staticmethod + def Spades() -> Suit: + return Suit(spades=None) + @staticmethod + def Hearts() -> Suit: + return Suit(hearts=None) -def test_single_case_union_match_value(): - addr = "foo@bar.com" - email = EmailAddress(addr) + @staticmethod + def Clubs() -> Suit: + return Suit(clubs=None) - match email: - case EmailAddress(value=value): - assert value == addr - case _: # type: ignore - assert False + @staticmethod + def Diamonds() -> Suit: + return Suit(diamonds=None) -def test_single_case_union_not_match_value(): - addr = "foo@bar.com" - email = EmailAddress(addr) +@tagged_union +class Face: + tag: Literal["jack", "queen", "king", "ace"] = tag() - match email: - case EmailAddress(value="test@test.com"): - assert False - case _: - assert True + jack: None = case() + queen: None = case() + king: None = case() + ace: None = case() + @staticmethod + def Jack() -> Face: + return Face(jack=None) -def test_union_to_dict_works(): - maybe = Maybe.just(10) - obj = maybe.dict() - assert obj == dict(tag="JUST", value=10) + @staticmethod + def Queen() -> Face: + return Face(queen=None) + @staticmethod + def King() -> Face: + return Face(king=None) -def test_union_from_dict_works(): - obj = dict(tag="JUST", value=10) - maybe = parse_obj_as(Maybe[int], obj) + @staticmethod + def Ace() -> Face: + return Face(ace=None) - assert maybe - assert maybe.value == 10 +@tagged_union +class Card: + tag: Literal["value_card", "face_card", "joker"] = tag() -def test_nested_union_to_dict_works(): - maybe = Maybe.just(Maybe.just(10)) - obj = maybe.dict() - assert obj == dict(tag="JUST", value=dict(tag="JUST", value=10)) + face_card: tuple[Suit, Face] = case() + value_card: tuple[Suit, int] = case() + joker: None = case() + @staticmethod + def Face(suit: Suit, face: Face) -> Card: + return Card(face_card=(suit, face)) -def test_nested_union_from_dict_works(): - obj = dict(tag="JUST", value=dict(tag="JUST", value=10)) + @staticmethod + def Value(suit: Suit, value: int) -> Card: + return Card(value_card=(suit, value)) - maybe = parse_obj_as(Maybe[Maybe[int]], obj) - assert maybe - assert maybe.value - assert maybe.value.value == 10 + @staticmethod + def Joker() -> Card: + return Card(joker=None) + + +def test_rummy_score(): + def score(card: Card) -> int: + match card: + case Card(tag="face_card", face_card=(Suit(spades=None), Face(queen=None))): + return 40 + case Card(tag="face_card", face_card=(_suit, Face(ace=None))): + return 15 + case Card(tag="face_card", face_card=(_suit, _face)): + return 10 + case Card(tag="value_card", value_card=(_suit, value)): + return value + case Card(tag="joker", joker=None): + return 0 + case _: + raise AssertionError("Should not match") + + assert score(Card.Face(Suit.Spades(), Face.Jack())) == 10 + assert score(Card.Value(Suit.Spades(), 5)) == 5 + assert score(Card.Joker()) == 0 + assert score(Card.Face(Suit.Spades(), Face.Queen())) == 40 + assert score(Card.Face(Suit.Spades(), Face.King())) == 10 + assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 From eae64b4528efe42e6193c0fa56105b61ed6f7577 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 09:16:36 +0100 Subject: [PATCH 07/39] Fixes for block and pydantic --- expression/collections/block.py | 56 +++-- expression/core/builder.py | 7 +- expression/core/option.py | 360 +------------------------------- expression/core/result.py | 8 +- expression/core/union.py | 1 - tests/test_block.py | 9 +- tests/test_option.py | 2 - tests/test_result.py | 5 +- 8 files changed, 42 insertions(+), 406 deletions(-) diff --git a/expression/collections/block.py b/expression/collections/block.py index 2c18f037..35d399ca 100644 --- a/expression/collections/block.py +++ b/expression/collections/block.py @@ -23,7 +23,10 @@ import functools import itertools from collections.abc import Callable, Collection, Iterable, Iterator -from typing import Any, ClassVar, Literal, TypeVar, cast, overload +from typing import Any, Literal, Sequence, TypeVar, get_args, overload + +from pydantic import GetCoreSchemaHandler +from pydantic_core import CoreSchema, core_schema from expression.core import ( Nothing, @@ -35,7 +38,7 @@ curry_flip, pipe, ) -from expression.core.typing import GenericValidator, ModelField, SupportsValidation +from expression.core.typing import SupportsValidation from . import seq @@ -52,29 +55,6 @@ _T4 = TypeVar("_T4") -def _validate(value: Any, field: ModelField) -> Block[Any]: - if isinstance(value, Block): - return cast(Block[Any], value) - - if not isinstance(value, list): - raise ValueError("not a list") - - value_ = cast(list[Any], value) - - if field.sub_fields: - sub_field = field.sub_fields[0] - - value__: list[Any] = [] - for item in value_: - val, error = sub_field.validate(item, {}, loc="Block") - if error: - raise ValueError(str(error)) - value__.append(val) - value_ = value__ - - return Block(value_) - - class Block( Collection[_TSource], # Sequence breaks pydantic PipeMixin, @@ -99,8 +79,6 @@ class Block( __match_args__ = ("_value",) - __validators__: ClassVar = [_validate] - def __init__(self, value: Iterable[_TSource] = ()) -> None: # Use composition instead of inheritance since generic tuples # are not suppored by mypy. @@ -473,7 +451,7 @@ def dict(self) -> list[_TSource]: """Returns a json serializable representation of the list.""" def to_obj(value: Any) -> Any: - attr = getattr(value, "dict", None) or getattr(value, "dict", None) + attr = getattr(value, "model_dump", None) or getattr(value, "dict", None) if attr and callable(attr): value = attr() return value @@ -563,8 +541,24 @@ def __repr__(self) -> str: return str(self) @classmethod - def __get_validators__(cls) -> Iterator[GenericValidator[Block[_TSource]]]: - yield from cls.__validators__ + def __get_pydantic_core_schema__(cls, source: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: + instance_schema = core_schema.is_instance_schema(cls) + + args = get_args(source) + if args: + # replace the type and rely on Pydantic to generate the right schema + # for `Sequence` + sequence_t_schema = handler.generate_schema(Sequence[args[0]]) + else: + sequence_t_schema = handler.generate_schema(Sequence) + + non_instance_schema = core_schema.no_info_after_validator_function(Block, sequence_t_schema) + python_schema = core_schema.union_schema([instance_schema, non_instance_schema]) + return core_schema.json_or_python_schema( + json_schema=non_instance_schema, + python_schema=python_schema, + serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.dict()), + ) @curry_flip(1) @@ -783,7 +777,7 @@ def starmap(mapper: Callable[[_T1, _T2, _T3], _TResult]) -> Callable[[Block[tupl @overload def starmap( - mapper: Callable[[_T1, _T2, _T3, _T4], _TResult] + mapper: Callable[[_T1, _T2, _T3, _T4], _TResult], ) -> Callable[[Block[tuple[_T1, _T2, _T3, _T4]]], Block[_TResult]]: ... diff --git a/expression/core/builder.py b/expression/core/builder.py index d2afd71a..7fe7417f 100644 --- a/expression/core/builder.py +++ b/expression/core/builder.py @@ -58,7 +58,9 @@ def _send( # Effect errors (Nothing, Error, etc) short circuits the processing so we # set `done` to `True` here. done.append(True) - return self.return_from(cast("_TOuter", error)) + # get value from exception + value = error.args[0] + return self.return_from(cast("_TOuter", value)) except StopIteration as ex: done.append(True) # Return of a value in the generator produces StopIteration with a value @@ -127,6 +129,3 @@ def binder(value: Any) -> _TOuter: return self.run(result) return wrapper - - -__all__ = ["Builder"] diff --git a/expression/core/option.py b/expression/core/option.py index 05af1ec4..dff02750 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -235,11 +235,11 @@ def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TErr case _: return Result[_TSource, _TError].Error(error()) - def model_dump(self) -> _TSource | None: + def dict(self) -> _TSource | None: """Returns a json string representation of the option.""" match self: case Option(tag="some", some=value): - attr = getattr(value, "model_dump", None) + attr = getattr(value, "model_dump", None) or getattr(value, "dict", None) if attr and callable(attr): value = attr() @@ -293,7 +293,6 @@ def __hash__(self) -> int: @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: - print("Some:__get_pydantic_core_schema__", source_type, handler) origin = get_origin(source_type) if origin is None: # used as `x: Owner` without params origin = source_type @@ -305,13 +304,11 @@ def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHa none_schema = handler.generate_schema(None) def validate_some(v: Any, handler: ValidatorFunctionWrapHandler) -> Option[Any]: - print("Some:validate", v, handler) value = handler(v) return Some(value) def validate_none(v: Any, handler: ValidatorFunctionWrapHandler) -> Option[Any]: - print("None:validate", v, handler) - value = handler(v) + _ = handler(v) return Nothing python_schema = core_schema.union_schema( @@ -346,357 +343,10 @@ def validate_none(v: Any, handler: ValidatorFunctionWrapHandler) -> Option[Any]: ] ), python_schema=python_schema, - serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.model_dump()), + serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.dict()), ) -# class Some(BaseOption[_TSource]): -# """The Some option case class.""" - -# __match_args__ = ("value",) - -# def __init__(self, value: _TSource) -> None: -# self._value = value - -# def default_value(self, value: _TSource) -> _TSource: -# """Get value or default value. - -# Gets the value of the option if the option is Some, otherwise -# returns the specified default value. -# """ -# return self._value - -# def default_with(self, getter: Callable[[], _TSource]) -> _TSource: -# """Get with default value. - -# Gets the value of the option if the option is Some, otherwise -# returns the value produced by the getter -# """ -# return self._value - -# def is_some(self) -> bool: -# """Returns `True`.""" -# return True - -# def is_none(self) -> bool: -# """Returns `False`.""" -# return False - -# def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: -# return Some(mapper(self._value)) - -# def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: -# if isinstance(other, Some): -# return Some(mapper(self._value, other.value)) -# return Nothing - -# def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: -# """Bind option. - -# Applies and returns the result of the mapper if the value is -# `Some`. If the value is `Nothing` then `Nothing` is returned. - -# Args: -# mapper: A function that takes the value of type TSource from -# an option and transforms it into an option containing a -# value of type TResult. - -# Returns: -# An option of the output type of the mapper. -# """ -# return mapper(self._value) - -# def or_else(self, if_none: Option[_TSource]) -> Option[_TSource]: -# """Returns `self`.""" -# return self - -# def or_else_with(self, if_none: Callable[[], Option[_TSource]]) -> Option[_TSource]: -# """Returns `self`.""" -# return self - -# def filter(self, predicate: Callable[[_TSource], bool]) -> Option[_TSource]: -# """Filter option. - -# Returns the input if the predicate evaluates to true, -# otherwise returns `Nothing`. -# """ -# return self if predicate(self._value) else Nothing - -# def to_list(self) -> list[_TSource]: -# return [self._value] - -# def to_seq(self) -> Seq[_TSource]: -# # deferred import to avoid circular dependencies -# from expression.collections.seq import Seq - -# return Seq.of(self._value) - -# def to_optional(self) -> _TSource | None: -# """Convert option to an optional.""" -# return self._value - -# def to_result(self, error: _TError) -> Result[_TSource, _TError]: -# """Convert option to a result.""" -# from expression.core.result import Ok - -# return Ok(self._value) - -# def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TError]: -# """Convert option to a result.""" -# from expression.core.result import Ok - -# return Ok(self._value) - -# def dict(self) -> _TSource: -# attr = getattr(self._value, "dict", None) or getattr(self._value, "dict", None) -# if attr and callable(attr): -# value = attr() -# else: -# value = self._value - -# return value - -# @property -# def value(self) -> _TSource: -# """Returns the value wrapped by the option. - -# A `ValueError` is raised if the option is `Nothing`. -# """ -# return self._value - -# def __lt__(self, other: Any) -> bool: -# if isinstance(other, Some): -# return self._value < other._value # type: ignore -# return False - -# def __eq__(self, o: Any) -> bool: -# if isinstance(o, Some): -# return self._value == o._value # type: ignore -# return False - -# def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: -# return (yield self._value) - -# def __str__(self) -> str: -# return f"Some {self._value}" - -# def __hash__(self) -> int: -# return hash(self._value) - -# @classmethod -# def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: -# print("Some:__get_pydantic_core_schema__", source_type, handler) -# origin = get_origin(source_type) -# if origin is None: # used as `x: Owner` without params -# origin = source_type -# item_tp = Any -# else: -# item_tp = get_args(source_type)[0] - -# value_schema = handler.generate_schema(item_tp) - -# def validate(v: Any, handler: ValidatorFunctionWrapHandler) -> Some[Any]: -# value = handler(v) -# return Some(value) - -# python_schema = core_schema.union_schema( -# [ -# core_schema.is_instance_schema(Some), -# core_schema.chain_schema( -# [ -# # Ensure the value is an instance of _T -# core_schema.is_instance_schema(item_tp), -# # Use the value_schema to validate `values` -# core_schema.no_info_wrap_validator_function(validate, value_schema), -# ] -# ), -# ] -# ) - -# return core_schema.json_or_python_schema( -# json_schema=core_schema.chain_schema( -# [ -# core_schema.any_schema(), -# # after validating the json data convert it to python -# core_schema.no_info_before_validator_function( -# lambda data: Some(data), -# python_schema, -# ), -# ] -# ), -# python_schema=python_schema, -# serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.value), -# ) - - -# class Nothing_(BaseOption[_TSource], EffectError): -# """The None option case class. - -# Do not use. Use the singleton `Nothing` instead. Since Nothing is a -# singleton it can be tested e.g using `is`: -# >>> if xs is Nothing: -# ... return True -# """ - -# def default_value(self, value: _TSource) -> _TSource: -# """Get value or default value. - -# Gets the value of the option if the option is Some, otherwise -# returns the specified default value. -# """ -# return value - -# def default_with(self, getter: Callable[[], _TSource]) -> _TSource: -# """Get with default value. - -# Gets the value of the option if the option is Some, otherwise -# returns the value produced by the getter -# """ -# return getter() - -# def is_some(self) -> bool: -# """Returns `False`.""" -# return False - -# def is_none(self) -> bool: -# """Returns `True`.""" -# return True - -# def map(self, mapper: Callable[[_TSource], _TResult]) -> Option[_TResult]: -# return Nothing - -# def map2(self, mapper: Callable[[_TSource, _T2], _TResult], other: Option[_T2]) -> Option[_TResult]: -# return Nothing - -# def bind(self, mapper: Callable[[_TSource], Option[_TResult]]) -> Option[_TResult]: -# """Bind option. - -# Applies and returns the result of the mapper if the value is -# `Some`. If the value is `Nothing` then `Nothing` is returned. - -# Args: -# mapper: A function that takes the value of type TSource from -# an option and transforms it into an option containing a -# value of type TResult. - -# Returns: -# An option of the output type of the mapper. -# """ -# return Nothing - -# def or_else(self, if_none: Option[_TSource]) -> Option[_TSource]: -# """Returns `if_none`.""" -# return if_none - -# def or_else_with(self, if_none: Callable[[], Option[_TSource]]) -> Option[_TSource]: -# """Evaluates `if_none` and returns the result.""" -# return if_none() - -# def filter(self, predicate: Callable[[_TSource], bool]) -> Option[_TSource]: -# return Nothing - -# def to_list(self) -> list[_TSource]: -# return [] - -# def to_seq(self) -> Seq[_TSource]: -# # deferred import to avoid circular dependencies -# from expression.collections.seq import Seq - -# return Seq() - -# def to_optional(self) -> _TSource | None: -# """Convert option to an optional.""" -# return None - -# def to_result(self, error: _TError) -> Result[_TSource, _TError]: -# """Convert option to a result.""" -# from expression.core.result import Error - -# return Error(error) - -# def to_result_with(self, error: Callable[[], _TError]) -> Result[_TSource, _TError]: -# """Convert option to a result.""" -# from expression.core.result import Error - -# return Error(error()) - -# def dict(self) -> builtins.dict[str, Any]: -# return {} # Pydantic cannot handle None or other types than Optional - -# @property -# def value(self) -> _TSource: -# """Returns the value wrapped by the option. - -# A `ValueError` is raised if the option is `Nothing`. -# """ -# raise ValueError("There is no value.") - -# def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: -# """Return iterator for the `Nothing` case. - -# We basically want to return nothing, but we have to return -# something to signal fail. -# """ -# raise Nothing -# while False: -# yield - -# def __lt__(self, other: Any) -> bool: -# return True - -# def __eq__(self, o: Any) -> bool: -# if o is Nothing: -# return True -# return False - -# def __str__(self): -# return "Nothing" - -# def __hash__(self) -> int: -# return 0 - -# @classmethod -# def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: -# print("Nothing:__get_pydantic_core_schema__", source_type, handler) -# value_schema = handler.generate_schema(None) - -# def validate(v: None, handler: ValidatorFunctionWrapHandler) -> Nothing_[Any]: -# print("Nothing_:val_item, nothing", v, handler) -# v = handler(v) -# print("Nothing_:val_item, value:", v) -# return Nothing - -# python_schema = core_schema.union_schema( -# [ -# core_schema.is_instance_schema(Nothing_), -# core_schema.chain_schema( -# [ -# # Ensure the value is an instance of Owner -# # core_schema.is_instance_schema(None), -# # Use the item_schema to validate `items` -# core_schema.no_info_wrap_validator_function(validate, value_schema), -# ] -# ), -# ] -# ) - -# return core_schema.json_or_python_schema( -# # for JSON accept null object -# json_schema=core_schema.chain_schema( -# [ -# core_schema.any_schema(), -# # after validating the json data convert it to python -# core_schema.no_info_before_validator_function( -# lambda data: Some(data), -# python_schema, -# ), -# ] -# ), -# python_schema=python_schema, -# serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: None), -# ) - - # # The singleton None class. We use the name 'Nothing' here instead of `None` to # # avoid conflicts with the builtin `None` value in Python. # TODO: also allow None here? @@ -851,7 +501,7 @@ def to_result_with(value: Option[_TSource], error: Callable[[], _TError]) -> Res def model_dump(value: Option[_TSource]) -> _TSource | builtins.dict[Any, Any] | None: - return value.model_dump() + return value.dict() def default_arg(value: Option[_TSource], default_value: _TSource) -> _TSource: diff --git a/expression/core/result.py b/expression/core/result.py index 7b15a332..9b6e9fb7 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -159,16 +159,16 @@ def is_ok(self) -> bool: case _: return False - def model_dump(self) -> builtins.dict[str, _TSource | _TError]: + def dict(self) -> builtins.dict[str, _TSource | _TError]: """Return a json serializable representation of the result.""" match self: case Result(tag="ok", ok=value): - attr = getattr(value, "model_dump", None) + attr = getattr(value, "model_dump", None) or getattr(value, "dict", None) if attr and callable(attr): value = attr() return {"ok": value} case Result(error=error): - attr = getattr(error, "model_dump", None) + attr = getattr(error, "model_dump", None) or getattr(error, "dict", None) if attr and callable(attr): error = attr() return {"error": error} @@ -369,7 +369,7 @@ def bind( def dict(source: Result[_TSource, _TError]) -> builtins.dict[str, _TSource | _TError]: - return source.model_dump() + return source.dict() def is_ok(result: Result[_TSource, _TError]) -> TypeGuard[Result[_TSource, _TError]]: diff --git a/expression/core/union.py b/expression/core/union.py index 47a84b34..8b900eb7 100644 --- a/expression/core/union.py +++ b/expression/core/union.py @@ -31,7 +31,6 @@ def __init__(self: Any, *args: Any, **kwargs: Any) -> None: # Enables the use of dataclasses.asdict union_fields = dict((f.name, f) for f in fields_ if f.name in [name, "tag"]) object.__setattr__(self, "__dataclass_fields__", union_fields) # type: ignore - # print("original_init: ", original_init) original_init(self) def __repr__(self: Any) -> str: diff --git a/tests/test_block.py b/tests/test_block.py index ff60d1f3..dacc97ff 100644 --- a/tests/test_block.py +++ b/tests/test_block.py @@ -412,13 +412,10 @@ class Model(BaseModel): two: Block[str] = block.empty three: Block[float] = block.empty - class Config: - json_encoders: Dict[Type[Any], Callable[[Any], List[Any]]] = {Block: block.dict} - def test_parse_block_works(): obj = dict(one=[1, 2, 3], two=[]) - model = Model.parse_obj(obj) + model = Model.model_validate(obj) assert isinstance(model.one, Block) assert model.one == Block([1, 2, 3]) assert model.two == Block.empty() @@ -430,10 +427,10 @@ def test_serialize_block_works(): model = Model(one=Block([1, 2, 3]), two=Block.empty()) # act - json = model.json() + json = model.model_dump_json() # assert - model_ = Model.parse_raw(json) + model_ = Model.model_validate_json(json) assert model_.one == Block([1, 2, 3]) assert model_.two == Block.empty() assert model_.three == block.empty diff --git a/tests/test_option.py b/tests/test_option.py index b0e7018e..45c24974 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -560,8 +560,6 @@ def test_parse_option_works(): obj = dict(one=10, two=None) model = Model.model_validate(obj) - print("model: ", model) - assert model.one.is_some() assert model.one.value == 10 assert model.two == Nothing diff --git a/tests/test_result.py b/tests/test_result.py index e95038a9..8fffd50c 100644 --- a/tests/test_result.py +++ b/tests/test_result.py @@ -381,14 +381,14 @@ def test_parse_block_works(): def test_ok_to_dict_works(): result = Ok(10) - obj = result.model_dump() + obj = result.dict() assert obj == dict(ok=10) def test_error_to_dict_works(): error = MyError(message="got error") result = Error(error) - obj = result.model_dump() + obj = result.dict() assert obj == dict(error=dict(message="got error")) @@ -423,7 +423,6 @@ def test_error_from_dict_works(): def test_model_to_json_works(): model = Model(one=Ok(10)) obj = model.model_dump_json() - print(f"obj: {obj}") assert obj == '{"one":{"ok":10},"two":{"error":{"message":"error"}},"three":{"error":{"message":"error"}}}' def test_error_default_value(): From 9bba6f00b7e321abb7158a5dccc4ffbd9532af86 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 09:41:33 +0100 Subject: [PATCH 08/39] Cleanup --- expression/__init__.py | 1 - expression/collections/array.py | 8 +++++--- expression/collections/block.py | 18 +++++++++--------- expression/core/__init__.py | 1 - expression/core/misc.py | 5 ++++- expression/core/option.py | 8 ++++---- expression/core/pipe.py | 2 +- expression/core/try_.py | 3 +-- expression/core/typing.py | 24 +----------------------- expression/core/union.py | 10 +++++----- expression/extra/parser.py | 2 +- tests/test_block.py | 2 +- tests/test_option.py | 2 +- tests/test_try.py | 3 --- tests/test_union.py | 4 ++-- 15 files changed, 35 insertions(+), 58 deletions(-) diff --git a/expression/__init__.py b/expression/__init__.py index 3bbe7941..49571004 100644 --- a/expression/__init__.py +++ b/expression/__init__.py @@ -90,7 +90,6 @@ "curry_flipped", "default_arg", "downcast", - "effect", "EffectError", "Error", "Failure", diff --git a/expression/collections/array.py b/expression/collections/array.py index 629b893e..95606b47 100644 --- a/expression/collections/array.py +++ b/expression/collections/array.py @@ -580,9 +580,11 @@ def of_seq(xs: Iterable[_TSource]) -> TypedArray[_TSource]: def of_option(option: Option[_TSource]) -> TypedArray[_TSource]: - if isinstance(option, Some): - return singleton(option.value) - return empty() + match option: + case Option(tag="some", some=value): + return singleton(value) + case _: + return empty() def singleton(value: _TSource) -> TypedArray[_TSource]: diff --git a/expression/collections/block.py b/expression/collections/block.py index 35d399ca..d09fa227 100644 --- a/expression/collections/block.py +++ b/expression/collections/block.py @@ -22,11 +22,11 @@ import builtins import functools import itertools -from collections.abc import Callable, Collection, Iterable, Iterator -from typing import Any, Literal, Sequence, TypeVar, get_args, overload +from collections.abc import Callable, Collection, Iterable, Iterator, Sequence +from typing import Any, Literal, TypeVar, get_args, overload from pydantic import GetCoreSchemaHandler -from pydantic_core import CoreSchema, core_schema +from pydantic_core import core_schema from expression.core import ( Nothing, @@ -38,7 +38,6 @@ curry_flip, pipe, ) -from expression.core.typing import SupportsValidation from . import seq @@ -58,7 +57,6 @@ class Block( Collection[_TSource], # Sequence breaks pydantic PipeMixin, - SupportsValidation["Block[_TSource]"], ): """Immutable list type. @@ -548,7 +546,7 @@ def __get_pydantic_core_schema__(cls, source: Any, handler: GetCoreSchemaHandler if args: # replace the type and rely on Pydantic to generate the right schema # for `Sequence` - sequence_t_schema = handler.generate_schema(Sequence[args[0]]) + sequence_t_schema = handler.generate_schema(Sequence[args[0]]) # type: ignore else: sequence_t_schema = handler.generate_schema(Sequence) @@ -841,9 +839,11 @@ def of_seq(xs: Iterable[_TSource]) -> Block[_TSource]: def of_option(option: Option[_TSource]) -> Block[_TSource]: - if isinstance(option, Some): - return singleton(option.value) - return empty + match option: + case Option(tag="some", some=value): + return singleton(value) + case _: + return empty @curry_flip(1) diff --git a/expression/core/__init__.py b/expression/core/__init__.py index 351e41d8..0383cbf2 100644 --- a/expression/core/__init__.py +++ b/expression/core/__init__.py @@ -64,7 +64,6 @@ "is_some", "MailboxProcessor", "Nothing", - "Nothing_", "Ok", "Option", "option", diff --git a/expression/core/misc.py b/expression/core/misc.py index 1aad173c..35ab76d5 100644 --- a/expression/core/misc.py +++ b/expression/core/misc.py @@ -1,9 +1,12 @@ from collections.abc import Callable from typing import Any, TypeVar +from typing_extensions import TypeVarTuple, Unpack + _A = TypeVar("_A") _B = TypeVar("_B") +_P = TypeVarTuple("_P") _TSource = TypeVar("_TSource") _TResult = TypeVar("_TResult") @@ -16,7 +19,7 @@ def identity(value: _A) -> _A: return value -def starid(*value: Any) -> tuple[Any, ...]: +def starid(*value: Unpack[_P]) -> tuple[Unpack[_P]]: return value diff --git a/expression/core/option.py b/expression/core/option.py index dff02750..38135f45 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -9,7 +9,7 @@ import builtins from collections.abc import Callable, Generator, Iterable -from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, cast, get_args, get_origin +from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, get_args, get_origin from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler from pydantic_core import CoreSchema, core_schema @@ -203,7 +203,7 @@ def of_optional(cls, value: _TSource | None) -> Option[_TSource]: return of_optional(value) @classmethod - def of_result(cls, result: Result[_TSource, _TError]) -> Option[_TSource]: + def of_result(cls, result: Result[_TSource, Any]) -> Option[_TSource]: """Convert result to an option.""" return of_result(result) @@ -260,7 +260,7 @@ def value(self) -> _TSource: raise ValueError("There is no value.") def __eq__(self, o: Any) -> bool: - return isinstance(o, Option) and self.tag == o.tag and getattr(self, self.tag) == getattr(o, self.tag) + return isinstance(o, Option) and self.tag == o.tag and getattr(self, self.tag) == getattr(o, self.tag) # type: ignore def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: match self: @@ -482,7 +482,7 @@ def of_obj(value: Any) -> Option[Any]: return of_optional(value) -def of_result(result: Result[_TSource, _TError]) -> Option[_TSource]: +def of_result(result: Result[_TSource, Any]) -> Option[_TSource]: from expression.core.result import Result match result: diff --git a/expression/core/pipe.py b/expression/core/pipe.py index a3dfef18..50e3d8f7 100644 --- a/expression/core/pipe.py +++ b/expression/core/pipe.py @@ -187,7 +187,7 @@ def pipe3(__values: Any, *fns: Any) -> Any: return pipe(fns[0](__values[0])(__values[1])(__values[2]), *fns[1:]) if fns else __values -def starpipe(args: Any, *fns: Callable[..., Any]): +def starpipe(args: tuple[Any, ...], *fns: Callable[..., Any]): """Functional pipe_n (`||>`, `||>`, `|||>`, etc). Allows the use of function arguments on the left side of the diff --git a/expression/core/try_.py b/expression/core/try_.py index 53abfc6d..72459d3c 100644 --- a/expression/core/try_.py +++ b/expression/core/try_.py @@ -8,8 +8,7 @@ from typing import Any, TypeVar -from .result import Error, Ok, Result -from .union import case +from .result import Result _TSource = TypeVar("_TSource") diff --git a/expression/core/typing.py b/expression/core/typing.py index a1d8418d..e1cfe46b 100644 --- a/expression/core/typing.py +++ b/expression/core/typing.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import abstractmethod -from collections.abc import Callable, Iterable, Iterator +from collections.abc import Iterable from typing import Any, Protocol, TypeVar, cast, get_origin @@ -55,24 +55,6 @@ def validate(self, value: Any, values: dict[str, str], loc: str) -> tuple[Any, A ... -Validator = Callable[[Any], _T] -GenericValidator = Callable[[Any, ModelField], _T] - - -class SupportsValidation(Protocol[_T_co]): - """A type that supports valication. - - A type that implements __get_validators__ to be used with pydantic. - """ - - @classmethod - def __get_validators__( - cls, - ) -> Iterator[Validator[_T_co] | GenericValidator[_T_co]]: - """Yield an iterator of validators.""" - ... - - def upcast(type: type[_Base], expr: _Base) -> _Base: """Upcast expression from a `Derived` to `Base`. @@ -116,12 +98,8 @@ def try_downcast(type_: type[_Derived], expr: Any) -> _Derived | None: "downcast", "upcast", "try_downcast", - "GenericValidator", "SupportsLessThan", "SupportsSum", "SupportsGreaterThan", - "SupportsValidation", "SupportsMatch", - "Validator", - "GenericValidator", ] diff --git a/expression/core/union.py b/expression/core/union.py index 8b900eb7..1724bd1d 100644 --- a/expression/core/union.py +++ b/expression/core/union.py @@ -67,12 +67,12 @@ def __deepcopy__(self: Any, memo: Any) -> Any: mapping = {self.tag: value} return cls(**mapping) - cls.__eq__ = __eq__ + cls.__eq__ = __eq__ # type: ignore cls.__init__ = __init__ # type: ignore - cls.__repr__ = __repr__ - cls.__hash__ = __hash__ - cls.__setattr__ = __setattr__ - cls.__delattr__ = __delattr__ + cls.__repr__ = __repr__ # type: ignore + cls.__hash__ = __hash__ # type: ignore + cls.__setattr__ = __setattr__ # type: ignore + cls.__delattr__ = __delattr__ # type: ignore cls.__match_args__ = tuple(field_names) # type: ignore # We need to handle copy and deepcopy ourselves because they are needed by Pydantic diff --git a/expression/extra/parser.py b/expression/extra/parser.py index 8e2fc41b..cf23880a 100644 --- a/expression/extra/parser.py +++ b/expression/extra/parser.py @@ -228,7 +228,7 @@ def run(input: Remaining) -> ParseResult[_A]: def fail(error: str) -> Parser[Any]: def run(input: Remaining) -> ParseResult[Any]: - return Error[tuple[Any, Remaining], str](error) + return Error(error) return Parser(run, f'fail("{error}")') diff --git a/tests/test_block.py b/tests/test_block.py index dacc97ff..fb287c42 100644 --- a/tests/test_block.py +++ b/tests/test_block.py @@ -1,6 +1,6 @@ import functools from builtins import list as list -from typing import Any, Callable, Dict, List, Tuple, Type +from typing import Any, Callable, List, Tuple from hypothesis import given # type: ignore from hypothesis import strategies as st diff --git a/tests/test_option.py b/tests/test_option.py index 45c24974..567c35b0 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, Dict, Generator, Type +from typing import Any, Callable, Generator import pytest from hypothesis import given # type: ignore diff --git a/tests/test_try.py b/tests/test_try.py index 4af576a7..cef028c2 100644 --- a/tests/test_try.py +++ b/tests/test_try.py @@ -1,8 +1,5 @@ -import pytest - from expression import Failure, Success, Try -from .utils import CustomException def test_can_create_success(): diff --git a/tests/test_union.py b/tests/test_union.py index 1ece554f..ae615c53 100644 --- a/tests/test_union.py +++ b/tests/test_union.py @@ -38,7 +38,7 @@ def test_union_shape_circle_pattern_matching_works(): shape = Shape(circle=Circle(10.0)) match shape: - case Shape(tag="rectangle", rectangle=(w, h)): + case Shape(tag="rectangle", rectangle=(_, _)): raise AssertionError("Should not match") case Shape(tag="circle", circle=Circle(radius=r)): assert r == 10.0 @@ -50,7 +50,7 @@ def test_shape_rectangle_pattern_matching_works(): shape = Shape(rectangle=(10.0, 20.0)) match shape: - case Shape(tag="circle", circle=Circle(radius=r)): + case Shape(tag="circle", circle=Circle(radius=_)): raise AssertionError("Should not match") case Shape(tag="rectangle", rectangle=(w, h)): assert w == 10.0 From e2aacbd95aeea67329618592cdc6039d57eab068 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 09:47:21 +0100 Subject: [PATCH 09/39] Fix effect import --- expression/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/expression/__init__.py b/expression/__init__.py index 49571004..44e1c2ba 100644 --- a/expression/__init__.py +++ b/expression/__init__.py @@ -9,7 +9,7 @@ GitHub: https://github.com/cognitedata/Expression """ -from . import collections, core # , effect +from . import collections, core, effect from ._version import __version__ from .core import ( AsyncReplyChannel, @@ -90,6 +90,7 @@ "curry_flipped", "default_arg", "downcast", + "effect", "EffectError", "Error", "Failure", From aab007dedf2f90a1b181215dcb54ea841c8884cb Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 10:03:53 +0100 Subject: [PATCH 10/39] Bump python version to 3.11+ --- .github/workflows/python-package.yml | 2 +- .github/workflows/python-publish.yml | 2 +- .pre-commit-config.yaml | 2 +- expression/collections/array.py | 1 - expression/core/result.py | 13 +- poetry.lock | 249 ++++++++++++--------------- pyproject.toml | 4 +- 7 files changed, 113 insertions(+), 160 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 7f3fc929..ece5e2e5 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10"] + python-version: ["3.11", "3.12"] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index d7b910d3..5db627b8 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -20,7 +20,7 @@ jobs: - name: Setup Python Env uses: actions/setup-python@v4 with: - python-version: '3.9' + python-version: '3.11' - name: Install dependencies run: pip install poetry dunamai diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 52ee9944..c57e2f75 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: language: node pass_filenames: false types: [python] - additional_dependencies: ["pyright@1.1.334"] + additional_dependencies: ["pyright@1.1.344"] repo: local - hooks: - id: jb-to-sphinx diff --git a/expression/collections/array.py b/expression/collections/array.py index 95606b47..a37e7f7a 100644 --- a/expression/collections/array.py +++ b/expression/collections/array.py @@ -230,7 +230,6 @@ def is_empty(self) -> bool: """Return `True` if list is empty.""" return not self.value - @property @classmethod def empty(cls) -> TypedArray[Any]: """Returns empty array.""" diff --git a/expression/core/result.py b/expression/core/result.py index 9b6e9fb7..bd6d1580 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -287,7 +287,7 @@ def validate_error(v: Any, handler: ValidatorFunctionWrapHandler) -> Result[_TSo return core_schema.json_or_python_schema( json_schema=json_schema, python_schema=python_schema, - serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.model_dump()), + serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: instance.dict()), ) @@ -299,17 +299,6 @@ def Ok(value: _TSource) -> Result[_TSource, Any]: return Result[_TSource, Any].Ok(value) -# class Ok(Result[_TSource, Any]): -# ok: _TSource = case() -# tag = "ok" - - -# class Error(Result[Any, _TError]): -# error: _TError = case() - -# tag = "error" - - class ResultException(EffectError): """Makes the Error case a valid exception for effect handling. diff --git a/poetry.lock b/poetry.lock index 832a24e8..16d0abb7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -67,21 +67,22 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "attrs" -version = "23.1.0" +version = "23.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] +dev = ["attrs[tests]", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "autoflake" @@ -96,7 +97,6 @@ files = [ [package.dependencies] pyflakes = ">=3.0.0" -tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} [[package]] name = "babel" @@ -167,8 +167,6 @@ mypy-extensions = ">=0.4.3" packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -388,13 +386,13 @@ files = [ [[package]] name = "comm" -version = "0.2.0" +version = "0.2.1" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." optional = false python-versions = ">=3.8" files = [ - {file = "comm-0.2.0-py3-none-any.whl", hash = "sha256:2da8d9ebb8dd7bfc247adaff99f24dce705638a8042b85cb995066793e391001"}, - {file = "comm-0.2.0.tar.gz", hash = "sha256:a517ea2ca28931c7007a7a99c562a0fa5883cfb48963140cf642c41c948498be"}, + {file = "comm-0.2.1-py3-none-any.whl", hash = "sha256:87928485c0dfc0e7976fd89fc1e187023cf587e7c353e4a9b417555b44adf021"}, + {file = "comm-0.2.1.tar.gz", hash = "sha256:0bc91edae1344d39d3661dcbc36937181fdaddb304790458f8b044dbc064b89a"}, ] [package.dependencies] @@ -568,20 +566,6 @@ files = [ [package.dependencies] packaging = ">=20.9" -[[package]] -name = "exceptiongroup" -version = "1.2.0" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, -] - -[package.extras] -test = ["pytest (>=6)"] - [[package]] name = "executing" version = "2.0.1" @@ -726,7 +710,6 @@ files = [ [package.dependencies] attrs = ">=22.2.0" -exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] @@ -846,19 +829,18 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.18.1" +version = "8.19.0" description = "IPython: Productive Interactive Computing" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" files = [ - {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, - {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, + {file = "ipython-8.19.0-py3-none-any.whl", hash = "sha256:2f55d59370f59d0d2b2212109fe0e6035cfea436b1c0e6150ad2244746272ec5"}, + {file = "ipython-8.19.0.tar.gz", hash = "sha256:ac4da4ecf0042fb4e0ce57c60430c2db3c719fa8bdf92f8631d6bd8a5785d1f0"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} @@ -866,20 +848,19 @@ prompt-toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" -typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.23)", "pandas", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] +test = ["pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "isort" @@ -1042,7 +1023,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" @@ -1055,13 +1035,13 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.5.1" +version = "5.7.0" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.5.1-py3-none-any.whl", hash = "sha256:220dfb00c45f0d780ce132bb7976b58263f81a3ada6e90a9b6823785a424f739"}, - {file = "jupyter_core-5.5.1.tar.gz", hash = "sha256:1553311a97ccd12936037f36b9ab4d6ae8ceea6ad2d5c90d94a909e752178e40"}, + {file = "jupyter_core-5.7.0-py3-none-any.whl", hash = "sha256:16eea462f7dad23ba9f86542bdf17f830804e2028eb48d609b6134d91681e983"}, + {file = "jupyter_core-5.7.0.tar.gz", hash = "sha256:cb8d3ed92144d2463a3c5664fdd686a3f0c1442ea45df8babb1c1a9e6333fe03"}, ] [package.dependencies] @@ -1748,13 +1728,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydata-sphinx-theme" -version = "0.14.4" +version = "0.15.1" description = "Bootstrap-based Sphinx theme from the PyData community" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pydata_sphinx_theme-0.14.4-py3-none-any.whl", hash = "sha256:ac15201f4c2e2e7042b0cad8b30251433c1f92be762ddcefdb4ae68811d918d9"}, - {file = "pydata_sphinx_theme-0.14.4.tar.gz", hash = "sha256:f5d7a2cb7a98e35b9b49d3b02cec373ad28958c2ed5c9b1ffe6aff6c56e9de5b"}, + {file = "pydata_sphinx_theme-0.15.1-py3-none-any.whl", hash = "sha256:064efbe96137bd0acab80413759f1db38a42b51e2429b159af75c43a7590320b"}, + {file = "pydata_sphinx_theme-0.15.1.tar.gz", hash = "sha256:4606f7d59765ae06ff7cb5e07dead4286ea2ff2164deeee63922481eddf1083c"}, ] [package.dependencies] @@ -1801,22 +1781,20 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pytest" -version = "7.4.3" +version = "7.4.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] @@ -2042,13 +2020,13 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "referencing" -version = "0.32.0" +version = "0.32.1" description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.32.0-py3-none-any.whl", hash = "sha256:bdcd3efb936f82ff86f993093f6da7435c7de69a3b3a5a06678a6050184bee99"}, - {file = "referencing-0.32.0.tar.gz", hash = "sha256:689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161"}, + {file = "referencing-0.32.1-py3-none-any.whl", hash = "sha256:7e4dc12271d8e15612bfe35792f5ea1c40970dadf8624602e33db2758f7ee554"}, + {file = "referencing-0.32.1.tar.gz", hash = "sha256:3c57da0513e9563eb7e203ebe9bb3a1b509b042016433bd1e45a2853466c3dd3"}, ] [package.dependencies] @@ -2186,28 +2164,28 @@ files = [ [[package]] name = "ruff" -version = "0.1.9" +version = "0.1.11" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e6a212f436122ac73df851f0cf006e0c6612fe6f9c864ed17ebefce0eff6a5fd"}, - {file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:28d920e319783d5303333630dae46ecc80b7ba294aeffedf946a02ac0b7cc3db"}, - {file = "ruff-0.1.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:104aa9b5e12cb755d9dce698ab1b97726b83012487af415a4512fedd38b1459e"}, - {file = "ruff-0.1.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e63bf5a4a91971082a4768a0aba9383c12392d0d6f1e2be2248c1f9054a20da"}, - {file = "ruff-0.1.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d0738917c203246f3e275b37006faa3aa96c828b284ebfe3e99a8cb413c8c4b"}, - {file = "ruff-0.1.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69dac82d63a50df2ab0906d97a01549f814b16bc806deeac4f064ff95c47ddf5"}, - {file = "ruff-0.1.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2aec598fb65084e41a9c5d4b95726173768a62055aafb07b4eff976bac72a592"}, - {file = "ruff-0.1.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:744dfe4b35470fa3820d5fe45758aace6269c578f7ddc43d447868cfe5078bcb"}, - {file = "ruff-0.1.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:479ca4250cab30f9218b2e563adc362bd6ae6343df7c7b5a7865300a5156d5a6"}, - {file = "ruff-0.1.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:aa8344310f1ae79af9ccd6e4b32749e93cddc078f9b5ccd0e45bd76a6d2e8bb6"}, - {file = "ruff-0.1.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:837c739729394df98f342319f5136f33c65286b28b6b70a87c28f59354ec939b"}, - {file = "ruff-0.1.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:e6837202c2859b9f22e43cb01992373c2dbfeae5c0c91ad691a4a2e725392464"}, - {file = "ruff-0.1.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:331aae2cd4a0554667ac683243b151c74bd60e78fb08c3c2a4ac05ee1e606a39"}, - {file = "ruff-0.1.9-py3-none-win32.whl", hash = "sha256:8151425a60878e66f23ad47da39265fc2fad42aed06fb0a01130e967a7a064f4"}, - {file = "ruff-0.1.9-py3-none-win_amd64.whl", hash = "sha256:c497d769164df522fdaf54c6eba93f397342fe4ca2123a2e014a5b8fc7df81c7"}, - {file = "ruff-0.1.9-py3-none-win_arm64.whl", hash = "sha256:0e17f53bcbb4fff8292dfd84cf72d767b5e146f009cccd40c2fad27641f8a7a9"}, - {file = "ruff-0.1.9.tar.gz", hash = "sha256:b041dee2734719ddbb4518f762c982f2e912e7f28b8ee4fe1dee0b15d1b6e800"}, + {file = "ruff-0.1.11-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a7f772696b4cdc0a3b2e527fc3c7ccc41cdcb98f5c80fdd4f2b8c50eb1458196"}, + {file = "ruff-0.1.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:934832f6ed9b34a7d5feea58972635c2039c7a3b434fe5ba2ce015064cb6e955"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea0d3e950e394c4b332bcdd112aa566010a9f9c95814844a7468325290aabfd9"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9bd4025b9c5b429a48280785a2b71d479798a69f5c2919e7d274c5f4b32c3607"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ad00662305dcb1e987f5ec214d31f7d6a062cae3e74c1cbccef15afd96611d"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4b077ce83f47dd6bea1991af08b140e8b8339f0ba8cb9b7a484c30ebab18a23f"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a88efecec23c37b11076fe676e15c6cdb1271a38f2b415e381e87fe4517f18"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b25093dad3b055667730a9b491129c42d45e11cdb7043b702e97125bcec48a1"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231d8fb11b2cc7c0366a326a66dafc6ad449d7fcdbc268497ee47e1334f66f77"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:09c415716884950080921dd6237767e52e227e397e2008e2bed410117679975b"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0f58948c6d212a6b8d41cd59e349751018797ce1727f961c2fa755ad6208ba45"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:190a566c8f766c37074d99640cd9ca3da11d8deae2deae7c9505e68a4a30f740"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6464289bd67b2344d2a5d9158d5eb81025258f169e69a46b741b396ffb0cda95"}, + {file = "ruff-0.1.11-py3-none-win32.whl", hash = "sha256:9b8f397902f92bc2e70fb6bebfa2139008dc72ae5177e66c383fa5426cb0bf2c"}, + {file = "ruff-0.1.11-py3-none-win_amd64.whl", hash = "sha256:eb85ee287b11f901037a6683b2374bb0ec82928c5cbc984f575d0437979c521a"}, + {file = "ruff-0.1.11-py3-none-win_arm64.whl", hash = "sha256:97ce4d752f964ba559c7023a86e5f8e97f026d511e48013987623915431c7ea9"}, + {file = "ruff-0.1.11.tar.gz", hash = "sha256:f9d4d88cb6eeb4dfe20f9f0519bd2eaba8119bde87c3d5065c541dbae2b5a2cb"}, ] [[package]] @@ -2287,7 +2265,6 @@ babel = ">=1.3" colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} docutils = ">=0.14,<0.19" imagesize = "*" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" @@ -2532,7 +2509,6 @@ files = [ [package.dependencies] docutils = ">=0.8" -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} pybtex = ">=0.24" pybtex-docutils = ">=1.0.0" Sphinx = ">=2.1" @@ -2625,65 +2601,65 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.24" +version = "2.0.25" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.24-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f801d85ba4753d4ed97181d003e5d3fa330ac7c4587d131f61d7f968f416862"}, - {file = "SQLAlchemy-2.0.24-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b35c35e3923ade1e7ac44e150dec29f5863513246c8bf85e2d7d313e3832bcfb"}, - {file = "SQLAlchemy-2.0.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d9b3fd5eca3c0b137a5e0e468e24ca544ed8ca4783e0e55341b7ed2807518ee"}, - {file = "SQLAlchemy-2.0.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a6209e689d0ff206c40032b6418e3cfcfc5af044b3f66e381d7f1ae301544b4"}, - {file = "SQLAlchemy-2.0.24-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:37e89d965b52e8b20571b5d44f26e2124b26ab63758bf1b7598a0e38fb2c4005"}, - {file = "SQLAlchemy-2.0.24-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6910eb4ea90c0889f363965cd3c8c45a620ad27b526a7899f0054f6c1b9219e"}, - {file = "SQLAlchemy-2.0.24-cp310-cp310-win32.whl", hash = "sha256:d8e7e8a150e7b548e7ecd6ebb9211c37265991bf2504297d9454e01b58530fc6"}, - {file = "SQLAlchemy-2.0.24-cp310-cp310-win_amd64.whl", hash = "sha256:396f05c552f7fa30a129497c41bef5b4d1423f9af8fe4df0c3dcd38f3e3b9a14"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:adbd67dac4ebf54587198b63cd30c29fd7eafa8c0cab58893d9419414f8efe4b"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a0f611b431b84f55779cbb7157257d87b4a2876b067c77c4f36b15e44ced65e2"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56a0e90a959e18ac5f18c80d0cad9e90cb09322764f536e8a637426afb1cae2f"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6db686a1d9f183c639f7e06a2656af25d4ed438eda581de135d15569f16ace33"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f0cc0b486a56dff72dddae6b6bfa7ff201b0eeac29d4bc6f0e9725dc3c360d71"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a1d4856861ba9e73bac05030cec5852eabfa9ef4af8e56c19d92de80d46fc34"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-win32.whl", hash = "sha256:a3c2753bf4f48b7a6024e5e8a394af49b1b12c817d75d06942cae03d14ff87b3"}, - {file = "SQLAlchemy-2.0.24-cp311-cp311-win_amd64.whl", hash = "sha256:38732884eabc64982a09a846bacf085596ff2371e4e41d20c0734f7e50525d01"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9f992e0f916201731993eab8502912878f02287d9f765ef843677ff118d0e0b1"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2587e108463cc2e5b45a896b2e7cc8659a517038026922a758bde009271aed11"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bb7cedcddffca98c40bb0becd3423e293d1fef442b869da40843d751785beb3"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83fa6df0e035689df89ff77a46bf8738696785d3156c2c61494acdcddc75c69d"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:cc889fda484d54d0b31feec409406267616536d048a450fc46943e152700bb79"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57ef6f2cb8b09a042d0dbeaa46a30f2df5dd1e1eb889ba258b0d5d7d6011b81c"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-win32.whl", hash = "sha256:ea490564435b5b204d8154f0e18387b499ea3cedc1e6af3b3a2ab18291d85aa7"}, - {file = "SQLAlchemy-2.0.24-cp312-cp312-win_amd64.whl", hash = "sha256:ccfd336f96d4c9bbab0309f2a565bf15c468c2d8b2d277a32f89c5940f71fcf9"}, - {file = "SQLAlchemy-2.0.24-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9aaaaa846b10dfbe1bda71079d0e31a7e2cebedda9409fa7dba3dfed1ae803e8"}, - {file = "SQLAlchemy-2.0.24-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95bae3d38f8808d79072da25d5e5a6095f36fe1f9d6c614dd72c59ca8397c7c0"}, - {file = "SQLAlchemy-2.0.24-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a04191a7c8d77e63f6fc1e8336d6c6e93176c0c010833e74410e647f0284f5a1"}, - {file = "SQLAlchemy-2.0.24-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:acc58b7c2e40235712d857fdfc8f2bda9608f4a850d8d9ac0dd1fc80939ca6ac"}, - {file = "SQLAlchemy-2.0.24-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:00d76fe5d7cdb5d84d625ce002ce29fefba0bfd98e212ae66793fed30af73931"}, - {file = "SQLAlchemy-2.0.24-cp37-cp37m-win32.whl", hash = "sha256:29e51f848f843bbd75d74ae64ab1ab06302cb1dccd4549d1f5afe6b4a946edb2"}, - {file = "SQLAlchemy-2.0.24-cp37-cp37m-win_amd64.whl", hash = "sha256:e9d036e343a604db3f5a6c33354018a84a1d3f6dcae3673358b404286204798c"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9bafaa05b19dc07fa191c1966c5e852af516840b0d7b46b7c3303faf1a349bc9"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e69290b921b7833c04206f233d6814c60bee1d135b09f5ae5d39229de9b46cd4"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8398593ccc4440ce6dffcc4f47d9b2d72b9fe7112ac12ea4a44e7d4de364db1"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f073321a79c81e1a009218a21089f61d87ee5fa3c9563f6be94f8b41ff181812"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9036ebfd934813990c5b9f71f297e77ed4963720db7d7ceec5a3fdb7cd2ef6ce"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcf84fe93397a0f67733aa2a38ed4eab9fc6348189fc950e656e1ea198f45668"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-win32.whl", hash = "sha256:6f5e75de91c754365c098ac08c13fdb267577ce954fa239dd49228b573ca88d7"}, - {file = "SQLAlchemy-2.0.24-cp38-cp38-win_amd64.whl", hash = "sha256:9f29c7f0f4b42337ec5a779e166946a9f86d7d56d827e771b69ecbdf426124ac"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:07cc423892f2ceda9ae1daa28c0355757f362ecc7505b1ab1a3d5d8dc1c44ac6"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2a479aa1ab199178ff1956b09ca8a0693e70f9c762875d69292d37049ffd0d8f"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b8d0e8578e7f853f45f4512b5c920f6a546cd4bed44137460b2a56534644205"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17e7e27af178d31b436dda6a596703b02a89ba74a15e2980c35ecd9909eea3a"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1ca7903d5e7db791a355b579c690684fac6304478b68efdc7f2ebdcfe770d8d7"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db09e424d7bb89b6215a184ca93b4f29d7f00ea261b787918a1af74143b98c06"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-win32.whl", hash = "sha256:a5cd7d30e47f87b21362beeb3e86f1b5886e7d9b0294b230dde3d3f4a1591375"}, - {file = "SQLAlchemy-2.0.24-cp39-cp39-win_amd64.whl", hash = "sha256:7ae5d44517fe81079ce75cf10f96978284a6db2642c5932a69c82dbae09f009a"}, - {file = "SQLAlchemy-2.0.24-py3-none-any.whl", hash = "sha256:8f358f5cfce04417b6ff738748ca4806fe3d3ae8040fb4e6a0c9a6973ccf9b6e"}, - {file = "SQLAlchemy-2.0.24.tar.gz", hash = "sha256:6db97656fd3fe3f7e5b077f12fa6adb5feb6e0b567a3e99f47ecf5f7ea0a09e3"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-win32.whl", hash = "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669"}, + {file = "SQLAlchemy-2.0.25-cp310-cp310-win_amd64.whl", hash = "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-win32.whl", hash = "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c"}, + {file = "SQLAlchemy-2.0.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-win32.whl", hash = "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2"}, + {file = "SQLAlchemy-2.0.25-cp312-cp312-win_amd64.whl", hash = "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5"}, + {file = "SQLAlchemy-2.0.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0"}, + {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7"}, + {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62"}, + {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9"}, + {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23"}, + {file = "SQLAlchemy-2.0.25-cp37-cp37m-win32.whl", hash = "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4"}, + {file = "SQLAlchemy-2.0.25-cp37-cp37m-win_amd64.whl", hash = "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-win32.whl", hash = "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e"}, + {file = "SQLAlchemy-2.0.25-cp38-cp38-win_amd64.whl", hash = "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-win32.whl", hash = "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24"}, + {file = "SQLAlchemy-2.0.25-cp39-cp39-win_amd64.whl", hash = "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7"}, + {file = "SQLAlchemy-2.0.25-py3-none-any.whl", hash = "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3"}, + {file = "SQLAlchemy-2.0.25.tar.gz", hash = "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08"}, ] [package.dependencies] greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} -typing-extensions = ">=4.2.0" +typing-extensions = ">=4.6.0" [package.extras] aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] @@ -2743,17 +2719,6 @@ files = [ [package.extras] widechars = ["wcwidth"] -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - [[package]] name = "tornado" version = "6.4" @@ -2776,13 +2741,13 @@ files = [ [[package]] name = "traitlets" -version = "5.14.0" +version = "5.14.1" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.14.0-py3-none-any.whl", hash = "sha256:f14949d23829023013c47df20b4a76ccd1a85effb786dc060f34de7948361b33"}, - {file = "traitlets-5.14.0.tar.gz", hash = "sha256:fcdaa8ac49c04dfa0ed3ee3384ef6dfdb5d6f3741502be247279407679296772"}, + {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, + {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, ] [package.extras] @@ -2852,13 +2817,13 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "wcwidth" -version = "0.2.12" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.12-py2.py3-none-any.whl", hash = "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c"}, - {file = "wcwidth-0.2.12.tar.gz", hash = "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02"}, + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, ] [[package]] @@ -2892,5 +2857,5 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" -python-versions = ">= 3.9, < 4" -content-hash = "3a9a88c923c0c2acbff96c969831444e3c556d92cc91ba45e790e9f782ad3ea7" +python-versions = ">= 3.11, < 4" +content-hash = "e10e9d29c1657d108742bbf95475a75f459854afc813a21bd1faf38f37ebda8e" diff --git a/pyproject.toml b/pyproject.toml index 1c1d5969..9e90c968 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ ] [tool.poetry.dependencies] -python = ">= 3.9, < 4" +python = ">= 3.11, < 4" typing-extensions = "^4.1.1" [tool.poetry.dev-dependencies] @@ -42,7 +42,7 @@ sphinx-autodoc-typehints = "^1.17.0" pydantic = "^2.5.0" [tool.poetry.group.dev.dependencies] -ruff = "^0.1.3" +ruff = "^0.1.11" [tool.black] line-length = 88 From b288bb27e39bcbc841ebd12885e66d61a1613326 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 10:09:08 +0100 Subject: [PATCH 11/39] Fix pattern match --- tests/test_union.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_union.py b/tests/test_union.py index ae615c53..8772b699 100644 --- a/tests/test_union.py +++ b/tests/test_union.py @@ -177,7 +177,7 @@ class Email: def test_single_case_union_works(): email = Email(email="test@test.com") match email: - case Email(e): + case Email(email=e): assert e == "test@test.com" case _: # pyright: ignore assert False From e82934f7da5171bfce5e095ec6a43a76433e93ac Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 10:58:23 +0100 Subject: [PATCH 12/39] Don't build for 3.12 yet --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index ece5e2e5..61b26194 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", "3.12"] + python-version: ["3.11"] steps: - uses: actions/checkout@v3 From 23eabcdfb8c7b848c4ed91b7eacfd62f99a874b0 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 12:12:35 +0100 Subject: [PATCH 13/39] Update docs --- README.md | 71 +++++++++++++++------------ expression/__init__.py | 16 ------ expression/core/__init__.py | 18 ------- expression/core/choice.py | 97 ------------------------------------- 4 files changed, 41 insertions(+), 161 deletions(-) delete mode 100644 expression/core/choice.py diff --git a/README.md b/README.md index e905b7ae..3bccf4cd 100644 --- a/README.md +++ b/README.md @@ -370,10 +370,10 @@ type union `(A | B)` are both types, while the cases in a tagged union type `U = are both constructors for the type U and are not types themselves. One consequence is that tagged unions can be nested in a way union types might not. -In Expression you make a tagged union by defining your type as a sub-class of -`TaggedUnion` with the appropriate generic types that this union represent for -each case. Then you define static or class-method constructors for creating each of the -tagged union cases. +In Expression you make a tagged union by defining your type similar to a dataclass and +decorate it with `@tagged_union` and add the appropriate generic types that this union +represent for each case. Then you optionally define static or class-method constructors +for creating each of the tagged union cases. ```python from dataclasses import dataclass @@ -388,34 +388,45 @@ class Rectangle: class Circle: radius: float -class Shape(TaggedUnion): - RECTANGLE = tag(Rectangle) - CIRCLE = tag(Circle) +@tagged_union +class Shape: + tag: Literal["rectangle", "circle"] = tag() + + rectangle: Rectangle = case() + circle: Circle = case() @staticmethod - def rectangle(width: float, length: float) -> Shape: - return Shape(Shape.RECTANGLE, Rectangle(width, length)) + def Rectangle(width: float, length: float) -> Shape: + ""Optional static method for creating a tagged union case"" + return Shape(rectangle=Rectangle(width, length)) @staticmethod - def circle(radius: float) -> Shape: - return Shape(Shape.CIRCLE, Circle(radius)) + def Circle(radius: float) -> Shape: + """Optional static method for creating a tagged union case""" + return Shape(circle=Circle(radius)) ``` +Note that the tag field is optional, but recommended. If you don't specify a tag field +then then it will be created for you, but static type checkers will not be able to type +check correctly when pattern matching. + Now you may pattern match the shape to get back the actual value: ```python - from expression import match - shape = Shape.Rectangle(2.3, 3.3) match shape: - case Shape(value=Rectangle(width=2.3)): + case Shape(tag="rectangle", rectangle=Rectangle(width=2.3)): assert shape.value.width == 2.3 case _: assert False ``` -## Notable differences between Expression and F# +Note that when matching keyword arguments, then the tag field must be specified for +static type checkers to work correctly. It's not required for the code to work properly, +but it's recommended. + +## Notable differences between Expression and F\# In F# modules are capitalized, in Python they are lowercase ([PEP-8](https://www.python.org/dev/peps/pep-0008/#package-and-module-names)). @@ -450,27 +461,27 @@ with Expression. A collection of resources that were used as reference and inspiration for creating this library. -- F# (http://fsharp.org) -- Get Started with F# (https://aka.ms/fsharphome) +- F# () +- Get Started with F# () - F# as a Better Python - Phillip Carter - NDC Oslo 2020 - (https://www.youtube.com/watch?v=_QnbV6CAWXc) -- OSlash (https://github.com/dbrattli/OSlash) -- RxPY (https://github.com/ReactiveX/RxPY) -- PEP 8 -- Style Guide for Python Code (https://www.python.org/dev/peps/pep-0008/) + () +- OSlash () +- RxPY () +- PEP 8 -- Style Guide for Python Code () - PEP 342 -- Coroutines via Enhanced Generators - (https://www.python.org/dev/peps/pep-0342/) + () - PEP 380 -- Syntax for Delegating to a Subgenerator - (https://www.python.org/dev/peps/pep-0380) -- PEP 479 -- Change StopIteration handling inside generators (https://www.python.org/dev/peps/pep-0479/) -- PEP 634 -- Structural Pattern Matching (https://www.python.org/dev/peps/pep-0634/) + () +- PEP 479 -- Change StopIteration handling inside generators () +- PEP 634 -- Structural Pattern Matching () - Thunks, Trampolines and Continuation Passing - (https://jtauber.com/blog/2008/03/30/thunks,_trampolines_and_continuation_passing/) + () - Tail Recursion Elimination - (http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html) + () - Final Words on Tail Calls - (http://neopythonic.blogspot.com/2009/04/final-words-on-tail-calls.html) + () - Python is the Haskell You Never Knew You Had: Tail Call Optimization - (https://sagnibak.github.io/blog/python-is-haskell-tail-recursion/) + () ## How-to Contribute @@ -496,7 +507,7 @@ by running: ## Code of Conduct -This project follows https://www.contributor-covenant.org, see our [Code +This project follows , see our [Code of Conduct](https://github.com/cognitedata/Expression/blob/main/CODE_OF_CONDUCT.md). diff --git a/expression/__init__.py b/expression/__init__.py index 44e1c2ba..3824754b 100644 --- a/expression/__init__.py +++ b/expression/__init__.py @@ -14,14 +14,6 @@ from .core import ( AsyncReplyChannel, Builder, - Choice, - Choice1of2, - Choice1of3, - Choice2, - Choice2of2, - Choice2of3, - Choice3, - Choice3of3, EffectError, Error, Failure, @@ -74,14 +66,6 @@ "AsyncReplyChannel", "Builder", "case", - "Choice", - "Choice1of2", - "Choice1of3", - "Choice2", - "Choice2of2", - "Choice2of3", - "Choice3", - "Choice3of3", "collections", "compose", "core", diff --git a/expression/core/__init__.py b/expression/core/__init__.py index 0383cbf2..5a25143d 100644 --- a/expression/core/__init__.py +++ b/expression/core/__init__.py @@ -2,16 +2,6 @@ from . import aiotools, option, result from .builder import Builder -from .choice import ( - Choice, - Choice1of2, - Choice1of3, - Choice2, - Choice2of2, - Choice2of3, - Choice3, - Choice3of3, -) from .compose import compose from .curry import curry, curry_flip from .error import EffectError, failwith @@ -38,14 +28,6 @@ "aiotools", "AsyncReplyChannel", "Builder", - "Choice", - "Choice2", - "Choice3", - "Choice1of2", - "Choice2of2", - "Choice1of3", - "Choice2of3", - "Choice3of3", "compose", "curry", "curry_flip", diff --git a/expression/core/choice.py b/expression/core/choice.py deleted file mode 100644 index f03abc0e..00000000 --- a/expression/core/choice.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Choice type. - -A union type similar to the `Result` type. But also allows for higher -number of choices. Usually you would most likely want to use the -`Result` type instead, but choice can be preferred in non-error cases. -""" -from abc import ABC -from typing import Any, Generic, TypeVar - - -_TSource = TypeVar("_TSource") -_A = TypeVar("_A") -_B = TypeVar("_B") -_C = TypeVar("_C") - - -class Choice(ABC, Generic[_TSource]): - def __init__(self, value: Any) -> None: - self.value = value - - def __repr__(self) -> str: - return str(self) - - def __hash__(self) -> int: - return hash(self.value) - - -class Choice2(Generic[_A, _B]): - def __repr__(self) -> str: - return str(self) - - -class Choice1of2(Choice2[_A, _B], Choice[_A]): - __match_args__ = ("value",) - - def __init__(self, value: _A) -> None: - super().__init__(value) - - def __eq__(self, o: Any) -> bool: - if isinstance(o, Choice1of2): - return self.value == o.value - return False - - def __str__(self) -> str: - return f"Choice1of2 {self.value}" - - -class Choice2of2(Choice2[_A, _B], Choice[_B]): - __match_args__ = ("value",) - - def __init__(self, value: _B) -> None: - super().__init__(value) - - def __eq__(self, o: Any) -> bool: - if isinstance(o, Choice2of2): - return self.value == o.value - return False - - def __str__(self) -> str: - return f"Choice2of2 {self.value}" - - -class Choice3(Generic[_A, _B, _C]): - ... - - -class Choice1of3(Choice3[_A, _B, _C], Choice[_A]): - __match_args__ = ("value",) - - def __init__(self, value: _A) -> None: - super().__init__(value) - - -class Choice2of3(Choice3[_A, _B, _C], Choice[_B]): - __match_args__ = ("value",) - - def __init__(self, value: _B) -> None: - super().__init__(value) - - -class Choice3of3(Choice3[_A, _B, _C], Choice[_C]): - __match_args__ = ("value",) - - def __init__(self, value: _C) -> None: - super().__init__(value) - - -__all__ = [ - "Choice", - "Choice2", - "Choice3", - "Choice1of2", - "Choice2of2", - "Choice1of3", - "Choice2of3", - "Choice3of3", -] From d2852a675af7b65b7537ee3e7b2216a2a42a4b7e Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 13:02:28 +0100 Subject: [PATCH 14/39] Make pydantic optional dependency --- .github/workflows/python-package.yml | 2 +- README.md | 10 ++++++++-- expression/collections/block.py | 12 ++++++++---- expression/core/option.py | 10 +++++++--- expression/core/result.py | 9 ++++++--- poetry.lock | 12 ++++++++---- pyproject.toml | 8 ++++++-- tests/test_choice.py | 27 --------------------------- 8 files changed, 44 insertions(+), 46 deletions(-) delete mode 100644 tests/test_choice.py diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 61b26194..68b3a504 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -28,7 +28,7 @@ jobs: run: | pip install poetry poetry config installer.modern-installation false - poetry install + poetry install --all-extras - name: Code checks run: | diff --git a/README.md b/README.md index 3bccf4cd..759ff53d 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,16 @@ similar to Python, but F# can also do a lot of things better than Python: ## Getting Started You can install the latest `expression` from PyPI by running `pip` (or -`pip3`). Note that `expression` only works for Python 3.9+. +`pip3`). Note that `expression` only works for Python 3.11+. ```console -> pip3 install expression +> pip install expression +``` + +To add Pydantic support, install the `pydantic` extra: + +```console +> pip install expression[pydantic] ``` ## Goals diff --git a/expression/collections/block.py b/expression/collections/block.py index d09fa227..0dfe05d7 100644 --- a/expression/collections/block.py +++ b/expression/collections/block.py @@ -23,10 +23,12 @@ import functools import itertools from collections.abc import Callable, Collection, Iterable, Iterator, Sequence -from typing import Any, Literal, TypeVar, get_args, overload +from typing import TYPE_CHECKING, Any, Literal, TypeVar, get_args, overload -from pydantic import GetCoreSchemaHandler -from pydantic_core import core_schema + +if TYPE_CHECKING: + from pydantic import GetCoreSchemaHandler + from pydantic_core import CoreSchema from expression.core import ( Nothing, @@ -539,7 +541,9 @@ def __repr__(self) -> str: return str(self) @classmethod - def __get_pydantic_core_schema__(cls, source: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: + def __get_pydantic_core_schema__(cls, source: Any, handler: GetCoreSchemaHandler) -> CoreSchema: + from pydantic_core import core_schema + instance_schema = core_schema.is_instance_schema(cls) args = get_args(source) diff --git a/expression/core/option.py b/expression/core/option.py index 38135f45..f8e959f3 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -11,9 +11,6 @@ from collections.abc import Callable, Generator, Iterable from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, get_args, get_origin -from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler -from pydantic_core import CoreSchema, core_schema - from .curry import curry_flip from .error import EffectError from .pipe import PipeMixin @@ -23,9 +20,13 @@ if TYPE_CHECKING: + from pydantic import GetCoreSchemaHandler + from pydantic_core import CoreSchema + from expression.collections.seq import Seq from expression.core.result import Result + _TSource = TypeVar("_TSource") _TResult = TypeVar("_TResult") _TError = TypeVar("_TError") @@ -293,6 +294,9 @@ def __hash__(self) -> int: @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: + from pydantic import ValidatorFunctionWrapHandler + from pydantic_core import core_schema + origin = get_origin(source_type) if origin is None: # used as `x: Owner` without params origin = source_type diff --git a/expression/core/result.py b/expression/core/result.py index bd6d1580..3c5f307b 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -23,11 +23,11 @@ get_origin, ) -from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler -from pydantic_core import CoreSchema, core_schema - if TYPE_CHECKING: + from pydantic import GetCoreSchemaHandler + from pydantic_core import CoreSchema + from expression.core.option import Option from .curry import curry_flip @@ -228,6 +228,9 @@ def __hash__(self) -> int: @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: + from pydantic import ValidatorFunctionWrapHandler + from pydantic_core import core_schema + origin = get_origin(source_type) if origin is None: # used as `x: Result` without params origin = source_type diff --git a/poetry.lock b/poetry.lock index 16d0abb7..bfcf8bd0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -29,7 +29,7 @@ files = [ name = "annotated-types" version = "0.6.0" description = "Reusable constraint types to use with typing.Annotated" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, @@ -1594,7 +1594,7 @@ files = [ name = "pydantic" version = "2.5.3" description = "Data validation using Python type hints" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, @@ -1613,7 +1613,7 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.14.6" description = "" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, @@ -2855,7 +2855,11 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +[extras] +all = ["pydantic"] +pydantic = ["pydantic"] + [metadata] lock-version = "2.0" python-versions = ">= 3.11, < 4" -content-hash = "e10e9d29c1657d108742bbf95475a75f459854afc813a21bd1faf38f37ebda8e" +content-hash = "8c5dee9a3edbf0295034949b3c76b695bd4515f4fc6ef5e9633818518a38288c" diff --git a/pyproject.toml b/pyproject.toml index 9e90c968..452bc0f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,8 @@ classifiers = [ python = ">= 3.11, < 4" typing-extensions = "^4.1.1" +pydantic = {version = "^2.0.0", optional = true} + [tool.poetry.dev-dependencies] pytest-asyncio = "^0.21.0" pytest = "^7.2.0" @@ -38,8 +40,10 @@ hypothesis = "^6.54.2" jupyter-book = "^0.15.0" sphinx-autodoc-typehints = "^1.17.0" -# Make optional dependency -pydantic = "^2.5.0" + +[tool.poetry.extras] +pydantic = ["pydantic"] +all = ["pydantic"] [tool.poetry.group.dev.dependencies] ruff = "^0.1.11" diff --git a/tests/test_choice.py b/tests/test_choice.py deleted file mode 100644 index 7e1a9080..00000000 --- a/tests/test_choice.py +++ /dev/null @@ -1,27 +0,0 @@ -from expression import Choice, Choice1of2, Choice2, Choice2of2 - - -def test_choice_choice1of2(): - xs: Choice2[int, str] = Choice1of2(42) - - assert isinstance(xs, Choice) - assert isinstance(xs, Choice2) - - match xs: - case Choice1of2(x): - assert x == 42 - case _: # type: ignore - assert False - - -def test_choice_choice2of2(): - xs: Choice2[int, str] = Choice2of2("test") - - assert isinstance(xs, Choice) - assert isinstance(xs, Choice2) - - match xs: - case Choice2of2(x): - assert x == "test" - case _: # type: ignore - assert False From 7c628607b3a57f523e28e8b8d00e78d183342d2a Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 13:43:24 +0100 Subject: [PATCH 15/39] Make union frozen optional --- expression/core/option.py | 1 - expression/core/union.py | 160 +++++++++++++++++++++----------------- tests/test_union.py | 2 +- 3 files changed, 88 insertions(+), 75 deletions(-) diff --git a/expression/core/option.py b/expression/core/option.py index f8e959f3..9ecbf475 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -39,7 +39,6 @@ class Option( Iterable[_TSource], PipeMixin, - # SupportsValidation["BaseOption[_TSource]"], ): """Option abstract base class.""" diff --git a/expression/core/union.py b/expression/core/union.py index 1724bd1d..75d44699 100644 --- a/expression/core/union.py +++ b/expression/core/union.py @@ -1,3 +1,4 @@ +from collections.abc import Callable from copy import deepcopy from dataclasses import dataclass, field, fields from typing import Any, TypeVar, dataclass_transform @@ -7,79 +8,92 @@ @dataclass_transform() -def tagged_union(cls: type[_T]) -> type[_T]: - cls = dataclass(cls) # TODO: decide if we should be a dataclass or not - fields_ = fields(cls) # type: ignore - field_names = {f.name for f in fields_} - field_names.add("tag") - original_init = cls.__init__ - - def __init__(self: Any, *args: Any, **kwargs: Any) -> None: - tag = kwargs.pop("tag", None) - if len(kwargs) != 1: - raise TypeError(f"One and only one case can be specified. Not {kwargs}") - name, value = next(iter(kwargs.items())) - if name not in field_names: - raise TypeError(f"Unknown case name: {name}") - if tag is not None and tag != name: - raise TypeError(f"Tag {tag} does not match case name {name}") - - # Cannot use setattr because it is overridden - object.__setattr__(self, "tag", name) - object.__setattr__(self, name, value) - - # Enables the use of dataclasses.asdict - union_fields = dict((f.name, f) for f in fields_ if f.name in [name, "tag"]) - object.__setattr__(self, "__dataclass_fields__", union_fields) # type: ignore - original_init(self) - - def __repr__(self: Any) -> str: - return f"{cls.__name__}({self.tag}={getattr(self, self.tag)})" - - def __hash__(self: Any) -> int: - return hash((cls.__name__, self.tag, getattr(self, self.tag))) - - def __setattr__(self: Any, name: str, value: Any) -> None: - if name in field_names: - raise TypeError("Cannot change the value of a tagged union case") - - object.__setattr__(self, name, value) - - def __delattr__(self: Any, name: str) -> None: - if name in field_names: - raise TypeError("Cannot delete a tagged union case") - - object.__delattr__(self, name) - - def __eq__(self: Any, other: Any) -> bool: - return ( - isinstance(other, cls) - and self.tag == getattr(other, "tag") - and getattr(self, self.tag) == getattr(other, self.tag) - ) - - def __copy__(self: Any) -> Any: - mapping = {self.tag: getattr(self, self.tag)} - return cls(**mapping) - - def __deepcopy__(self: Any, memo: Any) -> Any: - value = deepcopy(getattr(self, self.tag), memo) - mapping = {self.tag: value} - return cls(**mapping) - - cls.__eq__ = __eq__ # type: ignore - cls.__init__ = __init__ # type: ignore - cls.__repr__ = __repr__ # type: ignore - cls.__hash__ = __hash__ # type: ignore - cls.__setattr__ = __setattr__ # type: ignore - cls.__delattr__ = __delattr__ # type: ignore - cls.__match_args__ = tuple(field_names) # type: ignore - - # We need to handle copy and deepcopy ourselves because they are needed by Pydantic - cls.__copy__ = __copy__ # type: ignore - cls.__deepcopy__ = __deepcopy__ # type: ignore - - return cls +def tagged_union(cls: type[_T] | None = None, *, frozen: bool = False) -> Callable[[type[_T]], type[_T]] | type[_T]: + """Tagged union decorator. + + A decorator that turns a dataclass into a tagged union. + """ + + def transform(cls: type[_T]) -> type[_T]: + cls = dataclass(cls) # TODO: decide if we should be a dataclass or not + fields_ = fields(cls) # type: ignore + field_names = {f.name for f in fields_} + field_names.add("tag") + original_init = cls.__init__ + + def __init__(self: Any, **kwargs: Any) -> None: + tag = kwargs.pop("tag", None) + if len(kwargs) != 1: + raise TypeError(f"One and only one case can be specified. Not {kwargs}") + name, value = next(iter(kwargs.items())) + if name not in field_names: + raise TypeError(f"Unknown case name: {name}") + if tag is not None and tag != name: + raise TypeError(f"Tag {tag} does not match case name {name}") + + # Cannot use setattr because it might be overridden for frozen classes + object.__setattr__(self, "tag", name) + object.__setattr__(self, name, value) + + # Enables the use of dataclasses.asdict + union_fields = dict((f.name, f) for f in fields_ if f.name in [name, "tag"]) + object.__setattr__(self, "__dataclass_fields__", union_fields) # type: ignore + original_init(self) + + def __repr__(self: Any) -> str: + return f"{cls.__name__}({self.tag}={getattr(self, self.tag)})" + + def __hash__(self: Any) -> int: + return hash((cls.__name__, self.tag, getattr(self, self.tag))) + + if frozen: + + def __setattr__(self: Any, name: str, value: Any) -> None: + if name in field_names: + raise TypeError("Cannot change the value of a tagged union case") + object.__setattr__(self, name, value) + + def __delattr__(self: Any, name: str) -> None: + if name in field_names: + raise TypeError("Cannot delete a tagged union case") + + object.__delattr__(self, name) + + cls.__setattr__ = __setattr__ + cls.__delattr__ = __delattr__ # type: ignore + + def __eq__(self: Any, other: Any) -> bool: + return ( + isinstance(other, cls) + and self.tag == getattr(other, "tag") + and getattr(self, self.tag) == getattr(other, self.tag) + ) + + def __copy__(self: Any) -> Any: + mapping = {self.tag: getattr(self, self.tag)} + return cls(**mapping) + + def __deepcopy__(self: Any, memo: Any) -> Any: + value = deepcopy(getattr(self, self.tag), memo) + mapping = {self.tag: value} + return cls(**mapping) + + cls.__eq__ = __eq__ # type: ignore + cls.__init__ = __init__ # type: ignore + cls.__repr__ = __repr__ # type: ignore + cls.__hash__ = __hash__ # type: ignore + cls.__match_args__ = tuple(field_names) # type: ignore + + # We need to handle copy and deepcopy ourselves because they are needed by Pydantic + cls.__copy__ = __copy__ # type: ignore + cls.__deepcopy__ = __deepcopy__ # type: ignore + + return cls + + if cls is None: + return transform + + return transform(cls) def case() -> Any: diff --git a/tests/test_union.py b/tests/test_union.py index 8772b699..9024a520 100644 --- a/tests/test_union.py +++ b/tests/test_union.py @@ -15,7 +15,7 @@ class Circle: radius: float -@tagged_union +@tagged_union(frozen=True) class Shape: tag: Literal["circle", "rectangle", "triangle"] = tag() From 38ebe851bbb2f7fcdc109db1174e1812b22305da Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 13:44:33 +0100 Subject: [PATCH 16/39] Ignore type error (by design) --- tests/test_union.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_union.py b/tests/test_union.py index 9024a520..8b0f4b1c 100644 --- a/tests/test_union.py +++ b/tests/test_union.py @@ -78,7 +78,7 @@ def test_union_can_add_custom_attributes_to_shape(): def test_union_cannot_change_case_value(): shape = Shape(circle=Circle(10.0)) with pytest.raises(TypeError): - shape.circle = Circle(20.0) + shape.circle = Circle(20.0) # type: ignore def test_union_compare_shapes(): From 8934a1a9ca5075c6b74a2a56eacd0be6479cfde3 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 13:53:35 +0100 Subject: [PATCH 17/39] Fixes for union frozen argument --- .pre-commit-config.yaml | 2 +- expression/collections/seq.py | 4 ++-- expression/core/union.py | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c57e2f75..6dfecb90 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: - id: ruff-format args: [--check] repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.3 + rev: v0.1.11 - hooks: - id: pyright name: pyright diff --git a/expression/collections/seq.py b/expression/collections/seq.py index 58ca2b7e..65d2cb2f 100644 --- a/expression/collections/seq.py +++ b/expression/collections/seq.py @@ -656,14 +656,14 @@ def starmap(mapper: Callable[[_T1, _T2], _TResult]) -> Callable[[Iterable[tuple[ @overload def starmap( - mapper: Callable[[_T1, _T2, _T3], _TResult] + mapper: Callable[[_T1, _T2, _T3], _TResult], ) -> Callable[[Iterable[tuple[_T1, _T2, _T3]]], Iterable[_TResult]]: ... @overload def starmap( - mapper: Callable[[_T1, _T2, _T3, _T4], _TResult] + mapper: Callable[[_T1, _T2, _T3, _T4], _TResult], ) -> Callable[[Iterable[tuple[_T1, _T2, _T3, _T4]]], Iterable[_TResult]]: ... diff --git a/expression/core/union.py b/expression/core/union.py index 75d44699..97a7790c 100644 --- a/expression/core/union.py +++ b/expression/core/union.py @@ -8,10 +8,13 @@ @dataclass_transform() -def tagged_union(cls: type[_T] | None = None, *, frozen: bool = False) -> Callable[[type[_T]], type[_T]] | type[_T]: +def tagged_union(_cls: type[_T] | None = None, *, frozen: bool = False) -> Callable[[type[_T]], type[_T]] | type[_T]: """Tagged union decorator. A decorator that turns a dataclass into a tagged union. + + Arguments: + frozen: Whether the tagged union should be frozen. """ def transform(cls: type[_T]) -> type[_T]: @@ -90,10 +93,7 @@ def __deepcopy__(self: Any, memo: Any) -> Any: return cls - if cls is None: - return transform - - return transform(cls) + return transform if _cls is None else transform(_cls) def case() -> Any: From d3d7e6bf3e7050b025f41a516bd2275be416156a Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 21:58:20 +0100 Subject: [PATCH 18/39] Remove dependencies to build on 3.12 --- .github/workflows/python-package.yml | 2 +- docs/requirements.txt | 3 +- poetry.lock | 2625 +++----------------------- pyproject.toml | 11 +- 4 files changed, 284 insertions(+), 2357 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 68b3a504..bf76124a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11"] + python-version: ["3.11", 3.12"] steps: - uses: actions/checkout@v3 diff --git a/docs/requirements.txt b/docs/requirements.txt index 52b3f5de..0a8f6022 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,4 @@ jupyter-book sphinx-autodoc-typehints>=1.17.0 -expression>=2.0.1 +sphinx-panels +expression>=4.0.0 diff --git a/poetry.lock b/poetry.lock index bfcf8bd0..4667da08 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,30 +1,5 @@ # This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. -[[package]] -name = "accessible-pygments" -version = "0.0.4" -description = "A collection of accessible pygments styles" -optional = false -python-versions = "*" -files = [ - {file = "accessible-pygments-0.0.4.tar.gz", hash = "sha256:e7b57a9b15958e9601c7e9eb07a440c813283545a20973f2574a5f453d0e953e"}, - {file = "accessible_pygments-0.0.4-py2.py3-none-any.whl", hash = "sha256:416c6d8c1ea1c5ad8701903a20fcedf953c6e720d64f33dc47bfb2d3f2fa4e8d"}, -] - -[package.dependencies] -pygments = ">=1.5" - -[[package]] -name = "alabaster" -version = "0.7.13" -description = "A configurable sidebar-enabled Sphinx theme" -optional = false -python-versions = ">=3.6" -files = [ - {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, - {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, -] - [[package]] name = "annotated-types" version = "0.6.0" @@ -36,35 +11,6 @@ files = [ {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, ] -[[package]] -name = "appnope" -version = "0.1.3" -description = "Disable App Nap on macOS >= 10.9" -optional = false -python-versions = "*" -files = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, -] - -[[package]] -name = "asttokens" -version = "2.4.1" -description = "Annotate AST trees with source code positions" -optional = false -python-versions = "*" -files = [ - {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, - {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, -] - -[package.dependencies] -six = ">=1.12.0" - -[package.extras] -astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] -test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] - [[package]] name = "attrs" version = "23.2.0" @@ -84,96 +30,6 @@ tests = ["attrs[tests-no-zope]", "zope-interface"] tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] -[[package]] -name = "autoflake" -version = "2.2.1" -description = "Removes unused imports and unused variables" -optional = false -python-versions = ">=3.8" -files = [ - {file = "autoflake-2.2.1-py3-none-any.whl", hash = "sha256:265cde0a43c1f44ecfb4f30d95b0437796759d07be7706a2f70e4719234c0f79"}, - {file = "autoflake-2.2.1.tar.gz", hash = "sha256:62b7b6449a692c3c9b0c916919bbc21648da7281e8506bcf8d3f8280e431ebc1"}, -] - -[package.dependencies] -pyflakes = ">=3.0.0" - -[[package]] -name = "babel" -version = "2.14.0" -description = "Internationalization utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, - {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, -] - -[package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] - -[[package]] -name = "beautifulsoup4" -version = "4.12.2" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "black" -version = "23.12.1" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, - {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, - {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, - {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, - {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, - {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, - {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, - {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, - {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, - {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, - {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, - {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, - {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, - {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, - {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, - {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, - {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, - {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, - {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, - {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, - {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, - {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - [[package]] name = "certifi" version = "2023.11.17" @@ -185,70 +41,6 @@ files = [ {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, ] -[[package]] -name = "cffi" -version = "1.16.0" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, - {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, - {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, -] - -[package.dependencies] -pycparser = "*" - [[package]] name = "cfgv" version = "3.4.0" @@ -359,20 +151,6 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - [[package]] name = "colorama" version = "0.4.6" @@ -384,23 +162,6 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "comm" -version = "0.2.1" -description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -optional = false -python-versions = ">=3.8" -files = [ - {file = "comm-0.2.1-py3-none-any.whl", hash = "sha256:87928485c0dfc0e7976fd89fc1e187023cf587e7c353e4a9b417555b44adf021"}, - {file = "comm-0.2.1.tar.gz", hash = "sha256:0bc91edae1344d39d3661dcbc36937181fdaddb304790458f8b044dbc064b89a"}, -] - -[package.dependencies] -traitlets = ">=4" - -[package.extras] -test = ["pytest"] - [[package]] name = "coverage" version = "6.5.0" @@ -482,44 +243,6 @@ requests = ">=1.0.0" [package.extras] yaml = ["PyYAML (>=3.10)"] -[[package]] -name = "debugpy" -version = "1.8.0" -description = "An implementation of the Debug Adapter Protocol for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "debugpy-1.8.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb"}, - {file = "debugpy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada"}, - {file = "debugpy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f"}, - {file = "debugpy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637"}, - {file = "debugpy-1.8.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e"}, - {file = "debugpy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6"}, - {file = "debugpy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b"}, - {file = "debugpy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153"}, - {file = "debugpy-1.8.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd"}, - {file = "debugpy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f"}, - {file = "debugpy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa"}, - {file = "debugpy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595"}, - {file = "debugpy-1.8.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8"}, - {file = "debugpy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332"}, - {file = "debugpy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6"}, - {file = "debugpy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926"}, - {file = "debugpy-1.8.0-py2.py3-none-any.whl", hash = "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4"}, - {file = "debugpy-1.8.0.zip", hash = "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0"}, -] - -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -optional = false -python-versions = ">=3.5" -files = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] - [[package]] name = "distlib" version = "0.3.8" @@ -541,17 +264,6 @@ files = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] -[[package]] -name = "docutils" -version = "0.18.1" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, - {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, -] - [[package]] name = "dunamai" version = "1.19.0" @@ -566,34 +278,6 @@ files = [ [package.dependencies] packaging = ">=20.9" -[[package]] -name = "executing" -version = "2.0.1" -description = "Get the currently executing AST node of a frame, and other information" -optional = false -python-versions = ">=3.5" -files = [ - {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, - {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, -] - -[package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] - -[[package]] -name = "fastjsonschema" -version = "2.19.1" -description = "Fastest Python implementation of JSON schema" -optional = false -python-versions = "*" -files = [ - {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, - {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, -] - -[package.extras] -devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] - [[package]] name = "filelock" version = "3.13.1" @@ -610,93 +294,6 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] -[[package]] -name = "flake8" -version = "6.1.0" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, - {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.1.0,<3.2.0" - -[[package]] -name = "greenlet" -version = "3.0.3" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=3.7" -files = [ - {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, - {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, - {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, - {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, - {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, - {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, - {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, - {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, - {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, - {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, - {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, - {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, - {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, - {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, - {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, - {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, -] - -[package.extras] -docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil"] - [[package]] name = "hypothesis" version = "6.92.2" @@ -753,36 +350,6 @@ files = [ {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] -[[package]] -name = "imagesize" -version = "1.4.1" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] - -[[package]] -name = "importlib-metadata" -version = "7.0.1" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -795,1965 +362,385 @@ files = [ ] [[package]] -name = "ipykernel" -version = "6.28.0" -description = "IPython Kernel for Jupyter" -optional = false -python-versions = ">=3.8" -files = [ - {file = "ipykernel-6.28.0-py3-none-any.whl", hash = "sha256:c6e9a9c63a7f4095c0a22a79f765f079f9ec7be4f2430a898ddea889e8665661"}, - {file = "ipykernel-6.28.0.tar.gz", hash = "sha256:69c11403d26de69df02225916f916b37ea4b9af417da0a8c827f84328d88e5f3"}, -] - -[package.dependencies] -appnope = {version = "*", markers = "platform_system == \"Darwin\""} -comm = ">=0.1.1" -debugpy = ">=1.6.5" -ipython = ">=7.23.1" -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -matplotlib-inline = ">=0.1" -nest-asyncio = "*" -packaging = "*" -psutil = "*" -pyzmq = ">=24" -tornado = ">=6.1" -traitlets = ">=5.4.0" - -[package.extras] -cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] -pyqt5 = ["pyqt5"] -pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "ipython" -version = "8.19.0" -description = "IPython: Productive Interactive Computing" -optional = false -python-versions = ">=3.10" -files = [ - {file = "ipython-8.19.0-py3-none-any.whl", hash = "sha256:2f55d59370f59d0d2b2212109fe0e6035cfea436b1c0e6150ad2244746272ec5"}, - {file = "ipython-8.19.0.tar.gz", hash = "sha256:ac4da4ecf0042fb4e0ce57c60430c2db3c719fa8bdf92f8631d6bd8a5785d1f0"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -prompt-toolkit = ">=3.0.41,<3.1.0" -pygments = ">=2.4.0" -stack-data = "*" -traitlets = ">=5" - -[package.extras] -all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.23)", "pandas", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] -black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath", "trio"] - -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - -[[package]] -name = "jedi" -version = "0.19.1" -description = "An autocompletion tool for Python that can be used for text editors." +name = "nodeenv" +version = "1.8.0" +description = "Node.js virtual environment builder" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ - {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, - {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, ] [package.dependencies] -parso = ">=0.8.3,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +setuptools = "*" [[package]] -name = "jinja2" -version = "3.1.2" -description = "A very fast and expressive template engine." +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - [[package]] -name = "jsonschema" -version = "4.20.0" -description = "An implementation of JSON Schema validation for Python" +name = "platformdirs" +version = "4.1.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.20.0-py3-none-any.whl", hash = "sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3"}, - {file = "jsonschema-4.20.0.tar.gz", hash = "sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa"}, + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, ] -[package.dependencies] -attrs = ">=22.2.0" -jsonschema-specifications = ">=2023.03.6" -referencing = ">=0.28.4" -rpds-py = ">=0.7.1" - [package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] -name = "jsonschema-specifications" -version = "2023.12.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +name = "pluggy" +version = "1.3.0" +description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, - {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, -] - -[package.dependencies] -referencing = ">=0.31.0" - -[[package]] -name = "jupyter-book" -version = "0.15.1" -description = "Build a book with Jupyter Notebooks and Sphinx." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyter-book-0.15.1.tar.gz", hash = "sha256:8a1634ec16f7eedee0d116f1e5fb7c48203289ad92da42e09519dc71d956c010"}, - {file = "jupyter_book-0.15.1-py3-none-any.whl", hash = "sha256:7671264952abd1ca3f5e713b03e138dda710c92a985c49154f398817fe089968"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] -[package.dependencies] -click = ">=7.1,<9" -docutils = ">=0.15,<0.19" -Jinja2 = "*" -jsonschema = "<5" -linkify-it-py = ">=2.0.0,<2.1.0" -myst-nb = ">=0.17.1,<0.18.0" -pyyaml = "*" -sphinx = ">=4,<6" -sphinx-book-theme = ">=1.0.0,<1.1.0" -sphinx-comments = "*" -sphinx-copybutton = "*" -sphinx-design = ">=0.3.0,<0.4.0" -sphinx-external-toc = ">=0.3.1,<0.4.0" -sphinx-jupyterbook-latex = ">=0.5.2,<0.6.0" -sphinx-multitoc-numbering = ">=0.1.3,<0.2.0" -sphinx-thebe = ">=0.2.0,<0.3.0" -sphinx_togglebutton = "*" -sphinxcontrib-bibtex = ">=2.2.0,<=2.5.0" - [package.extras] -code-style = ["pre-commit (>=3.1,<4.0)"] -pdfhtml = ["pyppeteer"] -sphinx = ["altair", "bokeh", "folium", "ipywidgets", "jupytext", "matplotlib", "nbclient", "numpy", "pandas", "plotly", "sphinx-click", "sphinx-examples", "sphinx-proof", "sphinx_inline_tabs", "sphinxext-rediraffe (>=0.2.3,<0.3.0)", "sympy"] -testing = ["altair", "beautifulsoup4", "beautifulsoup4", "cookiecutter", "coverage", "jupytext", "matplotlib", "pyppeteer", "pytest (>=6.2.4)", "pytest-cov", "pytest-regressions", "pytest-timeout", "pytest-xdist", "sphinx_click", "sphinx_tabs", "texsoup"] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] -name = "jupyter-cache" -version = "0.6.1" -description = "A defined interface for working with a cache of jupyter notebooks." +name = "pre-commit" +version = "3.6.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false -python-versions = "~=3.8" +python-versions = ">=3.9" files = [ - {file = "jupyter-cache-0.6.1.tar.gz", hash = "sha256:26f83901143edf4af2f3ff5a91e2d2ad298e46e2cee03c8071d37a23a63ccbfc"}, - {file = "jupyter_cache-0.6.1-py3-none-any.whl", hash = "sha256:2fce7d4975805c77f75bdfc1bc2e82bc538b8e5b1af27f2f5e06d55b9f996a82"}, + {file = "pre_commit-3.6.0-py2.py3-none-any.whl", hash = "sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376"}, + {file = "pre_commit-3.6.0.tar.gz", hash = "sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d"}, ] [package.dependencies] -attrs = "*" -click = "*" -importlib-metadata = "*" -nbclient = ">=0.2,<0.8" -nbformat = "*" -pyyaml = "*" -sqlalchemy = ">=1.3.12,<3" -tabulate = "*" - -[package.extras] -cli = ["click-log"] -code-style = ["pre-commit (>=2.12,<4.0)"] -rtd = ["ipykernel", "jupytext", "myst-nb", "nbdime", "sphinx-book-theme", "sphinx-copybutton"] -testing = ["coverage", "ipykernel", "jupytext", "matplotlib", "nbdime", "nbformat (>=5.1)", "numpy", "pandas", "pytest (>=6,<8)", "pytest-cov", "pytest-regressions", "sympy"] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" [[package]] -name = "jupyter-client" -version = "8.6.0" -description = "Jupyter protocol implementation and client libraries" -optional = false -python-versions = ">=3.8" +name = "pydantic" +version = "2.5.3" +description = "Data validation using Python type hints" +optional = true +python-versions = ">=3.7" files = [ - {file = "jupyter_client-8.6.0-py3-none-any.whl", hash = "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99"}, - {file = "jupyter_client-8.6.0.tar.gz", hash = "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7"}, + {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, + {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, ] [package.dependencies] -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -python-dateutil = ">=2.8.2" -pyzmq = ">=23.0" -tornado = ">=6.2" -traitlets = ">=5.3" +annotated-types = ">=0.4.0" +pydantic-core = "2.14.6" +typing-extensions = ">=4.6.1" [package.extras] -docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] +email = ["email-validator (>=2.0.0)"] [[package]] -name = "jupyter-core" -version = "5.7.0" -description = "Jupyter core package. A base package on which Jupyter projects rely." -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter_core-5.7.0-py3-none-any.whl", hash = "sha256:16eea462f7dad23ba9f86542bdf17f830804e2028eb48d609b6134d91681e983"}, - {file = "jupyter_core-5.7.0.tar.gz", hash = "sha256:cb8d3ed92144d2463a3c5664fdd686a3f0c1442ea45df8babb1c1a9e6333fe03"}, -] - -[package.dependencies] -platformdirs = ">=2.5" -pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} -traitlets = ">=5.3" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "latexcodec" -version = "2.0.1" -description = "A lexer and codec to work with LaTeX code in Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, - {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, -] - -[package.dependencies] -six = ">=1.4.1" - -[[package]] -name = "linkify-it-py" -version = "2.0.2" -description = "Links recognition library with FULL unicode support." -optional = false -python-versions = ">=3.7" -files = [ - {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, - {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, -] - -[package.dependencies] -uc-micro-py = "*" - -[package.extras] -benchmark = ["pytest", "pytest-benchmark"] -dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] -doc = ["myst-parser", "sphinx", "sphinx-book-theme"] -test = ["coverage", "pytest", "pytest-cov"] - -[[package]] -name = "markdown-it-py" -version = "2.2.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.7" -files = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "markupsafe" -version = "2.1.3" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, -] - -[[package]] -name = "matplotlib-inline" -version = "0.1.6" -description = "Inline Matplotlib backend for Jupyter" -optional = false -python-versions = ">=3.5" -files = [ - {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, - {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, -] - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - -[[package]] -name = "mdit-py-plugins" -version = "0.3.5" -description = "Collection of plugins for markdown-it-py" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, - {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, -] - -[package.dependencies] -markdown-it-py = ">=1.0.0,<3.0.0" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "myst-nb" -version = "0.17.2" -description = "A Jupyter Notebook Sphinx reader built on top of the MyST markdown parser." -optional = false -python-versions = ">=3.7" -files = [ - {file = "myst-nb-0.17.2.tar.gz", hash = "sha256:0f61386515fab07c73646adca97fff2f69f41e90d313a260217c5bbe419d858b"}, - {file = "myst_nb-0.17.2-py3-none-any.whl", hash = "sha256:132ca4d0f5c308fdd4b6fdaba077712e28e119ccdafd04d6e41b51aac5483494"}, -] - -[package.dependencies] -importlib_metadata = "*" -ipykernel = "*" -ipython = "*" -jupyter-cache = ">=0.5,<0.7" -myst-parser = ">=0.18.0,<0.19.0" -nbclient = "*" -nbformat = ">=5.0,<6.0" -pyyaml = "*" -sphinx = ">=4,<6" -typing-extensions = "*" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["alabaster", "altair", "bokeh", "coconut (>=1.4.3,<2.3.0)", "ipykernel (>=5.5,<6.0)", "ipywidgets", "jupytext (>=1.11.2,<1.12.0)", "matplotlib", "numpy", "pandas", "plotly", "sphinx-book-theme (>=0.3.0,<0.4.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0,<0.5.0)", "sphinxcontrib-bibtex", "sympy"] -testing = ["beautifulsoup4", "coverage (>=6.4,<8.0)", "ipykernel (>=5.5,<6.0)", "ipython (!=8.1.0,<8.5)", "ipywidgets (>=8)", "jupytext (>=1.11.2,<1.12.0)", "matplotlib (>=3.5.3,<3.6)", "nbdime", "numpy", "pandas", "pytest (>=7.1,<8.0)", "pytest-cov (>=3,<5)", "pytest-param-files (>=0.3.3,<0.4.0)", "pytest-regressions", "sympy (>=1.10.1)"] - -[[package]] -name = "myst-parser" -version = "0.18.1" -description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." -optional = false -python-versions = ">=3.7" -files = [ - {file = "myst-parser-0.18.1.tar.gz", hash = "sha256:79317f4bb2c13053dd6e64f9da1ba1da6cd9c40c8a430c447a7b146a594c246d"}, - {file = "myst_parser-0.18.1-py3-none-any.whl", hash = "sha256:61b275b85d9f58aa327f370913ae1bec26ebad372cc99f3ab85c8ec3ee8d9fb8"}, -] - -[package.dependencies] -docutils = ">=0.15,<0.20" -jinja2 = "*" -markdown-it-py = ">=1.0.0,<3.0.0" -mdit-py-plugins = ">=0.3.1,<0.4.0" -pyyaml = "*" -sphinx = ">=4,<6" -typing-extensions = "*" - -[package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -linkify = ["linkify-it-py (>=1.0,<2.0)"] -rtd = ["ipython", "sphinx-book-theme", "sphinx-design", "sphinxcontrib.mermaid (>=0.7.1,<0.8.0)", "sphinxext-opengraph (>=0.6.3,<0.7.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] -testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx (<5.2)", "sphinx-pytest"] - -[[package]] -name = "nbclient" -version = "0.7.4" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, - {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, -] - -[package.dependencies] -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -nbformat = ">=5.1" -traitlets = ">=5.3" - -[package.extras] -dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] - -[[package]] -name = "nbformat" -version = "5.9.2" -description = "The Jupyter Notebook format" -optional = false -python-versions = ">=3.8" -files = [ - {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, - {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, -] - -[package.dependencies] -fastjsonschema = "*" -jsonschema = ">=2.6" -jupyter-core = "*" -traitlets = ">=5.1" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["pep440", "pre-commit", "pytest", "testpath"] - -[[package]] -name = "nest-asyncio" -version = "1.5.8" -description = "Patch asyncio to allow nested event loops" -optional = false -python-versions = ">=3.5" -files = [ - {file = "nest_asyncio-1.5.8-py3-none-any.whl", hash = "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d"}, - {file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"}, -] - -[[package]] -name = "nodeenv" -version = "1.8.0" -description = "Node.js virtual environment builder" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" -files = [ - {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, - {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, -] - -[package.dependencies] -setuptools = "*" - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "parso" -version = "0.8.3" -description = "A Python Parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, -] - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "pexpect" -version = "4.9.0" -description = "Pexpect allows easy control of interactive console applications." -optional = false -python-versions = "*" -files = [ - {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, - {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "platformdirs" -version = "4.1.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, - {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, -] - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] - -[[package]] -name = "pluggy" -version = "1.3.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "3.6.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.9" -files = [ - {file = "pre_commit-3.6.0-py2.py3-none-any.whl", hash = "sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376"}, - {file = "pre_commit-3.6.0.tar.gz", hash = "sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "prompt-toolkit" -version = "3.0.43" -description = "Library for building powerful interactive command lines in Python" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, - {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "psutil" -version = "5.9.7" -description = "Cross-platform lib for process and system monitoring in Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "psutil-5.9.7-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0bd41bf2d1463dfa535942b2a8f0e958acf6607ac0be52265ab31f7923bcd5e6"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5794944462509e49d4d458f4dbfb92c47539e7d8d15c796f141f474010084056"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:fe361f743cb3389b8efda21980d93eb55c1f1e3898269bc9a2a1d0bb7b1f6508"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:e469990e28f1ad738f65a42dcfc17adaed9d0f325d55047593cb9033a0ab63df"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:3c4747a3e2ead1589e647e64aad601981f01b68f9398ddf94d01e3dc0d1e57c7"}, - {file = "psutil-5.9.7-cp27-none-win32.whl", hash = "sha256:1d4bc4a0148fdd7fd8f38e0498639ae128e64538faa507df25a20f8f7fb2341c"}, - {file = "psutil-5.9.7-cp27-none-win_amd64.whl", hash = "sha256:4c03362e280d06bbbfcd52f29acd79c733e0af33d707c54255d21029b8b32ba6"}, - {file = "psutil-5.9.7-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ea36cc62e69a13ec52b2f625c27527f6e4479bca2b340b7a452af55b34fcbe2e"}, - {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1132704b876e58d277168cd729d64750633d5ff0183acf5b3c986b8466cd0284"}, - {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8b7f07948f1304497ce4f4684881250cd859b16d06a1dc4d7941eeb6233bfe"}, - {file = "psutil-5.9.7-cp36-cp36m-win32.whl", hash = "sha256:b27f8fdb190c8c03914f908a4555159327d7481dac2f01008d483137ef3311a9"}, - {file = "psutil-5.9.7-cp36-cp36m-win_amd64.whl", hash = "sha256:44969859757f4d8f2a9bd5b76eba8c3099a2c8cf3992ff62144061e39ba8568e"}, - {file = "psutil-5.9.7-cp37-abi3-win32.whl", hash = "sha256:c727ca5a9b2dd5193b8644b9f0c883d54f1248310023b5ad3e92036c5e2ada68"}, - {file = "psutil-5.9.7-cp37-abi3-win_amd64.whl", hash = "sha256:f37f87e4d73b79e6c5e749440c3113b81d1ee7d26f21c19c47371ddea834f414"}, - {file = "psutil-5.9.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:032f4f2c909818c86cea4fe2cc407f1c0f0cde8e6c6d702b28b8ce0c0d143340"}, - {file = "psutil-5.9.7.tar.gz", hash = "sha256:3f02134e82cfb5d089fddf20bb2e03fd5cd52395321d1c8458a9e58500ff417c"}, -] - -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -optional = false -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pure-eval" -version = "0.2.2" -description = "Safely evaluate AST nodes without side effects" -optional = false -python-versions = "*" -files = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, -] - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "pybtex" -version = "0.24.0" -description = "A BibTeX-compatible bibliography processor in Python" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" -files = [ - {file = "pybtex-0.24.0-py2.py3-none-any.whl", hash = "sha256:e1e0c8c69998452fea90e9179aa2a98ab103f3eed894405b7264e517cc2fcc0f"}, - {file = "pybtex-0.24.0.tar.gz", hash = "sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755"}, -] - -[package.dependencies] -latexcodec = ">=1.0.4" -PyYAML = ">=3.01" -six = "*" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "pybtex-docutils" -version = "1.0.3" -description = "A docutils backend for pybtex." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pybtex-docutils-1.0.3.tar.gz", hash = "sha256:3a7ebdf92b593e00e8c1c538aa9a20bca5d92d84231124715acc964d51d93c6b"}, - {file = "pybtex_docutils-1.0.3-py3-none-any.whl", hash = "sha256:8fd290d2ae48e32fcb54d86b0efb8d573198653c7e2447d5bec5847095f430b9"}, -] - -[package.dependencies] -docutils = ">=0.14" -pybtex = ">=0.16" - -[[package]] -name = "pycodestyle" -version = "2.11.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, -] - -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] - -[[package]] -name = "pydantic" -version = "2.5.3" -description = "Data validation using Python type hints" -optional = true -python-versions = ">=3.7" -files = [ - {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, - {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, -] - -[package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.14.6" -typing-extensions = ">=4.6.1" - -[package.extras] -email = ["email-validator (>=2.0.0)"] - -[[package]] -name = "pydantic-core" -version = "2.14.6" -description = "" -optional = true -python-versions = ">=3.7" -files = [ - {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, - {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"}, - {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"}, - {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"}, - {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"}, - {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"}, - {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"}, - {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"}, - {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"}, - {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"}, - {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"}, - {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"}, - {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"}, - {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"}, - {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"}, - {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"}, - {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"}, - {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, - {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, - {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, - {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, - {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, - {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, - {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"}, - {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"}, - {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"}, - {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"}, - {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"}, - {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"}, - {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"}, - {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"}, - {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"}, - {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"}, - {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"}, - {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pydata-sphinx-theme" -version = "0.15.1" -description = "Bootstrap-based Sphinx theme from the PyData community" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pydata_sphinx_theme-0.15.1-py3-none-any.whl", hash = "sha256:064efbe96137bd0acab80413759f1db38a42b51e2429b159af75c43a7590320b"}, - {file = "pydata_sphinx_theme-0.15.1.tar.gz", hash = "sha256:4606f7d59765ae06ff7cb5e07dead4286ea2ff2164deeee63922481eddf1083c"}, -] - -[package.dependencies] -accessible-pygments = "*" -Babel = "*" -beautifulsoup4 = "*" -docutils = "!=0.17.0" -packaging = "*" -pygments = ">=2.7" -sphinx = ">=5.0" -typing-extensions = "*" - -[package.extras] -a11y = ["pytest-playwright"] -dev = ["nox", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml"] -doc = ["ablog (>=0.11.0rc2)", "colorama", "ipykernel", "ipyleaflet", "jupyter_sphinx", "jupyterlite-sphinx", "linkify-it-py", "matplotlib", "myst-parser", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-autoapi (>=3.0.0)", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube (<1.4)", "sphinxext-rediraffe", "xarray"] -test = ["pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "pyflakes" -version = "3.1.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, - {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, -] - -[[package]] -name = "pygments" -version = "2.17.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, -] - -[package.extras] -plugins = ["importlib-metadata"] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pytest" -version = "7.4.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.21.1" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-asyncio-0.21.1.tar.gz", hash = "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d"}, - {file = "pytest_asyncio-0.21.1-py3-none-any.whl", hash = "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b"}, -] - -[package.dependencies] -pytest = ">=7.0.0" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pywin32" -version = "306" -description = "Python for Window Extensions" -optional = false -python-versions = "*" -files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "pyzmq" -version = "25.1.2" -description = "Python bindings for 0MQ" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4"}, - {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75"}, - {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6"}, - {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979"}, - {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08"}, - {file = "pyzmq-25.1.2-cp310-cp310-win32.whl", hash = "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886"}, - {file = "pyzmq-25.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6"}, - {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c"}, - {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d"}, - {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b"}, - {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b"}, - {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3"}, - {file = "pyzmq-25.1.2-cp311-cp311-win32.whl", hash = "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097"}, - {file = "pyzmq-25.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9"}, - {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a"}, - {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537"}, - {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181"}, - {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe"}, - {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737"}, - {file = "pyzmq-25.1.2-cp312-cp312-win32.whl", hash = "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d"}, - {file = "pyzmq-25.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7"}, - {file = "pyzmq-25.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7b6d09a8962a91151f0976008eb7b29b433a560fde056ec7a3db9ec8f1075438"}, - {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967668420f36878a3c9ecb5ab33c9d0ff8d054f9c0233d995a6d25b0e95e1b6b"}, - {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5edac3f57c7ddaacdb4d40f6ef2f9e299471fc38d112f4bc6d60ab9365445fb0"}, - {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0dabfb10ef897f3b7e101cacba1437bd3a5032ee667b7ead32bbcdd1a8422fe7"}, - {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2c6441e0398c2baacfe5ba30c937d274cfc2dc5b55e82e3749e333aabffde561"}, - {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:16b726c1f6c2e7625706549f9dbe9b06004dfbec30dbed4bf50cbdfc73e5b32a"}, - {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a86c2dd76ef71a773e70551a07318b8e52379f58dafa7ae1e0a4be78efd1ff16"}, - {file = "pyzmq-25.1.2-cp36-cp36m-win32.whl", hash = "sha256:359f7f74b5d3c65dae137f33eb2bcfa7ad9ebefd1cab85c935f063f1dbb245cc"}, - {file = "pyzmq-25.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:55875492f820d0eb3417b51d96fea549cde77893ae3790fd25491c5754ea2f68"}, - {file = "pyzmq-25.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8c8a419dfb02e91b453615c69568442e897aaf77561ee0064d789705ff37a92"}, - {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8807c87fa893527ae8a524c15fc505d9950d5e856f03dae5921b5e9aa3b8783b"}, - {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5e319ed7d6b8f5fad9b76daa0a68497bc6f129858ad956331a5835785761e003"}, - {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3c53687dde4d9d473c587ae80cc328e5b102b517447456184b485587ebd18b62"}, - {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9add2e5b33d2cd765ad96d5eb734a5e795a0755f7fc49aa04f76d7ddda73fd70"}, - {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e690145a8c0c273c28d3b89d6fb32c45e0d9605b2293c10e650265bf5c11cfec"}, - {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:00a06faa7165634f0cac1abb27e54d7a0b3b44eb9994530b8ec73cf52e15353b"}, - {file = "pyzmq-25.1.2-cp37-cp37m-win32.whl", hash = "sha256:0f97bc2f1f13cb16905a5f3e1fbdf100e712d841482b2237484360f8bc4cb3d7"}, - {file = "pyzmq-25.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6cc0020b74b2e410287e5942e1e10886ff81ac77789eb20bec13f7ae681f0fdd"}, - {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:bef02cfcbded83473bdd86dd8d3729cd82b2e569b75844fb4ea08fee3c26ae41"}, - {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e10a4b5a4b1192d74853cc71a5e9fd022594573926c2a3a4802020360aa719d8"}, - {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8c5f80e578427d4695adac6fdf4370c14a2feafdc8cb35549c219b90652536ae"}, - {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5dde6751e857910c1339890f3524de74007958557593b9e7e8c5f01cd919f8a7"}, - {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea1608dd169da230a0ad602d5b1ebd39807ac96cae1845c3ceed39af08a5c6df"}, - {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0f513130c4c361201da9bc69df25a086487250e16b5571ead521b31ff6b02220"}, - {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:019744b99da30330798bb37df33549d59d380c78e516e3bab9c9b84f87a9592f"}, - {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2e2713ef44be5d52dd8b8e2023d706bf66cb22072e97fc71b168e01d25192755"}, - {file = "pyzmq-25.1.2-cp38-cp38-win32.whl", hash = "sha256:07cd61a20a535524906595e09344505a9bd46f1da7a07e504b315d41cd42eb07"}, - {file = "pyzmq-25.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb7e49a17fb8c77d3119d41a4523e432eb0c6932187c37deb6fbb00cc3028088"}, - {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:94504ff66f278ab4b7e03e4cba7e7e400cb73bfa9d3d71f58d8972a8dc67e7a6"}, - {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6dd0d50bbf9dca1d0bdea219ae6b40f713a3fb477c06ca3714f208fd69e16fd8"}, - {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:004ff469d21e86f0ef0369717351073e0e577428e514c47c8480770d5e24a565"}, - {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c0b5ca88a8928147b7b1e2dfa09f3b6c256bc1135a1338536cbc9ea13d3b7add"}, - {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9a79f1d2495b167119d02be7448bfba57fad2a4207c4f68abc0bab4b92925b"}, - {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:518efd91c3d8ac9f9b4f7dd0e2b7b8bf1a4fe82a308009016b07eaa48681af82"}, - {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1ec23bd7b3a893ae676d0e54ad47d18064e6c5ae1fadc2f195143fb27373f7f6"}, - {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db36c27baed588a5a8346b971477b718fdc66cf5b80cbfbd914b4d6d355e44e2"}, - {file = "pyzmq-25.1.2-cp39-cp39-win32.whl", hash = "sha256:39b1067f13aba39d794a24761e385e2eddc26295826530a8c7b6c6c341584289"}, - {file = "pyzmq-25.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:8e9f3fabc445d0ce320ea2c59a75fe3ea591fdbdeebec5db6de530dd4b09412e"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:df0c7a16ebb94452d2909b9a7b3337940e9a87a824c4fc1c7c36bb4404cb0cde"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:45999e7f7ed5c390f2e87ece7f6c56bf979fb213550229e711e45ecc7d42ccb8"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ac170e9e048b40c605358667aca3d94e98f604a18c44bdb4c102e67070f3ac9b"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b604734bec94f05f81b360a272fc824334267426ae9905ff32dc2be433ab96"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a793ac733e3d895d96f865f1806f160696422554e46d30105807fdc9841b9f7d"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0806175f2ae5ad4b835ecd87f5f85583316b69f17e97786f7443baaf54b9bb98"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ef12e259e7bc317c7597d4f6ef59b97b913e162d83b421dd0db3d6410f17a244"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea253b368eb41116011add00f8d5726762320b1bda892f744c91997b65754d73"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b9b1f2ad6498445a941d9a4fee096d387fee436e45cc660e72e768d3d8ee611"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8b14c75979ce932c53b79976a395cb2a8cd3aaf14aef75e8c2cb55a330b9b49d"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:889370d5174a741a62566c003ee8ddba4b04c3f09a97b8000092b7ca83ec9c49"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a18fff090441a40ffda8a7f4f18f03dc56ae73f148f1832e109f9bffa85df15"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99a6b36f95c98839ad98f8c553d8507644c880cf1e0a57fe5e3a3f3969040882"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4345c9a27f4310afbb9c01750e9461ff33d6fb74cd2456b107525bbeebcb5be3"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3516e0b6224cf6e43e341d56da15fd33bdc37fa0c06af4f029f7d7dfceceabbc"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:146b9b1f29ead41255387fb07be56dc29639262c0f7344f570eecdcd8d683314"}, - {file = "pyzmq-25.1.2.tar.gz", hash = "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226"}, -] - -[package.dependencies] -cffi = {version = "*", markers = "implementation_name == \"pypy\""} - -[[package]] -name = "referencing" -version = "0.32.1" -description = "JSON Referencing + Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "referencing-0.32.1-py3-none-any.whl", hash = "sha256:7e4dc12271d8e15612bfe35792f5ea1c40970dadf8624602e33db2758f7ee554"}, - {file = "referencing-0.32.1.tar.gz", hash = "sha256:3c57da0513e9563eb7e203ebe9bb3a1b509b042016433bd1e45a2853466c3dd3"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "rpds-py" -version = "0.16.2" -description = "Python bindings to Rust's persistent data structures (rpds)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rpds_py-0.16.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:509b617ac787cd1149600e731db9274ebbef094503ca25158e6f23edaba1ca8f"}, - {file = "rpds_py-0.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:413b9c17388bbd0d87a329d8e30c1a4c6e44e2bb25457f43725a8e6fe4161e9e"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2946b120718eba9af2b4dd103affc1164a87b9e9ebff8c3e4c05d7b7a7e274e2"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35ae5ece284cf36464eb160880018cf6088a9ac5ddc72292a6092b6ef3f4da53"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc6a7620ba7639a3db6213da61312cb4aa9ac0ca6e00dc1cbbdc21c2aa6eb57"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8cb6fe8ecdfffa0e711a75c931fb39f4ba382b4b3ccedeca43f18693864fe850"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dace7b26a13353e24613417ce2239491b40a6ad44e5776a18eaff7733488b44"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1bdbc5fcb04a7309074de6b67fa9bc4b418ab3fc435fec1f2779a0eced688d04"}, - {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f42e25c016927e2a6b1ce748112c3ab134261fc2ddc867e92d02006103e1b1b7"}, - {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:eab36eae3f3e8e24b05748ec9acc66286662f5d25c52ad70cadab544e034536b"}, - {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0474df4ade9a3b4af96c3d36eb81856cb9462e4c6657d4caecfd840d2a13f3c9"}, - {file = "rpds_py-0.16.2-cp310-none-win32.whl", hash = "sha256:84c5a4d1f9dd7e2d2c44097fb09fffe728629bad31eb56caf97719e55575aa82"}, - {file = "rpds_py-0.16.2-cp310-none-win_amd64.whl", hash = "sha256:2bd82db36cd70b3628c0c57d81d2438e8dd4b7b32a6a9f25f24ab0e657cb6c4e"}, - {file = "rpds_py-0.16.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:adc0c3d6fc6ae35fee3e4917628983f6ce630d513cbaad575b4517d47e81b4bb"}, - {file = "rpds_py-0.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ec23fcad480e77ede06cf4127a25fc440f7489922e17fc058f426b5256ee0edb"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07aab64e2808c3ebac2a44f67e9dc0543812b715126dfd6fe4264df527556cb6"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a4ebb8b20bd09c5ce7884c8f0388801100f5e75e7f733b1b6613c713371feefc"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3d7e2ea25d3517c6d7e5a1cc3702cffa6bd18d9ef8d08d9af6717fc1c700eed"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f28ac0e8e7242d140f99402a903a2c596ab71550272ae9247ad78f9a932b5698"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19f00f57fdd38db4bb5ad09f9ead1b535332dbf624200e9029a45f1f35527ebb"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3da5a4c56953bdbf6d04447c3410309616c54433146ccdb4a277b9cb499bc10e"}, - {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec2e1cf025b2c0f48ec17ff3e642661da7ee332d326f2e6619366ce8e221f018"}, - {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e0441fb4fdd39a230477b2ca9be90868af64425bfe7b122b57e61e45737a653b"}, - {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9f0350ef2fba5f34eb0c9000ea328e51b9572b403d2f7f3b19f24085f6f598e8"}, - {file = "rpds_py-0.16.2-cp311-none-win32.whl", hash = "sha256:5a80e2f83391ad0808b4646732af2a7b67550b98f0cae056cb3b40622a83dbb3"}, - {file = "rpds_py-0.16.2-cp311-none-win_amd64.whl", hash = "sha256:e04e56b4ca7a770593633556e8e9e46579d66ec2ada846b401252a2bdcf70a6d"}, - {file = "rpds_py-0.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5e6caa3809e50690bd92fa490f5c38caa86082c8c3315aa438bce43786d5e90d"}, - {file = "rpds_py-0.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e53b9b25cac9065328901713a7e9e3b12e4f57ef4280b370fbbf6fef2052eef"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af27423662f32d7501a00c5e7342f7dbd1e4a718aea7a239781357d15d437133"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43d4dd5fb16eb3825742bad8339d454054261ab59fed2fbac84e1d84d5aae7ba"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e061de3b745fe611e23cd7318aec2c8b0e4153939c25c9202a5811ca911fd733"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b811d182ad17ea294f2ec63c0621e7be92a1141e1012383461872cead87468f"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5552f328eaef1a75ff129d4d0c437bf44e43f9436d3996e8eab623ea0f5fcf73"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dcbe1f8dd179e4d69b70b1f1d9bb6fd1e7e1bdc9c9aad345cdeb332e29d40748"}, - {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8aad80645a011abae487d356e0ceb359f4938dfb6f7bcc410027ed7ae4f7bb8b"}, - {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6f5549d6ed1da9bfe3631ca9483ae906f21410be2445b73443fa9f017601c6f"}, - {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d452817e0d9c749c431a1121d56a777bd7099b720b3d1c820f1725cb40928f58"}, - {file = "rpds_py-0.16.2-cp312-none-win32.whl", hash = "sha256:888a97002e986eca10d8546e3c8b97da1d47ad8b69726dcfeb3e56348ebb28a3"}, - {file = "rpds_py-0.16.2-cp312-none-win_amd64.whl", hash = "sha256:d8dda2a806dfa4a9b795950c4f5cc56d6d6159f7d68080aedaff3bdc9b5032f5"}, - {file = "rpds_py-0.16.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:071980663c273bf3d388fe5c794c547e6f35ba3335477072c713a3176bf14a60"}, - {file = "rpds_py-0.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:726ac36e8a3bb8daef2fd482534cabc5e17334052447008405daca7ca04a3108"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9e557db6a177470316c82f023e5d571811c9a4422b5ea084c85da9aa3c035fc"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:90123853fc8b1747f80b0d354be3d122b4365a93e50fc3aacc9fb4c2488845d6"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a61f659665a39a4d17d699ab3593d7116d66e1e2e3f03ef3fb8f484e91908808"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc97f0640e91d7776530f06e6836c546c1c752a52de158720c4224c9e8053cad"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a54e99a2b9693a37ebf245937fd6e9228b4cbd64b9cc961e1f3391ec6c7391"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4b677d929cf1f6bac07ad76e0f2d5de367e6373351c01a9c0a39f6b21b4a8b"}, - {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5ef00873303d678aaf8b0627e111fd434925ca01c657dbb2641410f1cdaef261"}, - {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:349cb40897fd529ca15317c22c0eab67f5ac5178b5bd2c6adc86172045210acc"}, - {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2ddef620e70eaffebed5932ce754d539c0930f676aae6212f8e16cd9743dd365"}, - {file = "rpds_py-0.16.2-cp38-none-win32.whl", hash = "sha256:882ce6e25e585949c3d9f9abd29202367175e0aab3aba0c58c9abbb37d4982ff"}, - {file = "rpds_py-0.16.2-cp38-none-win_amd64.whl", hash = "sha256:f4bd4578e44f26997e9e56c96dedc5f1af43cc9d16c4daa29c771a00b2a26851"}, - {file = "rpds_py-0.16.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:69ac7ea9897ec201ce68b48582f3eb34a3f9924488a5432a93f177bf76a82a7e"}, - {file = "rpds_py-0.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a9880b4656efe36ccad41edc66789e191e5ee19a1ea8811e0aed6f69851a82f4"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee94cb58c0ba2c62ee108c2b7c9131b2c66a29e82746e8fa3aa1a1effbd3dcf1"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24f7a2eb3866a9e91f4599851e0c8d39878a470044875c49bd528d2b9b88361c"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca57468da2d9a660bcf8961637c85f2fbb2aa64d9bc3f9484e30c3f9f67b1dd7"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccd4e400309e1f34a5095bf9249d371f0fd60f8a3a5c4a791cad7b99ce1fd38d"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80443fe2f7b3ea3934c5d75fb0e04a5dbb4a8e943e5ff2de0dec059202b70a8b"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4d6a9f052e72d493efd92a77f861e45bab2f6be63e37fa8ecf0c6fd1a58fedb0"}, - {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:35953f4f2b3216421af86fd236b7c0c65935936a94ea83ddbd4904ba60757773"}, - {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:981d135c7cdaf6cd8eadae1c950de43b976de8f09d8e800feed307140d3d6d00"}, - {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d0dd7ed2f16df2e129496e7fbe59a34bc2d7fc8db443a606644d069eb69cbd45"}, - {file = "rpds_py-0.16.2-cp39-none-win32.whl", hash = "sha256:703d95c75a72e902544fda08e965885525e297578317989fd15a6ce58414b41d"}, - {file = "rpds_py-0.16.2-cp39-none-win_amd64.whl", hash = "sha256:e93ec1b300acf89730cf27975ef574396bc04edecc358e9bd116fb387a123239"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:44627b6ca7308680a70766454db5249105fa6344853af6762eaad4158a2feebe"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3f91df8e6dbb7360e176d1affd5fb0246d2b88d16aa5ebc7db94fd66b68b61da"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d904c5693e08bad240f16d79305edba78276be87061c872a4a15e2c301fa2c0"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:290a81cfbe4673285cdf140ec5cd1658ffbf63ab359f2b352ebe172e7cfa5bf0"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b634c5ec0103c5cbebc24ebac4872b045cccb9456fc59efdcf6fe39775365bd2"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a297a4d08cc67c7466c873c78039d87840fb50d05473db0ec1b7b03d179bf322"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2e75e17bd0bb66ee34a707da677e47c14ee51ccef78ed6a263a4cc965a072a1"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f1b9d9260e06ea017feb7172976ab261e011c1dc2f8883c7c274f6b2aabfe01a"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:162d7cd9cd311c1b0ff1c55a024b8f38bd8aad1876b648821da08adc40e95734"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:9b32f742ce5b57201305f19c2ef7a184b52f6f9ba6871cc042c2a61f0d6b49b8"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac08472f41ea77cd6a5dae36ae7d4ed3951d6602833af87532b556c1b4601d63"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:495a14b72bbe217f2695dcd9b5ab14d4f8066a00f5d209ed94f0aca307f85f6e"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d6b6937ae9eac6d6c0ca3c42774d89fa311f55adff3970fb364b34abde6ed3d"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a61226465bda9283686db8f17d02569a98e4b13c637be5a26d44aa1f1e361c2"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5cf6af100ffb5c195beec11ffaa8cf8523057f123afa2944e6571d54da84cdc9"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6df15846ee3fb2e6397fe25d7ca6624af9f89587f3f259d177b556fed6bebe2c"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1be2f033df1b8be8c3167ba3c29d5dca425592ee31e35eac52050623afba5772"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96f957d6ab25a78b9e7fc9749d754b98eac825a112b4e666525ce89afcbd9ed5"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:088396c7c70e59872f67462fcac3ecbded5233385797021976a09ebd55961dfe"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4c46ad6356e1561f2a54f08367d1d2e70a0a1bb2db2282d2c1972c1d38eafc3b"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:47713dc4fce213f5c74ca8a1f6a59b622fc1b90868deb8e8e4d993e421b4b39d"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:f811771019f063bbd0aa7bb72c8a934bc13ebacb4672d712fc1639cfd314cccc"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f19afcfc0dd0dca35694df441e9b0f95bc231b512f51bded3c3d8ca32153ec19"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a4b682c5775d6a3d21e314c10124599976809455ee67020e8e72df1769b87bc3"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c647ca87fc0ebe808a41de912e9a1bfef9acb85257e5d63691364ac16b81c1f0"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:302bd4983bbd47063e452c38be66153760112f6d3635c7eeefc094299fa400a9"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf721ede3eb7b829e4a9b8142bd55db0bdc82902720548a703f7e601ee13bdc3"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:358dafc89ce3894c7f486c615ba914609f38277ef67f566abc4c854d23b997fa"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cad0f59ee3dc35526039f4bc23642d52d5f6616b5f687d846bfc6d0d6d486db0"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cffa76b385dfe1e38527662a302b19ffb0e7f5cf7dd5e89186d2c94a22dd9d0c"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:83640a5d7cd3bff694747d50436b8b541b5b9b9782b0c8c1688931d6ee1a1f2d"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:ed99b4f7179d2111702020fd7d156e88acd533f5a7d3971353e568b6051d5c97"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4022b9dc620e14f30201a8a73898a873c8e910cb642bcd2f3411123bc527f6ac"}, - {file = "rpds_py-0.16.2.tar.gz", hash = "sha256:781ef8bfc091b19960fc0142a23aedadafa826bc32b433fdfe6fd7f964d7ef44"}, -] - -[[package]] -name = "ruff" -version = "0.1.11" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.1.11-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a7f772696b4cdc0a3b2e527fc3c7ccc41cdcb98f5c80fdd4f2b8c50eb1458196"}, - {file = "ruff-0.1.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:934832f6ed9b34a7d5feea58972635c2039c7a3b434fe5ba2ce015064cb6e955"}, - {file = "ruff-0.1.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea0d3e950e394c4b332bcdd112aa566010a9f9c95814844a7468325290aabfd9"}, - {file = "ruff-0.1.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9bd4025b9c5b429a48280785a2b71d479798a69f5c2919e7d274c5f4b32c3607"}, - {file = "ruff-0.1.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ad00662305dcb1e987f5ec214d31f7d6a062cae3e74c1cbccef15afd96611d"}, - {file = "ruff-0.1.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4b077ce83f47dd6bea1991af08b140e8b8339f0ba8cb9b7a484c30ebab18a23f"}, - {file = "ruff-0.1.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a88efecec23c37b11076fe676e15c6cdb1271a38f2b415e381e87fe4517f18"}, - {file = "ruff-0.1.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b25093dad3b055667730a9b491129c42d45e11cdb7043b702e97125bcec48a1"}, - {file = "ruff-0.1.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231d8fb11b2cc7c0366a326a66dafc6ad449d7fcdbc268497ee47e1334f66f77"}, - {file = "ruff-0.1.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:09c415716884950080921dd6237767e52e227e397e2008e2bed410117679975b"}, - {file = "ruff-0.1.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0f58948c6d212a6b8d41cd59e349751018797ce1727f961c2fa755ad6208ba45"}, - {file = "ruff-0.1.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:190a566c8f766c37074d99640cd9ca3da11d8deae2deae7c9505e68a4a30f740"}, - {file = "ruff-0.1.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6464289bd67b2344d2a5d9158d5eb81025258f169e69a46b741b396ffb0cda95"}, - {file = "ruff-0.1.11-py3-none-win32.whl", hash = "sha256:9b8f397902f92bc2e70fb6bebfa2139008dc72ae5177e66c383fa5426cb0bf2c"}, - {file = "ruff-0.1.11-py3-none-win_amd64.whl", hash = "sha256:eb85ee287b11f901037a6683b2374bb0ec82928c5cbc984f575d0437979c521a"}, - {file = "ruff-0.1.11-py3-none-win_arm64.whl", hash = "sha256:97ce4d752f964ba559c7023a86e5f8e97f026d511e48013987623915431c7ea9"}, - {file = "ruff-0.1.11.tar.gz", hash = "sha256:f9d4d88cb6eeb4dfe20f9f0519bd2eaba8119bde87c3d5065c541dbae2b5a2cb"}, -] - -[[package]] -name = "setuptools" -version = "69.0.3" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, - {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = false -python-versions = "*" -files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] - -[[package]] -name = "sortedcontainers" -version = "2.4.0" -description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -optional = false -python-versions = "*" -files = [ - {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, - {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, -] - -[[package]] -name = "soupsieve" -version = "2.5" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.8" -files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, -] - -[[package]] -name = "sphinx" -version = "5.0.2" -description = "Python documentation generator" -optional = false -python-versions = ">=3.6" -files = [ - {file = "Sphinx-5.0.2-py3-none-any.whl", hash = "sha256:d3e57663eed1d7c5c50895d191fdeda0b54ded6f44d5621b50709466c338d1e8"}, - {file = "Sphinx-5.0.2.tar.gz", hash = "sha256:b18e978ea7565720f26019c702cd85c84376e948370f1cd43d60265010e1c7b0"}, -] - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.19" -imagesize = "*" -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" -requests = ">=2.5.0" -snowballstemmer = ">=1.1" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.950)", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest (>=4.6)", "typed-ast"] - -[[package]] -name = "sphinx-autodoc-typehints" -version = "1.19.1" -description = "Type hints (PEP 484) support for the Sphinx autodoc extension" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinx_autodoc_typehints-1.19.1-py3-none-any.whl", hash = "sha256:9be46aeeb1b315eb5df1f3a7cb262149895d16c7d7dcd77b92513c3c3a1e85e6"}, - {file = "sphinx_autodoc_typehints-1.19.1.tar.gz", hash = "sha256:6c841db55e0e9be0483ff3962a2152b60e79306f4288d8c4e7e86ac84486a5ea"}, -] - -[package.dependencies] -Sphinx = ">=4.5" - -[package.extras] -testing = ["covdefaults (>=2.2)", "coverage (>=6.3)", "diff-cover (>=6.4)", "nptyping (>=2.1.2)", "pytest (>=7.1)", "pytest-cov (>=3)", "sphobjinv (>=2)", "typing-extensions (>=4.1)"] -type-comments = ["typed-ast (>=1.5.2)"] - -[[package]] -name = "sphinx-book-theme" -version = "1.0.1" -description = "A clean book theme for scientific explanations and documentation with Sphinx" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinx_book_theme-1.0.1-py3-none-any.whl", hash = "sha256:d15f8248b3718a9a6be0ba617a32d1591f9fa39c614469bface777ba06a73b75"}, - {file = "sphinx_book_theme-1.0.1.tar.gz", hash = "sha256:927b399a6906be067e49c11ef1a87472f1b1964075c9eea30fb82c64b20aedee"}, -] - -[package.dependencies] -pydata-sphinx-theme = ">=0.13.3" -sphinx = ">=4,<7" - -[package.extras] -code-style = ["pre-commit"] -doc = ["ablog", "docutils (==0.17.1)", "folium", "ipywidgets", "matplotlib", "myst-nb", "nbclient", "numpy", "numpydoc", "pandas", "plotly", "sphinx-copybutton", "sphinx-design", "sphinx-examples", "sphinx-tabs (<=3.4.0)", "sphinx-thebe", "sphinx-togglebutton", "sphinxcontrib-bibtex", "sphinxcontrib-youtube", "sphinxext-opengraph"] -test = ["beautifulsoup4", "coverage", "myst-nb", "pytest", "pytest-cov", "pytest-regressions", "sphinx_thebe"] - -[[package]] -name = "sphinx-comments" -version = "0.0.3" -description = "Add comments and annotation to your documentation." -optional = false -python-versions = "*" -files = [ - {file = "sphinx-comments-0.0.3.tar.gz", hash = "sha256:00170afff27019fad08e421da1ae49c681831fb2759786f07c826e89ac94cf21"}, - {file = "sphinx_comments-0.0.3-py3-none-any.whl", hash = "sha256:1e879b4e9bfa641467f83e3441ac4629225fc57c29995177d043252530c21d00"}, -] - -[package.dependencies] -sphinx = ">=1.8" - -[package.extras] -code-style = ["black", "flake8 (>=3.7.0,<3.8.0)", "pre-commit (==1.17.0)"] -sphinx = ["myst-parser", "sphinx (>=2)", "sphinx-book-theme"] -testing = ["beautifulsoup4", "myst-parser", "pytest", "pytest-regressions", "sphinx (>=2)", "sphinx-book-theme"] - -[[package]] -name = "sphinx-copybutton" -version = "0.5.2" -description = "Add a copy button to each of your code cells." -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, - {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, -] - -[package.dependencies] -sphinx = ">=1.8" - -[package.extras] -code-style = ["pre-commit (==2.12.1)"] -rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] - -[[package]] -name = "sphinx-design" -version = "0.3.0" -description = "A sphinx extension for designing beautiful, view size responsive web components." -optional = false +name = "pydantic-core" +version = "2.14.6" +description = "" +optional = true python-versions = ">=3.7" files = [ - {file = "sphinx_design-0.3.0-py3-none-any.whl", hash = "sha256:823c1dd74f31efb3285ec2f1254caefed29d762a40cd676f58413a1e4ed5cc96"}, - {file = "sphinx_design-0.3.0.tar.gz", hash = "sha256:7183fa1fae55b37ef01bda5125a21ee841f5bbcbf59a35382be598180c4cefba"}, -] - -[package.dependencies] -sphinx = ">=4,<6" - -[package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -rtd = ["myst-parser (>=0.18.0,<0.19.0)"] -testing = ["myst-parser (>=0.18.0,<0.19.0)", "pytest (>=7.1,<8.0)", "pytest-cov", "pytest-regressions"] -theme-furo = ["furo (>=2022.06.04,<2022.07)"] -theme-pydata = ["pydata-sphinx-theme (>=0.9.0,<0.10.0)"] -theme-rtd = ["sphinx-rtd-theme (>=1.0,<2.0)"] -theme-sbt = ["sphinx-book-theme (>=0.3.0,<0.4.0)"] - -[[package]] -name = "sphinx-external-toc" -version = "0.3.1" -description = "A sphinx extension that allows the site-map to be defined in a single YAML file." -optional = false -python-versions = "~=3.7" -files = [ - {file = "sphinx_external_toc-0.3.1-py3-none-any.whl", hash = "sha256:cd93c1e7599327b2a728db12d9819068ce719c4b037ffc62e47f20ffb6310fb3"}, - {file = "sphinx_external_toc-0.3.1.tar.gz", hash = "sha256:9c8ea9980ea0e57bf3ce98f6a400f9b69eb1df808f7dd796c9c8cc1873d8b355"}, -] - -[package.dependencies] -click = ">=7.1,<9" -pyyaml = "*" -sphinx = ">=4,<6" - -[package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -rtd = ["myst-parser (>=0.17.0,<0.18.0)", "sphinx-book-theme (>=0.0.36)"] -testing = ["coverage", "pytest (>=7.1,<8.0)", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "sphinx-jupyterbook-latex" -version = "0.5.2" -description = "Latex specific features for jupyter book" -optional = false -python-versions = ">=3.6" -files = [ - {file = "sphinx_jupyterbook_latex-0.5.2-py3-none-any.whl", hash = "sha256:24de689689ddc27c736b15b91c6b9afdcdc31570938572693bb05bfff8f50758"}, - {file = "sphinx_jupyterbook_latex-0.5.2.tar.gz", hash = "sha256:da1d3ad028f55ddbf10b9130bb9f24fc60cafb671cbd39dfd95537aafc90972e"}, -] - -[package.dependencies] -sphinx = ">=4,<5.1" - -[package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -myst = ["myst-nb (>=0.13,<0.18)"] -rtd = ["myst-parser (<=0.18)", "sphinx-book-theme", "sphinx-design", "sphinx-jupyterbook-latex"] -testing = ["coverage (<5.0)", "myst-nb (>=0.13,<0.18)", "pytest (>=3.6,<4)", "pytest-cov (>=2.8,<3.0)", "pytest-regressions", "sphinx-external-toc (>=0.1.0,<0.3.0)", "sphinxcontrib-bibtex (>=2.2.1,<2.3.0)", "texsoup"] - -[[package]] -name = "sphinx-multitoc-numbering" -version = "0.1.3" -description = "Supporting continuous HTML section numbering" -optional = false -python-versions = "*" -files = [ - {file = "sphinx-multitoc-numbering-0.1.3.tar.gz", hash = "sha256:c9607671ac511236fa5d61a7491c1031e700e8d498c9d2418e6c61d1251209ae"}, - {file = "sphinx_multitoc_numbering-0.1.3-py3-none-any.whl", hash = "sha256:33d2e707a9b2b8ad636b3d4302e658a008025106fe0474046c651144c26d8514"}, -] - -[package.dependencies] -sphinx = ">=3" - -[package.extras] -code-style = ["black", "flake8 (>=3.7.0,<3.8.0)", "pre-commit (==1.17.0)"] -rtd = ["myst-parser", "sphinx (>=3.0)", "sphinx-book-theme"] -testing = ["coverage (<5.0)", "jupyter-book", "pytest (>=5.4,<6.0)", "pytest-cov (>=2.8,<3.0)", "pytest-regressions"] - -[[package]] -name = "sphinx-thebe" -version = "0.2.1" -description = "Integrate interactive code blocks into your documentation with Thebe and Binder." -optional = false -python-versions = "*" -files = [ - {file = "sphinx-thebe-0.2.1.tar.gz", hash = "sha256:f4c8c1542054f991b73fcb28c4cf21697e42aba2f83f22348c1c851b82766583"}, - {file = "sphinx_thebe-0.2.1-py3-none-any.whl", hash = "sha256:e8af555c90acba3541fa7108ea5981ae9c4bd406b54d9a242ab054d326ab7441"}, + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"}, + {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"}, + {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"}, + {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"}, + {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"}, + {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"}, + {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, + {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, + {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, + {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, + {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"}, + {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"}, + {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"}, + {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"}, + {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"}, + {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, ] [package.dependencies] -sphinx = ">=4,<7" - -[package.extras] -sphinx = ["matplotlib", "myst-nb", "sphinx-book-theme (>=0.4.0rc1)", "sphinx-copybutton", "sphinx-design"] -testing = ["beautifulsoup4", "matplotlib", "pytest", "pytest-regressions"] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] -name = "sphinx-togglebutton" -version = "0.3.2" -description = "Toggle page content and collapse admonitions in Sphinx." +name = "pytest" +version = "7.4.4" +description = "pytest: simple powerful testing with Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "sphinx-togglebutton-0.3.2.tar.gz", hash = "sha256:ab0c8b366427b01e4c89802d5d078472c427fa6e9d12d521c34fa0442559dc7a"}, - {file = "sphinx_togglebutton-0.3.2-py3-none-any.whl", hash = "sha256:9647ba7874b7d1e2d43413d8497153a85edc6ac95a3fea9a75ef9c1e08aaae2b"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] -docutils = "*" -setuptools = "*" -sphinx = "*" -wheel = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" [package.extras] -sphinx = ["matplotlib", "myst-nb", "numpy", "sphinx-book-theme", "sphinx-design", "sphinx-examples"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.7" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +name = "pytest-asyncio" +version = "0.21.1" +description = "Pytest support for asyncio" optional = false -python-versions = ">=3.9" +python-versions = ">=3.7" files = [ - {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"}, - {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"}, + {file = "pytest-asyncio-0.21.1.tar.gz", hash = "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d"}, + {file = "pytest_asyncio-0.21.1-py3-none-any.whl", hash = "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b"}, ] [package.dependencies] -Sphinx = ">=5" +pytest = ">=7.0.0" [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] [[package]] -name = "sphinxcontrib-bibtex" -version = "2.5.0" -description = "Sphinx extension for BibTeX style citations." +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.6" files = [ - {file = "sphinxcontrib-bibtex-2.5.0.tar.gz", hash = "sha256:71b42e5db0e2e284f243875326bf9936aa9a763282277d75048826fef5b00eaa"}, - {file = "sphinxcontrib_bibtex-2.5.0-py3-none-any.whl", hash = "sha256:748f726eaca6efff7731012103417ef130ecdcc09501b4d0c54283bf5f059f76"}, -] - -[package.dependencies] -docutils = ">=0.8" -pybtex = ">=0.24" -pybtex-docutils = ">=1.0.0" -Sphinx = ">=2.1" - -[[package]] -name = "sphinxcontrib-devhelp" -version = "1.0.5" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"}, - {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.4" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"}, - {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["html5lib", "pytest"] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] - -[package.extras] -test = ["flake8", "mypy", "pytest"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "1.0.6" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"}, - {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"}, -] - -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "1.1.9" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"}, - {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"}, + {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_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] -[package.dependencies] -Sphinx = ">=5" - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - [[package]] -name = "sqlalchemy" -version = "2.0.25" -description = "Database Abstraction Library" +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-win32.whl", hash = "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-win_amd64.whl", hash = "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-win32.whl", hash = "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-win32.whl", hash = "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-win_amd64.whl", hash = "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-win32.whl", hash = "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-win_amd64.whl", hash = "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-win32.whl", hash = "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-win_amd64.whl", hash = "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-win32.whl", hash = "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-win_amd64.whl", hash = "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7"}, - {file = "SQLAlchemy-2.0.25-py3-none-any.whl", hash = "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3"}, - {file = "SQLAlchemy-2.0.25.tar.gz", hash = "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08"}, + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} -typing-extensions = ">=4.6.0" +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" [package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] -aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "stack-data" -version = "0.6.3" -description = "Extract data from python stack frames and tracebacks for informative displays" +name = "ruff" +version = "0.1.11" +description = "An extremely fast Python linter and code formatter, written in Rust." optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, - {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, + {file = "ruff-0.1.11-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a7f772696b4cdc0a3b2e527fc3c7ccc41cdcb98f5c80fdd4f2b8c50eb1458196"}, + {file = "ruff-0.1.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:934832f6ed9b34a7d5feea58972635c2039c7a3b434fe5ba2ce015064cb6e955"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea0d3e950e394c4b332bcdd112aa566010a9f9c95814844a7468325290aabfd9"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9bd4025b9c5b429a48280785a2b71d479798a69f5c2919e7d274c5f4b32c3607"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ad00662305dcb1e987f5ec214d31f7d6a062cae3e74c1cbccef15afd96611d"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4b077ce83f47dd6bea1991af08b140e8b8339f0ba8cb9b7a484c30ebab18a23f"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a88efecec23c37b11076fe676e15c6cdb1271a38f2b415e381e87fe4517f18"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b25093dad3b055667730a9b491129c42d45e11cdb7043b702e97125bcec48a1"}, + {file = "ruff-0.1.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231d8fb11b2cc7c0366a326a66dafc6ad449d7fcdbc268497ee47e1334f66f77"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:09c415716884950080921dd6237767e52e227e397e2008e2bed410117679975b"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0f58948c6d212a6b8d41cd59e349751018797ce1727f961c2fa755ad6208ba45"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:190a566c8f766c37074d99640cd9ca3da11d8deae2deae7c9505e68a4a30f740"}, + {file = "ruff-0.1.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6464289bd67b2344d2a5d9158d5eb81025258f169e69a46b741b396ffb0cda95"}, + {file = "ruff-0.1.11-py3-none-win32.whl", hash = "sha256:9b8f397902f92bc2e70fb6bebfa2139008dc72ae5177e66c383fa5426cb0bf2c"}, + {file = "ruff-0.1.11-py3-none-win_amd64.whl", hash = "sha256:eb85ee287b11f901037a6683b2374bb0ec82928c5cbc984f575d0437979c521a"}, + {file = "ruff-0.1.11-py3-none-win_arm64.whl", hash = "sha256:97ce4d752f964ba559c7023a86e5f8e97f026d511e48013987623915431c7ea9"}, + {file = "ruff-0.1.11.tar.gz", hash = "sha256:f9d4d88cb6eeb4dfe20f9f0519bd2eaba8119bde87c3d5065c541dbae2b5a2cb"}, ] -[package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - [[package]] -name = "tabulate" -version = "0.9.0" -description = "Pretty-print tabular data" +name = "setuptools" +version = "69.0.3" +description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, - {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, + {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, + {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, ] [package.extras] -widechars = ["wcwidth"] - -[[package]] -name = "tornado" -version = "6.4" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -optional = false -python-versions = ">= 3.8" -files = [ - {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, - {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, - {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, - {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, - {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, -] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] -name = "traitlets" -version = "5.14.1" -description = "Traitlets Python configuration system" +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" optional = false -python-versions = ">=3.8" +python-versions = "*" files = [ - {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, - {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] - [[package]] name = "typing-extensions" version = "4.9.0" @@ -2765,20 +752,6 @@ files = [ {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] -[[package]] -name = "uc-micro-py" -version = "1.0.2" -description = "Micro subset of unicode data files for linkify-it-py projects." -optional = false -python-versions = ">=3.7" -files = [ - {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"}, - {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"}, -] - -[package.extras] -test = ["coverage", "pytest", "pytest-cov"] - [[package]] name = "urllib3" version = "2.1.0" @@ -2815,46 +788,6 @@ platformdirs = ">=3.9.1,<5" docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] -[[package]] -name = "wcwidth" -version = "0.2.13" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = "*" -files = [ - {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, - {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, -] - -[[package]] -name = "wheel" -version = "0.42.0" -description = "A built-package format for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "wheel-0.42.0-py3-none-any.whl", hash = "sha256:177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d"}, - {file = "wheel-0.42.0.tar.gz", hash = "sha256:c45be39f7882c9d34243236f2d63cbd58039e360f85d0913425fbd7ceea617a8"}, -] - -[package.extras] -test = ["pytest (>=6.0.0)", "setuptools (>=65)"] - -[[package]] -name = "zipp" -version = "3.17.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - [extras] all = ["pydantic"] pydantic = ["pydantic"] @@ -2862,4 +795,4 @@ pydantic = ["pydantic"] [metadata] lock-version = "2.0" python-versions = ">= 3.11, < 4" -content-hash = "8c5dee9a3edbf0295034949b3c76b695bd4515f4fc6ef5e9633818518a38288c" +content-hash = "8115179acfb55a6f8c417e3fe2982a7b1a6f91e36dccddf4dbd03eff42ceae35" diff --git a/pyproject.toml b/pyproject.toml index 452bc0f6..5a1e3950 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,28 +25,21 @@ typing-extensions = "^4.1.1" pydantic = {version = "^2.0.0", optional = true} -[tool.poetry.dev-dependencies] +[tool.poetry.group.dev.dependencies] pytest-asyncio = "^0.21.0" pytest = "^7.2.0" coverage = "^6.4.3" -black = "^23.0.0" -isort = "^5.10.1" -flake8 = "^6.0.0" coveralls = "^3.3.1" pre-commit = "^3.0.0" -autoflake = "^2.0" dunamai = "^1.12.0" hypothesis = "^6.54.2" -jupyter-book = "^0.15.0" -sphinx-autodoc-typehints = "^1.17.0" +ruff = "^0.1.11" [tool.poetry.extras] pydantic = ["pydantic"] all = ["pydantic"] -[tool.poetry.group.dev.dependencies] -ruff = "^0.1.11" [tool.black] line-length = 88 From 0672102e33aff578de3451ba35ebb27199bde665 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 22:00:46 +0100 Subject: [PATCH 19/39] Fix typo --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index bf76124a..a1b0a813 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", 3.12"] + python-version: ["3.11", "3.12"] steps: - uses: actions/checkout@v3 From f3d75c44b82c15c302ef160d8c3f09642d9d6781 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 22:10:23 +0100 Subject: [PATCH 20/39] Update config --- pyproject.toml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5a1e3950..357aec1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,20 +41,6 @@ pydantic = ["pydantic"] all = ["pydantic"] -[tool.black] -line-length = 88 -target-version = ['py310'] -include = '\.py$' -extend-exclude = '^/docs' - -[tool.isort] -profile = "black" -line_length=88 # corresponds to -w flag -multi_line_output=3 # corresponds to -m flag -include_trailing_comma=true # corresponds to -tc flag -src_paths = ["expression"] -float_to_top=true - [tool.ruff] # Keep in sync with .pre-commit-config.yaml line-length = 120 From 29f87b4e2a9d9401e306812159a4e71741b31b3d Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 22:15:27 +0100 Subject: [PATCH 21/39] Simplify build --- .github/workflows/python-package.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index a1b0a813..e285ec03 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -26,8 +26,7 @@ jobs: - name: Install dependencies run: | - pip install poetry - poetry config installer.modern-installation false + pipx install poetry poetry install --all-extras - name: Code checks From 1c0cd8812ecf5c8f488d163780d4b9087bcd96ec Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 7 Jan 2024 22:29:11 +0100 Subject: [PATCH 22/39] Remove jb from pre commit --- .pre-commit-config.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6dfecb90..f04bb602 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,8 +16,3 @@ repos: types: [python] additional_dependencies: ["pyright@1.1.344"] repo: local - - hooks: - - id: jb-to-sphinx - args: ["docs"] - repo: https://github.com/executablebooks/jupyter-book - rev: v0.12.1 From 91569b59aa3aac560ca1d3e9f8e91b0151decb1b Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Mon, 8 Jan 2024 08:47:49 +0100 Subject: [PATCH 23/39] Add more union tests --- expression/core/union.py | 8 +++- tests/test_union.py | 97 +++++++++++++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 23 deletions(-) diff --git a/expression/core/union.py b/expression/core/union.py index 97a7790c..cac10421 100644 --- a/expression/core/union.py +++ b/expression/core/union.py @@ -8,13 +8,16 @@ @dataclass_transform() -def tagged_union(_cls: type[_T] | None = None, *, frozen: bool = False) -> Callable[[type[_T]], type[_T]] | type[_T]: +def tagged_union( + _cls: type[_T] | None = None, *, frozen: bool = False, repr: bool = True +) -> Callable[[type[_T]], type[_T]] | type[_T]: """Tagged union decorator. A decorator that turns a dataclass into a tagged union. Arguments: frozen: Whether the tagged union should be frozen. + repr: If True, the __repr__ method will be generated. """ def transform(cls: type[_T]) -> type[_T]: @@ -83,7 +86,8 @@ def __deepcopy__(self: Any, memo: Any) -> Any: cls.__eq__ = __eq__ # type: ignore cls.__init__ = __init__ # type: ignore - cls.__repr__ = __repr__ # type: ignore + if repr: + cls.__repr__ = __repr__ # type: ignore cls.__hash__ = __hash__ # type: ignore cls.__match_args__ = tuple(field_names) # type: ignore diff --git a/tests/test_union.py b/tests/test_union.py index 8b0f4b1c..c2407203 100644 --- a/tests/test_union.py +++ b/tests/test_union.py @@ -176,63 +176,95 @@ class Email: def test_single_case_union_works(): email = Email(email="test@test.com") + + # Test attribute access + assert email.email == "test@test.com" + assert email.tag == "email" # type: ignore + + # Test pattern matching match email: case Email(email=e): assert e == "test@test.com" case _: # pyright: ignore assert False +@tagged_union(frozen=True, repr=False) +class SecurePassword: + password: str = case() + + # Override __str__ and __repr__ to make sure we don't leak the password in logs + def __str__(self) -> str: + return "********" + def __repr__(self) -> str: + return f"SecurePassword(password='********')" + +def test_single_case_union_secure_password_works(): + password = SecurePassword(password="secret") + # Test attribute access + assert password.password == "secret" + assert password.tag == "password" # type: ignore + + # Test pattern matching + match password: + case SecurePassword(password=p): + assert p == "secret" + + # Test __str__ + assert str(password) == "********" + + # Test __repr__ + assert repr(password) == "SecurePassword(password='********')" @tagged_union class Suit: tag: Literal["spades", "hearts", "clubs", "diamonds"] = tag() - spades: None = case() - hearts: None = case() - clubs: None = case() - diamonds: None = case() + spades: bool = case() + hearts: bool = case() + clubs: bool = case() + diamonds: bool = case() @staticmethod def Spades() -> Suit: - return Suit(spades=None) + return Suit(spades=True) @staticmethod def Hearts() -> Suit: - return Suit(hearts=None) + return Suit(hearts=True) @staticmethod def Clubs() -> Suit: - return Suit(clubs=None) + return Suit(clubs=True) @staticmethod def Diamonds() -> Suit: - return Suit(diamonds=None) + return Suit(diamonds=True) @tagged_union class Face: tag: Literal["jack", "queen", "king", "ace"] = tag() - jack: None = case() - queen: None = case() - king: None = case() - ace: None = case() + jack: bool = case() + queen: bool = case() + king: bool = case() + ace: bool = case() @staticmethod def Jack() -> Face: - return Face(jack=None) + return Face(jack=True) @staticmethod def Queen() -> Face: - return Face(queen=None) + return Face(queen=True) @staticmethod def King() -> Face: - return Face(king=None) + return Face(king=True) @staticmethod def Ace() -> Face: - return Face(ace=None) + return Face(ace=True) @tagged_union @@ -241,7 +273,7 @@ class Card: face_card: tuple[Suit, Face] = case() value_card: tuple[Suit, int] = case() - joker: None = case() + joker: bool = case() @staticmethod def Face(suit: Suit, face: Face) -> Card: @@ -249,25 +281,27 @@ def Face(suit: Suit, face: Face) -> Card: @staticmethod def Value(suit: Suit, value: int) -> Card: + if value < 1 or value > 10: + raise ValueError("Value must be between 1 and 10") return Card(value_card=(suit, value)) @staticmethod def Joker() -> Card: - return Card(joker=None) + return Card(joker=True) def test_rummy_score(): def score(card: Card) -> int: match card: - case Card(tag="face_card", face_card=(Suit(spades=None), Face(queen=None))): + case Card(tag="face_card", face_card=(Suit(spades=True), Face(queen=True))): return 40 - case Card(tag="face_card", face_card=(_suit, Face(ace=None))): + case Card(tag="face_card", face_card=(_suit, Face(ace=True))): return 15 case Card(tag="face_card", face_card=(_suit, _face)): return 10 case Card(tag="value_card", value_card=(_suit, value)): return value - case Card(tag="joker", joker=None): + case Card(tag="joker", joker=True): return 0 case _: raise AssertionError("Should not match") @@ -279,3 +313,24 @@ def score(card: Card) -> int: assert score(Card.Face(Suit.Spades(), Face.King())) == 10 assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Hearts(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Hearts(), Face.King())) == 10 + assert score(Card.Face(Suit.Clubs(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Clubs(), Face.King())) == 10 + assert score(Card.Face(Suit.Clubs(), Face.Queen())) == 10 + assert score(Card.Face(Suit.Clubs(), Face.Jack())) == 10 + assert score(Card.Face(Suit.Diamonds(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Diamonds(), Face.King())) == 10 + assert score(Card.Face(Suit.Diamonds(), Face.Queen())) == 10 + assert score(Card.Face(Suit.Diamonds(), Face.Jack())) == 10 + assert score(Card.Value(Suit.Hearts(), 1)) == 1 + assert score(Card.Value(Suit.Hearts(), 2)) == 2 + assert score(Card.Value(Suit.Hearts(), 3)) == 3 + assert score(Card.Value(Suit.Hearts(), 4)) == 4 + assert score(Card.Value(Suit.Hearts(), 5)) == 5 + assert score(Card.Value(Suit.Hearts(), 6)) == 6 + assert score(Card.Value(Suit.Hearts(), 7)) == 7 + assert score(Card.Value(Suit.Hearts(), 8)) == 8 + assert score(Card.Value(Suit.Hearts(), 9)) == 9 + assert score(Card.Value(Suit.Hearts(), 10)) == 10 + From 0683d59eb60eb6a48be428091123f87a663be7bb Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Mon, 8 Jan 2024 10:27:35 +0100 Subject: [PATCH 24/39] Format tests --- tests/test_array.py | 33 ++++++++++---------- tests/test_block.py | 13 ++++---- tests/test_cancellation.py | 8 ++--- tests/test_catch.py | 3 +- tests/test_compose.py | 3 +- tests/test_curried.py | 6 ++-- tests/test_disposable.py | 14 ++++----- tests/test_fn.py | 4 +-- tests/test_gen.py | 5 ++- tests/test_mailbox.py | 22 +++++-------- tests/test_map.py | 28 ++++++++--------- tests/test_option.py | 8 +++-- tests/test_option_effect.py | 4 ++- tests/test_parser.py | 4 ++- tests/test_pipe.py | 2 +- tests/test_result.py | 20 ++++++------ tests/test_seq.py | 62 ++++++++++++++++++------------------- tests/test_try.py | 1 - tests/test_typing.py | 10 +++--- tests/test_union.py | 18 +++++++---- 20 files changed, 134 insertions(+), 134 deletions(-) diff --git a/tests/test_array.py b/tests/test_array.py index d6aa6f45..d1949057 100644 --- a/tests/test_array.py +++ b/tests/test_array.py @@ -1,5 +1,6 @@ import functools -from typing import Any, Callable, List, Tuple +from collections.abc import Callable +from typing import Any import pytest from hypothesis import given # type: ignore @@ -8,6 +9,7 @@ from expression import Nothing, Option, Some, pipe from expression.collections import TypedArray, array + Func = Callable[[int], int] @@ -104,7 +106,7 @@ def test_array_filter_preserves_type(): @given(st.lists(st.integers())) # type: ignore -def test_array_length(xs: List[int]): +def test_array_length(xs: list[int]): ys = array.of_seq(xs) assert len(xs) == len(ys) @@ -141,7 +143,7 @@ def test_array_head_match_list(): @given(st.lists(st.integers(), min_size=1), st.integers(min_value=0)) # type: ignore -def test_array_item(xs: List[int], index: int): +def test_array_item(xs: list[int], index: int): ys = array.of_seq(xs) while index and index >= len(xs): index //= 2 @@ -149,7 +151,7 @@ def test_array_item(xs: List[int], index: int): @given(st.lists(st.integers())) # type: ignore -def test_array_pipe_map(xs: List[int]): +def test_array_pipe_map(xs: list[int]): def mapper(x: int): return x + 1 @@ -209,7 +211,7 @@ def mapper(x: int): @given(st.lists(st.integers())) # type: ignore -def test_array_len(xs: List[int]): +def test_array_len(xs: list[int]): ys = array.of_seq(xs) assert len(xs) == len(ys) @@ -226,7 +228,7 @@ def test_array_len(xs: List[int]): @given(st.lists(st.integers()), st.integers(min_value=0)) # type: ignore -def test_array_take(xs: List[int], x: int): +def test_array_take(xs: list[int], x: int): ys: TypedArray[int] try: ys = array.of_seq(xs).take(x) @@ -236,7 +238,7 @@ def test_array_take(xs: List[int], x: int): @given(st.lists(st.integers()), st.integers(min_value=0)) # type: ignore -def test_array_take_last(xs: List[int], x: int): +def test_array_take_last(xs: list[int], x: int): expected = xs[-x:] ys: TypedArray[int] ys = array.of_seq(xs).take_last(x) @@ -244,7 +246,7 @@ def test_array_take_last(xs: List[int], x: int): @given(st.lists(st.integers()), st.integers(min_value=0)) # type: ignore -def test_array_skip(xs: List[int], x: int): +def test_array_skip(xs: list[int], x: int): ys: TypedArray[int] try: ys = array.of_seq(xs).skip(x) @@ -254,7 +256,7 @@ def test_array_skip(xs: List[int], x: int): @given(st.lists(st.integers()), st.integers(min_value=0)) # type: ignore -def test_array_skip_last(xs: List[int], x: int): +def test_array_skip_last(xs: list[int], x: int): expected = xs[:-x] ys: TypedArray[int] ys = array.of_seq(xs).skip_last(x) @@ -272,7 +274,7 @@ def test_array_skip_last(xs: List[int], x: int): @given(st.lists(st.integers(), min_size=1), st.integers(min_value=0)) # type: ignore -def test_array_index(xs: List[int], x: int): +def test_array_index(xs: list[int], x: int): x = x % len(xs) if x > 0 else x expected = xs[x] @@ -288,7 +290,7 @@ def test_array_index(xs: List[int], x: int): @given(st.lists(st.integers())) # type: ignore -def test_array_indexed(xs: List[int]): +def test_array_indexed(xs: list[int]): expected = list(enumerate(xs)) ys: TypedArray[int] = array.of_seq(xs) @@ -298,7 +300,7 @@ def test_array_indexed(xs: List[int]): @given(st.lists(st.integers())) # type: ignore -def test_array_fold(xs: List[int]): +def test_array_fold(xs: list[int]): def folder(x: int, y: int) -> int: return x + y @@ -312,7 +314,7 @@ def folder(x: int, y: int) -> int: @given(st.integers(max_value=100)) # type: ignore def test_array_unfold(x: int): - def unfolder(state: int) -> Option[Tuple[int, int]]: + def unfolder(state: int) -> Option[tuple[int, int]]: if state < x: return Some((state, state + 1)) return Nothing @@ -323,7 +325,7 @@ def unfolder(state: int) -> Option[Tuple[int, int]]: @given(st.lists(st.integers()), st.integers()) # type: ignore -def test_array_filter(xs: List[int], limit: int): +def test_array_filter(xs: list[int], limit: int): expected = filter(lambda x: x < limit, xs) ys: TypedArray[int] = array.of_seq(xs) @@ -378,7 +380,6 @@ def test_array_monad_law_left_identity(value: int): return x >>= f is the same thing as f x """ - f: Callable[[int], TypedArray[int]] = lambda x: rtn(x + 42) assert rtn(value).collect(f) == f(value) @@ -420,7 +421,7 @@ def test_array_monad_law_associativity_empty(value: int): @given(st.lists(st.integers())) # type: ignore -def test_array_monad_law_associativity_iterable(xs: List[int]): +def test_array_monad_law_associativity_iterable(xs: list[int]): # (m >>= f) >>= g is just like doing m >>= (\x -> f x >>= g) f: Callable[[int], TypedArray[int]] = lambda x: rtn(x + 10) g: Callable[[int], TypedArray[int]] = lambda y: rtn(y * 42) diff --git a/tests/test_block.py b/tests/test_block.py index fb287c42..7664c054 100644 --- a/tests/test_block.py +++ b/tests/test_block.py @@ -1,6 +1,7 @@ import functools from builtins import list as list -from typing import Any, Callable, List, Tuple +from collections.abc import Callable +from typing import Any, List from hypothesis import given # type: ignore from hypothesis import strategies as st @@ -9,6 +10,7 @@ from expression import Nothing, Option, Some, pipe from expression.collections import Block, block + Func = Callable[[int], int] @@ -128,7 +130,7 @@ def mapper(x: int): @given(st.lists(st.tuples(st.integers(), st.integers()))) # type: ignore -def test_seq_pipe_starmap(xs: List[Tuple[int, int]]): +def test_seq_pipe_starmap(xs: List[tuple[int, int]]): mapper: Callable[[int, int], int] = lambda x, y: x + y ys = pipe( block.of_seq(xs), @@ -140,7 +142,7 @@ def test_seq_pipe_starmap(xs: List[Tuple[int, int]]): @given(st.lists(st.tuples(st.integers(), st.integers()))) # type: ignore -def test_seq_pipe_map2(xs: List[Tuple[int, int]]): +def test_seq_pipe_map2(xs: List[tuple[int, int]]): mapper: Callable[[int, int], int] = lambda x, y: x + y ys = pipe( block.of_seq(xs), @@ -152,7 +154,7 @@ def test_seq_pipe_map2(xs: List[Tuple[int, int]]): @given(st.lists(st.tuples(st.integers(), st.integers(), st.integers()))) # type: ignore -def test_seq_pipe_map3(xs: List[Tuple[int, int, int]]): +def test_seq_pipe_map3(xs: List[tuple[int, int, int]]): mapper: Callable[[int, int, int], int] = lambda x, y, z: x + y + z ys = pipe( block.of_seq(xs), @@ -279,7 +281,7 @@ def folder(x: int, y: int) -> int: @given(st.integers(max_value=100)) # type: ignore def test_block_unfold(x: int): - def unfolder(state: int) -> Option[Tuple[int, int]]: + def unfolder(state: int) -> Option[tuple[int, int]]: if state < x: return Some((state, state + 1)) return Nothing @@ -356,7 +358,6 @@ def test_block_monad_law_left_identity(value: int): return x >>= f is the same thing as f x """ - f: Callable[[int], Block[int]] = lambda x: rtn(x + 42) assert rtn(value).collect(f) == f(value) diff --git a/tests/test_cancellation.py b/tests/test_cancellation.py index 7df950cf..6a040b7c 100644 --- a/tests/test_cancellation.py +++ b/tests/test_cancellation.py @@ -1,5 +1,3 @@ -from typing import List - import pytest from expression.system import ( @@ -63,7 +61,7 @@ def test_token_disposing_works(): def test_token_cancellation_register_works(): - called: List[bool] = [] + called: list[bool] = [] source = CancellationTokenSource() with source: token = source.token @@ -74,7 +72,7 @@ def test_token_cancellation_register_works(): def test_token_cancellation_register_unregister_works(): - called: List[bool] = [] + called: list[bool] = [] source = CancellationTokenSource() with source as _: token = source.token @@ -86,7 +84,7 @@ def test_token_cancellation_register_unregister_works(): def test_token_cancelled_register_throws(): - called: List[bool] = [] + called: list[bool] = [] source = CancellationTokenSource.cancelled_source() with pytest.raises(ObjectDisposedException): diff --git a/tests/test_catch.py b/tests/test_catch.py index 17307326..0b39a780 100644 --- a/tests/test_catch.py +++ b/tests/test_catch.py @@ -1,4 +1,5 @@ -from typing import Any, Generator +from collections.abc import Generator +from typing import Any import pytest diff --git a/tests/test_compose.py b/tests/test_compose.py index 321162a1..51c22e9b 100644 --- a/tests/test_compose.py +++ b/tests/test_compose.py @@ -1,10 +1,11 @@ -from typing import Callable +from collections.abc import Callable from hypothesis import given # type: ignore from hypothesis import strategies as st from expression import compose, identity + Func = Callable[[int], int] diff --git a/tests/test_curried.py b/tests/test_curried.py index 67dafd27..3a466bcb 100644 --- a/tests/test_curried.py +++ b/tests/test_curried.py @@ -1,4 +1,4 @@ -from typing import Callable, List +from collections.abc import Callable import pytest @@ -100,7 +100,7 @@ def test_curry_flip_1(): xs = [1, 2, 3] @curry_flip(1) - def map(source: List[int], mapper: Callable[[int], int]): + def map(source: list[int], mapper: Callable[[int], int]): return [mapper(x) for x in source] ys = pipe( @@ -115,7 +115,7 @@ def test_curry_flip_2(): xs = [1, 2, 3] @curry_flip(2) - def map(a: int, source: List[int], mapper: Callable[[int], int]): + def map(a: int, source: list[int], mapper: Callable[[int], int]): return [mapper(x) + a for x in source] ys = pipe(xs, map(lambda x: x * 10)(10)) diff --git a/tests/test_disposable.py b/tests/test_disposable.py index 92bec911..548c7d9e 100644 --- a/tests/test_disposable.py +++ b/tests/test_disposable.py @@ -1,12 +1,10 @@ -from typing import List - import pytest from expression.system import AsyncDisposable, Disposable, ObjectDisposedException def test_disposable_works(): - called: List[bool] = [] + called: list[bool] = [] disp = Disposable.create(lambda: called.append(True)) with disp: @@ -16,7 +14,7 @@ def test_disposable_works(): def test_disposable_disposed(): - called: List[bool] = [] + called: list[bool] = [] disp = Disposable.create(lambda: called.append(True)) disp.dispose() assert called @@ -29,7 +27,7 @@ def test_disposable_disposed(): def test_disposable_disposed_twice_calls_once(): - called: List[bool] = [] + called: list[bool] = [] disp = Disposable.create(lambda: called.append(True)) disp.dispose() disp.dispose() @@ -39,7 +37,7 @@ def test_disposable_disposed_twice_calls_once(): @pytest.mark.asyncio async def test_async_disposable_works(): - called: List[bool] = [] + called: list[bool] = [] async def action(): called.append(True) @@ -54,7 +52,7 @@ async def action(): @pytest.mark.asyncio async def test_async_disposable_disposed(): - called: List[bool] = [] + called: list[bool] = [] async def action(): called.append(True) @@ -72,7 +70,7 @@ async def action(): @pytest.mark.asyncio async def test_async_disposable_disposed_twice_calls_once(): - called: List[bool] = [] + called: list[bool] = [] async def action(): called.append(True) diff --git a/tests/test_fn.py b/tests/test_fn.py index e702c7f3..7b629364 100644 --- a/tests/test_fn.py +++ b/tests/test_fn.py @@ -6,9 +6,7 @@ def test_factorial(): @tailrec - def factorial( - n: int, acc: int = 1 - ) -> Any: # Python 3.10: TailCallResult[int, [int, int]]: + def factorial(n: int, acc: int = 1) -> Any: # Python 3.10: TailCallResult[int, [int, int]]: if n == 0: return acc diff --git a/tests/test_gen.py b/tests/test_gen.py index 1f898b39..c579fc73 100644 --- a/tests/test_gen.py +++ b/tests/test_gen.py @@ -1,7 +1,6 @@ +"""This file is just to explore how generators works """ -This file is just to explore how generators works -""" -from typing import Generator +from collections.abc import Generator import pytest diff --git a/tests/test_mailbox.py b/tests/test_mailbox.py index 36df215c..74b9f958 100644 --- a/tests/test_mailbox.py +++ b/tests/test_mailbox.py @@ -1,5 +1,5 @@ import asyncio -from typing import Callable, List, Tuple +from collections.abc import Callable from hypothesis import given # type: ignore from hypothesis import strategies as st @@ -8,12 +8,12 @@ @given(st.lists(st.integers())) # type: ignore -def test_mailbox(xs: List[int]) -> None: - result: List[int] = [] +def test_mailbox(xs: list[int]) -> None: + result: list[int] = [] async def runner(): async def process(inbox: MailboxProcessor[int]) -> None: - """the message processing function.""" + """The message processing function.""" async def message_loop() -> None: msg: int = await inbox.receive() @@ -36,10 +36,8 @@ async def message_loop() -> None: @given(st.integers()) # type: ignore def test_mailbox_post_and_async_reply(x: int): async def runner(): - async def process( - inbox: MailboxProcessor[Tuple[int, AsyncReplyChannel[str]]] - ) -> None: - """the message processing function.""" + async def process(inbox: MailboxProcessor[tuple[int, AsyncReplyChannel[str]]]) -> None: + """The message processing function.""" async def message_loop() -> None: msg, rc = await inbox.receive() @@ -50,12 +48,8 @@ async def message_loop() -> None: # start the loop return await message_loop() - agent: MailboxProcessor[ - Tuple[int, AsyncReplyChannel[str]] - ] = MailboxProcessor.start(process) - build_message: Callable[ - [AsyncReplyChannel[str]], Tuple[int, AsyncReplyChannel[str]] - ] = lambda r: (x, r) + agent: MailboxProcessor[tuple[int, AsyncReplyChannel[str]]] = MailboxProcessor.start(process) + build_message: Callable[[AsyncReplyChannel[str]], tuple[int, AsyncReplyChannel[str]]] = lambda r: (x, r) reply = await agent.post_and_async_reply(build_message) assert reply == f"Got {x}" diff --git a/tests/test_map.py b/tests/test_map.py index 0f7fe553..da75f353 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -1,4 +1,4 @@ -from typing import Callable, Dict, ItemsView, Iterable, List, Tuple +from collections.abc import Callable, ItemsView, Iterable from hypothesis import given # type: ignore from hypothesis import strategies as st @@ -22,36 +22,36 @@ def test_map_non_empty(): @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_create(xs: Dict[str, int]): - items: Iterable[Tuple[str, int]] = xs.items() +def test_map_create(xs: dict[str, int]): + items: Iterable[tuple[str, int]] = xs.items() m = map.create(items) assert len(m) == len(xs) @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_of_seq(xs: Dict[str, int]): +def test_map_of_seq(xs: dict[str, int]): items: ItemsView[str, int] = xs.items() m = map.of_seq(items) assert len(m) == len(xs) @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_to_list_fluent(xs: Dict[str, int]): +def test_map_to_list_fluent(xs: dict[str, int]): items: ItemsView[str, int] = xs.items() ys = map.of_seq(items).to_list() assert sorted(xs.items()) == sorted(ys) @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_to_seq(xs: Dict[str, int]): - items: List[Tuple[str, int]] = list(xs.items()) +def test_map_to_seq(xs: dict[str, int]): + items: list[tuple[str, int]] = list(xs.items()) ys = map.of_list(items) zs = pipe(ys, map.to_seq) assert sorted(list(items)) == list(zs) @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_remove_fluent(xs: Dict[str, int]): +def test_map_remove_fluent(xs: dict[str, int]): items: ItemsView[str, int] = xs.items() m = Map.of_seq(items) @@ -64,7 +64,7 @@ def test_map_remove_fluent(xs: Dict[str, int]): @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_remove(xs: Dict[str, int]): +def test_map_remove(xs: dict[str, int]): items: ItemsView[str, int] = xs.items() m = Map.of_seq(items) @@ -77,7 +77,7 @@ def test_map_remove(xs: Dict[str, int]): @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_to_seq_fluent(xs: Dict[str, int]): +def test_map_to_seq_fluent(xs: dict[str, int]): items: ItemsView[str, int] = xs.items() ys = map.of_seq(items).to_seq() @@ -85,7 +85,7 @@ def test_map_to_seq_fluent(xs: Dict[str, int]): @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_to_list(xs: Dict[str, int]): +def test_map_to_list(xs: dict[str, int]): items = Block(xs.items()) ys = map.of_block(items).to_seq() @@ -93,7 +93,7 @@ def test_map_to_list(xs: Dict[str, int]): @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_map(xs: Dict[str, int]): +def test_map_map(xs: dict[str, int]): items = Block(xs.items()) mapper: Callable[[str, int], int] = lambda k, v: v * 20 @@ -112,14 +112,14 @@ def test_map_pipe_fluent(): @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_count(xs: Dict[str, int]): +def test_map_count(xs: dict[str, int]): ys: Map[str, int] = map.of(**xs) assert len(ys) == len(xs) == map.count(ys) @given(st.dictionaries(keys=st.text(), values=st.integers())) -def test_map_iterate(xs: Dict[str, int]): +def test_map_iterate(xs: dict[str, int]): ys = [k for k in map.of(**xs)] assert sorted(ys) == sorted(list(xs.keys())) diff --git a/tests/test_option.py b/tests/test_option.py index 567c35b0..1df464ec 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -1,10 +1,10 @@ -from typing import Any, Callable, Generator +from collections.abc import Callable, Generator +from typing import Any import pytest from hypothesis import given # type: ignore from hypothesis import strategies as st from pydantic import BaseModel -from tests.utils import CustomException from expression import ( Error, @@ -18,8 +18,9 @@ pipe, pipe2, ) -from expression.core.option import Option, Nothing, Some +from expression.core.option import Nothing, Option, Some from expression.extra.option import pipeline +from tests.utils import CustomException def test_option_some(): @@ -556,6 +557,7 @@ class Model(BaseModel): two: Option[str] = Nothing three: Option[float] = Nothing + def test_parse_option_works(): obj = dict(one=10, two=None) model = Model.model_validate(obj) diff --git a/tests/test_option_effect.py b/tests/test_option_effect.py index 42cc18e3..b601ecf6 100644 --- a/tests/test_option_effect.py +++ b/tests/test_option_effect.py @@ -1,7 +1,9 @@ -from typing import Generator, TypeVar +from collections.abc import Generator +from typing import TypeVar from expression import Nothing, Some, effect + T = TypeVar("T", float, int) diff --git a/tests/test_parser.py b/tests/test_parser.py index ddb16712..b80aeaa7 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from typing import Any, Literal -from expression import Option, case, tagged_union, pipe, tag, Result +from expression import Option, Result, case, pipe, tag, tagged_union from expression.collections import Block from expression.extra.parser import ( Parser, @@ -157,6 +157,7 @@ def test_negative_float_with_decimal(): case _: assert False + @tagged_union class ComparisonOperator: tag: Literal["EQ", "NOT_EQ", "LT", "LT_E", "GT", "GT_E", "IS", "IS_NOT", "IN", "NOT_IN"] = tag() @@ -187,6 +188,7 @@ class Compare: comparators: Block[Expression] ops: Block[ComparisonOperator] + @tagged_union class BoolOp: AND: None = case() diff --git a/tests/test_pipe.py b/tests/test_pipe.py index 67dc41ba..41115190 100644 --- a/tests/test_pipe.py +++ b/tests/test_pipe.py @@ -1,4 +1,4 @@ -from typing import Callable +from collections.abc import Callable from hypothesis import given # type: ignore from hypothesis import strategies as st diff --git a/tests/test_result.py b/tests/test_result.py index 8fffd50c..67836c6c 100644 --- a/tests/test_result.py +++ b/tests/test_result.py @@ -1,16 +1,18 @@ -from typing import Any, Callable, Generator, List +from collections.abc import Callable, Generator +from typing import Any import pytest from hypothesis import given # type: ignore from hypothesis import strategies as st from pydantic import BaseModel, TypeAdapter -from expression import Nothing, Option, Result, Some, effect, result, Ok, Error +from expression import Error, Nothing, Ok, Option, Result, Some, effect, result from expression.collections import Block from expression.extra.result import pipeline, sequence from .utils import CustomException + def test_pattern_match_with_alias(): xs: Result[int, str] = Ok(42) @@ -20,6 +22,7 @@ def test_pattern_match_with_alias(): case _: assert False + def test_result_ok(): xs: Result[int, str] = Result.Ok(42) @@ -204,7 +207,7 @@ def test_result_bind_piped(x: int, y: int): @given(st.lists(st.integers())) # type: ignore -def test_result_traverse_ok(xs: List[int]): +def test_result_traverse_ok(xs: list[int]): ys: Block[Result[int, str]] = Block([Ok(x) for x in xs]) zs = sequence(ys) match zs: @@ -215,11 +218,9 @@ def test_result_traverse_ok(xs: List[int]): @given(st.lists(st.integers(), min_size=5)) # type: ignore -def test_result_traverse_error(xs: List[int]): +def test_result_traverse_error(xs: list[int]): error = "Do'h" - ys: Block[Result[int, str]] = Block( - [Ok(x) if i == 3 else Error(error) for x, i in enumerate(xs)] - ) + ys: Block[Result[int, str]] = Block([Ok(x) if i == 3 else Error(error) for x, i in enumerate(xs)]) zs = sequence(ys) match zs: @@ -425,6 +426,7 @@ def test_model_to_json_works(): obj = model.model_dump_json() assert obj == '{"one":{"ok":10},"two":{"error":{"message":"error"}},"three":{"error":{"message":"error"}}}' + def test_error_default_value(): xs: Result[int, int] = Error(0) @@ -478,9 +480,7 @@ def test_result_of_option_error(): def test_result_of_option_with_ok(): - xs = result.of_option_with( - Some(42), error=lambda: exec('raise(Exception("Should not be called"))') - ) + xs = result.of_option_with(Some(42), error=lambda: exec('raise(Exception("Should not be called"))')) assert xs == Ok(42) diff --git a/tests/test_seq.py b/tests/test_seq.py index c91e2f97..73050201 100644 --- a/tests/test_seq.py +++ b/tests/test_seq.py @@ -1,6 +1,7 @@ import functools +from collections.abc import Callable, Iterable from itertools import accumulate -from typing import Any, Callable, Iterable, List, Optional, Tuple +from typing import Any, Optional import pytest from hypothesis import given # type: ignore @@ -33,7 +34,7 @@ def fn(): @given(st.lists(st.integers(), max_size=10)) # type: ignore -def test_seq_yield_for_in(xs: List[int]): +def test_seq_yield_for_in(xs: list[int]): @effect.seq[int]() def fn(): for x in xs: @@ -59,7 +60,7 @@ def fn(): @given(st.lists(st.integers())) # type: ignore -def test_seq_pipe_map(xs: List[int]): +def test_seq_pipe_map(xs: list[int]): mapper: Callable[[int], int] = lambda x: x + 1 ys = pipe(xs, seq.map(mapper)) @@ -68,7 +69,7 @@ def test_seq_pipe_map(xs: List[int]): @given(st.lists(st.tuples(st.integers(), st.integers()))) # type: ignore -def test_seq_pipe_starmap(xs: List[Tuple[int, int]]): +def test_seq_pipe_starmap(xs: list[tuple[int, int]]): mapper: Callable[[int, int], int] = lambda x, y: x + y ys = pipe(xs, seq.starmap(mapper)) @@ -77,7 +78,7 @@ def test_seq_pipe_starmap(xs: List[Tuple[int, int]]): @given(st.lists(st.tuples(st.integers(), st.integers()))) # type: ignore -def test_seq_pipe_map2(xs: List[Tuple[int, int]]): +def test_seq_pipe_map2(xs: list[tuple[int, int]]): mapper: Callable[[int, int], int] = lambda x, y: x + y ys = pipe(xs, seq.map2(mapper)) @@ -86,7 +87,7 @@ def test_seq_pipe_map2(xs: List[Tuple[int, int]]): @given(st.lists(st.tuples(st.integers(), st.integers(), st.integers()))) # type: ignore -def test_seq_pipe_map3(xs: List[Tuple[int, int, int]]): +def test_seq_pipe_map3(xs: list[tuple[int, int, int]]): mapper: Callable[[int, int, int], int] = lambda x, y, z: x + y + z ys = pipe(xs, seq.map3(mapper)) @@ -95,7 +96,7 @@ def test_seq_pipe_map3(xs: List[Tuple[int, int, int]]): @given(st.lists(st.integers())) # type: ignore -def test_seq_pipe_mapi(xs: List[int]): +def test_seq_pipe_mapi(xs: list[int]): mapper: Callable[[int, int], int] = lambda i, x: x + i ys = pipe(xs, seq.mapi(mapper)) @@ -104,7 +105,7 @@ def test_seq_pipe_mapi(xs: List[int]): @given(st.lists(st.integers(), min_size=1)) # type: ignore -def test_seq_head_pipe(xs: List[int]): +def test_seq_head_pipe(xs: list[int]): value = pipe(xs, seq.head) assert value == xs[0] @@ -120,14 +121,14 @@ def test_seq_head_empty_source(): @given(st.lists(st.integers(), min_size=1)) # type: ignore -def test_seq_head_fluent(xs: List[int]): +def test_seq_head_fluent(xs: list[int]): value = seq.of_iterable(xs).head() assert value == xs[0] @given(st.lists(st.integers(), min_size=1), st.integers()) # type: ignore -def test_seq_fold_pipe(xs: List[int], s: int): +def test_seq_fold_pipe(xs: list[int], s: int): folder: Callable[[int, int], int] = lambda s, v: s + v value = pipe(seq.of_iterable(xs), seq.fold(folder, s)) @@ -135,7 +136,7 @@ def test_seq_fold_pipe(xs: List[int], s: int): @given(st.lists(st.integers(), min_size=1), st.integers()) # type: ignore -def test_seq_fold_fluent(xs: List[int], s: int): +def test_seq_fold_fluent(xs: list[int], s: int): value = seq.of_iterable(xs).fold(lambda s, v: s + v, s) assert value == sum(xs) + s @@ -143,7 +144,7 @@ def test_seq_fold_fluent(xs: List[int], s: int): @given(st.integers(max_value=100)) # type: ignore def test_list_unfold(x: int): - def unfolder(state: int) -> Option[Tuple[int, int]]: + def unfolder(state: int) -> Option[tuple[int, int]]: if state < x: return Some((state, state + 1)) return Nothing @@ -154,7 +155,7 @@ def unfolder(state: int) -> Option[Tuple[int, int]]: @given(st.lists(st.integers(), min_size=1), st.integers()) # type: ignore -def test_seq_scan_pipe(xs: List[int], s: int): +def test_seq_scan_pipe(xs: list[int], s: int): func: Callable[[int, int], int] = lambda s, v: s + v value = pipe(seq.of_iterable(xs), seq.scan(func, s)) @@ -163,7 +164,7 @@ def test_seq_scan_pipe(xs: List[int], s: int): @given(st.lists(st.integers(), min_size=1), st.integers()) # type: ignore -def test_seq_scan_fluent(xs: List[int], s: int): +def test_seq_scan_fluent(xs: list[int], s: int): func: Callable[[int, int], int] = lambda s, v: s + v value = seq.of_iterable(xs).scan(func, s) @@ -172,49 +173,49 @@ def test_seq_scan_fluent(xs: List[int], s: int): @given(st.lists(st.integers())) # type: ignore -def test_seq_concat_1(xs: List[int]): +def test_seq_concat_1(xs: list[int]): value = seq.concat(xs) assert list(value) == xs @given(st.lists(st.integers()), st.lists(st.integers())) # type: ignore -def test_seq_concat_2(xs: List[int], ys: List[int]): +def test_seq_concat_2(xs: list[int], ys: list[int]): value = seq.concat(xs, ys) assert list(value) == xs + ys @given(st.lists(st.integers()), st.lists(st.integers()), st.lists(st.integers())) # type: ignore -def test_seq_concat_3(xs: List[int], ys: List[int], zs: List[int]): +def test_seq_concat_3(xs: list[int], ys: list[int], zs: list[int]): value = seq.concat(xs, ys, zs) assert list(value) == xs + ys + zs @given(st.lists(st.integers()), st.lists(st.integers())) # type: ignore -def test_seq_append_2(xs: List[int], ys: List[int]): +def test_seq_append_2(xs: list[int], ys: list[int]): value = pipe(xs, seq.append(ys)) assert list(value) == xs + ys @given(st.lists(st.integers()), st.lists(st.integers()), st.lists(st.integers())) # type: ignore -def test_seq_append_3(xs: List[int], ys: List[int], zs: List[int]): +def test_seq_append_3(xs: list[int], ys: list[int], zs: list[int]): value = pipe(xs, seq.append(ys, zs)) assert list(value) == xs + ys + zs @given(st.lists(st.integers()), st.lists(st.integers())) # type: ignore -def test_seq_append_fluent(xs: List[int], ys: List[int]): +def test_seq_append_fluent(xs: list[int], ys: list[int]): value = Seq(xs).append(ys) assert list(value) == xs + ys @given(st.lists(st.integers())) # type: ignore -def test_seq_collect(xs: List[int]): +def test_seq_collect(xs: list[int]): collector = seq.collect(seq.singleton) ys = pipe(xs, collector) @@ -222,7 +223,7 @@ def test_seq_collect(xs: List[int]): @given(st.lists(st.integers()), st.integers(min_value=0)) # type: ignore -def test_seq_skip(xs: List[int], x: int): +def test_seq_skip(xs: list[int], x: int): ys = seq.of_iterable(xs) try: zs = pipe(ys, seq.skip(x)) @@ -232,7 +233,7 @@ def test_seq_skip(xs: List[int], x: int): @given(st.lists(st.integers()), st.integers(min_value=0)) # type: ignore -def test_seq_take(xs: List[int], x: int): +def test_seq_take(xs: list[int], x: int): ys = seq.of_iterable(xs) try: zs = pipe(ys, seq.take(x)) @@ -249,21 +250,21 @@ def test_seq_take_is_lazy(): @given(st.lists(st.integers())) # type: ignore -def test_seq_length(xs: List[int]): +def test_seq_length(xs: list[int]): ys = seq.of_iterable(xs) n = pipe(ys, seq.length) assert n == len(xs) @given(st.lists(st.integers())) # type: ignore -def test_seq_len(xs: List[int]): +def test_seq_len(xs: list[int]): ys = seq.of_iterable(xs) n = ys.length() assert n == len(xs) @given(st.lists(st.integers())) # type: ignore -def test_seq_pipeline(xs: List[int]): +def test_seq_pipeline(xs: list[int]): mapper: Callable[[int], int] = lambda x: x * 10 predicate: Callable[[int], bool] = lambda x: x > 100 folder: Callable[[int, int], int] = lambda s, x: s + x @@ -273,13 +274,11 @@ def test_seq_pipeline(xs: List[int]): seq.filter(predicate), seq.fold(folder, 0), ) - assert ys == functools.reduce( - lambda s, x: s + x, filter(lambda x: x > 100, map(lambda x: x * 10, xs)), 0 - ) + assert ys == functools.reduce(lambda s, x: s + x, filter(lambda x: x > 100, map(lambda x: x * 10, xs)), 0) @given(st.lists(st.integers())) # type: ignore -def test_seq_delay(xs: List[int]): +def test_seq_delay(xs: list[int]): ran = False def generator(): @@ -312,7 +311,7 @@ def test_seq_choose_option_fluent(): @given(st.lists(st.integers())) # type: ignore -def test_seq_infinite(xs: List[int]): +def test_seq_infinite(xs: list[int]): ys = pipe(xs, seq.zip(seq.infinite)) expected = list(enumerate(xs)) @@ -345,7 +344,6 @@ def test_seq_monad_law_left_identity(value: int): return x >>= f is the same thing as f x """ - f: Callable[[int], Seq[int]] = lambda x: rtn(x + 42) assert list(rtn(value).collect(f)) == list(f(value)) diff --git a/tests/test_try.py b/tests/test_try.py index cef028c2..98ef5e12 100644 --- a/tests/test_try.py +++ b/tests/test_try.py @@ -1,7 +1,6 @@ from expression import Failure, Success, Try - def test_can_create_success(): Success(10) diff --git a/tests/test_typing.py b/tests/test_typing.py index 39afc6eb..dd5ad6df 100644 --- a/tests/test_typing.py +++ b/tests/test_typing.py @@ -1,4 +1,4 @@ -from typing import Any, List, cast +from typing import Any, cast import pytest @@ -87,18 +87,18 @@ def test_try_downcast_negative(): def test_try_cast_generic(): # Arrange - d: List[Derived] = [Derived()] + d: list[Derived] = [Derived()] # Act - b = try_downcast(List[Any], d) + b = try_downcast(list[Any], d) # Assert - assert isinstance(b, List) + assert isinstance(b, list) def test_try_cast_generic_negative(): # Arrange - d: List[Derived] = [Derived()] + d: list[Derived] = [Derived()] # Act b = try_downcast(str, d) diff --git a/tests/test_union.py b/tests/test_union.py index c2407203..feafec3d 100644 --- a/tests/test_union.py +++ b/tests/test_union.py @@ -7,6 +7,7 @@ from expression import case, tag, tagged_union + _T = TypeVar("_T") @@ -78,7 +79,7 @@ def test_union_can_add_custom_attributes_to_shape(): def test_union_cannot_change_case_value(): shape = Shape(circle=Circle(10.0)) with pytest.raises(TypeError): - shape.circle = Circle(20.0) # type: ignore + shape.circle = Circle(20.0) # type: ignore def test_union_compare_shapes(): @@ -123,6 +124,7 @@ def test_maybe_just_works(): case _: assert False + def test_maybe_nothing_works(): xs = Maybe[int](nothing=None) match xs: @@ -179,15 +181,16 @@ def test_single_case_union_works(): # Test attribute access assert email.email == "test@test.com" - assert email.tag == "email" # type: ignore + assert email.tag == "email" # type: ignore # Test pattern matching match email: case Email(email=e): assert e == "test@test.com" - case _: # pyright: ignore + case _: # pyright: ignore assert False + @tagged_union(frozen=True, repr=False) class SecurePassword: password: str = case() @@ -195,15 +198,17 @@ class SecurePassword: # Override __str__ and __repr__ to make sure we don't leak the password in logs def __str__(self) -> str: return "********" + def __repr__(self) -> str: - return f"SecurePassword(password='********')" + return "SecurePassword(password='********')" + def test_single_case_union_secure_password_works(): password = SecurePassword(password="secret") # Test attribute access assert password.password == "secret" - assert password.tag == "password" # type: ignore + assert password.tag == "password" # type: ignore # Test pattern matching match password: @@ -215,6 +220,8 @@ def test_single_case_union_secure_password_works(): # Test __repr__ assert repr(password) == "SecurePassword(password='********')" + + @tagged_union class Suit: tag: Literal["spades", "hearts", "clubs", "diamonds"] = tag() @@ -333,4 +340,3 @@ def score(card: Card) -> int: assert score(Card.Value(Suit.Hearts(), 8)) == 8 assert score(Card.Value(Suit.Hearts(), 9)) == 9 assert score(Card.Value(Suit.Hearts(), 10)) == 10 - From 0dccf48f039579d50b3121216ed11f038651d199 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Wed, 10 Jan 2024 07:23:13 +0100 Subject: [PATCH 25/39] Renamed files to tagged_union --- expression/core/__init__.py | 2 +- expression/core/option.py | 24 ++- expression/core/result.py | 6 +- expression/core/tagged_union.py | 127 +++++++++++ tests/test_option.py | 25 ++- tests/test_tagged_union.py | 363 ++++++++++++++++++++++++++++++++ 6 files changed, 533 insertions(+), 14 deletions(-) create mode 100644 expression/core/tagged_union.py create mode 100644 tests/test_tagged_union.py diff --git a/expression/core/__init__.py b/expression/core/__init__.py index 5a25143d..e4104807 100644 --- a/expression/core/__init__.py +++ b/expression/core/__init__.py @@ -21,7 +21,7 @@ try_downcast, upcast, ) -from .union import case, tag, tagged_union +from .tagged_union import case, tag, tagged_union __all__ = [ diff --git a/expression/core/option.py b/expression/core/option.py index 9ecbf475..d3acd459 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -9,14 +9,12 @@ import builtins from collections.abc import Callable, Generator, Iterable -from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, get_args, get_origin +from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, cast, get_args, get_origin from .curry import curry_flip from .error import EffectError from .pipe import PipeMixin - -# from .typing import ModelField -from .union import case, tag, tagged_union +from .tagged_union import case, tag, tagged_union if TYPE_CHECKING: @@ -35,7 +33,7 @@ _T2 = TypeVar("_T2") -@tagged_union +@tagged_union(frozen=True) class Option( Iterable[_TSource], PipeMixin, @@ -270,9 +268,19 @@ def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: raise EffectError(Nothing) def __lt__(self, other: Any) -> bool: - if isinstance(other, Option): - return self.value < other.value # type: ignore - return False + if not isinstance(other, Option): + return False + + other = cast(Option[Any], other) + match self, other: + case Option(tag="some", some=self_value), Option(tag="some", some=other_value): # type: ignore + return self_value < other_value # type: ignore + case _, Option(tag="none"): + return False + case Option(tag="none"), _: + return True + case _: + return False def __str__(self) -> str: match self: diff --git a/expression/core/result.py b/expression/core/result.py index 3c5f307b..6139dd0e 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -33,9 +33,7 @@ from .curry import curry_flip from .error import EffectError from .pipe import PipeMixin - -# from .typing import GenericValidator, ModelField, SupportsValidation -from .union import case, tag, tagged_union +from .tagged_union import case, tag, tagged_union _TSource = TypeVar("_TSource") @@ -44,7 +42,7 @@ _TError = TypeVar("_TError") -@tagged_union +@tagged_union(frozen=True) class Result( Iterable[_TSource], PipeMixin, diff --git a/expression/core/tagged_union.py b/expression/core/tagged_union.py new file mode 100644 index 00000000..f4ccb02f --- /dev/null +++ b/expression/core/tagged_union.py @@ -0,0 +1,127 @@ +from collections.abc import Callable +from copy import deepcopy +from dataclasses import dataclass, field, fields +from typing import Any, TypeVar, dataclass_transform + + +_T = TypeVar("_T") + + +@dataclass_transform() +def tagged_union( + _cls: type[_T] | None = None, *, frozen: bool = False, repr: bool = True, order: bool = False +) -> Callable[[type[_T]], type[_T]] | type[_T]: + """Tagged union decorator. + + A decorator that turns a dataclass into a tagged union. + + Arguments: + frozen: Whether the tagged union should be frozen. If True, + the __setattr__ and __delattr__ methods will be generated. + repr: If True, the __repr__ method will be generated. + order: If True, the __lt__ method will be generated. The first + case will be considered the smallest with index 0 and the + items will be compared as the tuple (index, value) + """ + + def transform(cls: type[_T]) -> type[_T]: + cls = dataclass(cls) # TODO: decide if we should be a dataclass or not + fields_ = fields(cls) # type: ignore + field_names = tuple(f.name for f in fields_) + original_init = cls.__init__ + + def __init__(self: Any, **kwargs: Any) -> None: + tag = kwargs.pop("tag", None) + if len(kwargs) != 1: + raise TypeError(f"One and only one case can be specified. Not {kwargs}") + name, value = next(iter(kwargs.items())) + if name not in field_names: + raise TypeError(f"Unknown case name: {name}") + if tag is not None and tag != name: + raise TypeError(f"Tag {tag} does not match case name {name}") + + # Cannot use setattr because it might be overridden for frozen classes + object.__setattr__(self, "tag", name) + object.__setattr__(self, name, value) + object.__setattr__(self, "__index", field_names.index(name)) + + # Enables the use of dataclasses.asdict + union_fields = dict((f.name, f) for f in fields_ if f.name in [name, "tag"]) + object.__setattr__(self, "__dataclass_fields__", union_fields) # type: ignore + original_init(self) + + def __repr__(self: Any) -> str: + return f"{cls.__name__}({self.tag}={getattr(self, self.tag)})" + + def __hash__(self: Any) -> int: + return hash((cls.__name__, self.tag, getattr(self, self.tag))) + + if order: + + def __lt__(self: Any, other: Any) -> bool: + if not isinstance(other, cls): + return False + + print("field names", field_names) + print((self.__index, getattr(self, self.tag)), (other.__index, getattr(other, other.tag))) + return (self.__index, getattr(self, self.tag)) < (other.__index, getattr(other, other.tag)) # type: ignore + + cls.__lt__ = __lt__ # type: ignore + + if frozen: + + def __setattr__(self: Any, name: str, value: Any) -> None: + if name in field_names: + raise TypeError("Cannot change the value of a tagged union case") + object.__setattr__(self, name, value) + + def __delattr__(self: Any, name: str) -> None: + if name in field_names: + raise TypeError("Cannot delete a tagged union case") + + object.__delattr__(self, name) + + cls.__setattr__ = __setattr__ + cls.__delattr__ = __delattr__ # type: ignore + + def __eq__(self: Any, other: Any) -> bool: + return ( + isinstance(other, cls) + and self.tag == getattr(other, "tag") + and getattr(self, self.tag) == getattr(other, self.tag) + ) + + def __copy__(self: Any) -> Any: + mapping = {self.tag: getattr(self, self.tag)} + return cls(**mapping) + + def __deepcopy__(self: Any, memo: Any) -> Any: + value = deepcopy(getattr(self, self.tag), memo) + mapping = {self.tag: value} + return cls(**mapping) + + cls.__eq__ = __eq__ # type: ignore + cls.__init__ = __init__ # type: ignore + if repr: + cls.__repr__ = __repr__ # type: ignore + cls.__hash__ = __hash__ # type: ignore + print("match args", field_names) + cls.__match_args__ = tuple(field_names) # type: ignore + + # We need to handle copy and deepcopy ourselves because they are needed by Pydantic + cls.__copy__ = __copy__ # type: ignore + cls.__deepcopy__ = __deepcopy__ # type: ignore + + return cls + + return transform if _cls is None else transform(_cls) + + +def case() -> Any: + """A case in a tagged union.""" + return field(init=False, kw_only=True) + + +def tag() -> Any: + """The tag of a tagged union.""" + return field(init=False, kw_only=True) diff --git a/tests/test_option.py b/tests/test_option.py index 1df464ec..58d144ec 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -106,6 +106,29 @@ def test_option_none_not_equals_some(): assert xs != ys assert ys != xs +def test_option_order_some_some_works(): + xs = Some(42) + ys = Some(41) + + assert xs > ys + assert ys < xs + + +def test_option_order_some_none_works(): + xs = Some(42) + ys = Nothing + + assert xs > ys + assert ys < xs + +def test_option_order_none_none_works(): + xs = Nothing + ys = Nothing + + assert not (xs < ys) + + + def test_option_none_default_value(): xs = Nothing @@ -201,7 +224,7 @@ def test_option_none_map(): assert ys is Nothing -@given(st.integers(), st.integers()) +@given(st.integers(), st.integers()) # type: ignore def test_option_some_map2_piped(x: int, y: int): xs = Some(x) ys = Some(y) diff --git a/tests/test_tagged_union.py b/tests/test_tagged_union.py new file mode 100644 index 00000000..0f20ac12 --- /dev/null +++ b/tests/test_tagged_union.py @@ -0,0 +1,363 @@ +from __future__ import annotations + +from dataclasses import asdict, dataclass +from typing import Generic, Literal, TypeVar + +import pytest + +from expression import case, tag, tagged_union + + +_T = TypeVar("_T") + + +@dataclass(unsafe_hash=True) +class Circle: + radius: float + + +@tagged_union(frozen=True) +class Shape: + tag: Literal["circle", "rectangle", "triangle"] = tag() + + circle: Circle = case() + rectangle: tuple[float, float] = case() + triangle: tuple[float, float] = case() + + +def test_union_create_shape_works(): + shape = Shape(circle=Circle(10.0)) + assert shape.circle.radius == 10.0 + + +def test_union_shape_tag_is_set(): + shape = Shape(circle=Circle(10.0)) + assert shape.tag == "circle" + + +def test_union_shape_circle_pattern_matching_works(): + shape = Shape(circle=Circle(10.0)) + + match shape: + case Shape(tag="rectangle", rectangle=(_, _)): + raise AssertionError("Should not match") + case Shape(tag="circle", circle=Circle(radius=r)): + assert r == 10.0 + case _: + assert False + + +def test_shape_rectangle_pattern_matching_works(): + shape = Shape(rectangle=(10.0, 20.0)) + + match shape: + case Shape(tag="circle", circle=Circle(radius=_)): + raise AssertionError("Should not match") + case Shape(tag="rectangle", rectangle=(w, h)): + assert w == 10.0 + assert h == 20.0 + case _: + assert False + + +def test_union_shape_hash_works(): + shape = Shape(circle=Circle(10.0)) + assert hash(shape) == hash(("Shape", "circle", Circle(10.0))) + + +def test_union_shape_repr_works(): + shape = Shape(circle=Circle(10.0)) + assert repr(shape) == "Shape(circle=Circle(radius=10.0))" + + +def test_union_can_add_custom_attributes_to_shape(): + shape = Shape(circle=Circle(10.0)) + setattr(shape, "custom", "rectangle") + assert getattr(shape, "custom") == "rectangle" + + +def test_union_cannot_change_case_value(): + shape = Shape(circle=Circle(10.0)) + with pytest.raises(TypeError): + shape.circle = Circle(20.0) # type: ignore + + +def test_union_compare_shapes(): + shape1 = Shape(circle=Circle(10.0)) + shape2 = Shape(circle=Circle(10.0)) + assert shape1 == shape2 + + shape3 = Shape(rectangle=(10.0, 20.0)) + assert shape1 != shape3 + + +def test_union_compare_shapes_with_different_tags(): + shape1 = Shape(circle=Circle(10.0)) + shape2 = Shape(rectangle=(10.0, 20.0)) + assert shape1 != shape2 + +@tagged_union(order=True, frozen=True) +class Maybe(Generic[_T]): + tag: Literal["just", "nothing"] = tag() + + nothing: None = case() + just: _T = case() + +def test_maybe_works(): + xs = Maybe(just=1) + match xs: + case Maybe(tag="just", just=x): + assert x == 1 + case _: + assert False + + +def test_maybe_just_works(): + xs = Maybe(just=1) + match xs: + case Maybe(tag="just", just=x): + assert x == 1 + case Maybe(tag="nothing", nothing=None): + assert False + case _: + assert False + + +def test_maybe_nothing_works(): + xs = Maybe[int](nothing=None) + match xs: + case Maybe(tag="nothing", nothing=None): + assert True + case _: + assert False + + +def test_nested_unions_works(): + xs = Maybe(just=Shape(circle=Circle(10.0))) + match xs: + case Maybe(tag="just", just=Shape(tag="circle", circle=Circle(radius=r))): + assert r == 10.0 + case _: + assert False + +def test_union_order_just_just_works(): + xs = Maybe(just=1) + ys = Maybe(just=2) + assert xs < ys + assert ys > xs + +def test_union_order_just_nothing_works(): + xs = Maybe(just=1) + ys = Maybe[int](nothing=None) + assert xs > ys + assert ys < xs + +def test_union_order_nothing_just_works(): + xs = Maybe[int](nothing=None) + ys = Maybe(just=1) + assert xs < ys + assert ys > xs + +def test_union_order_nothing_nothing_works(): + xs = Maybe[int](nothing=None) + ys = Maybe[int](nothing=None) + assert not xs < ys + assert not ys < xs + +def test_union_maybe_asdict_works(): + xs = Maybe(just=1) + assert asdict(xs) == {"tag": "just", "just": 1} + + +def test_unions_can_be_composed(): + @tagged_union + class Weather: + tag: Literal["sunny", "rainy"] = tag() + + sunny: bool = case() + rainy: bool = case() + + @tagged_union + class Day: + tag: Literal["weekday", "weekend"] = tag() + + weekday: Weather = case() + weekend: Weather = case() + + today = Day(weekday=Weather(sunny=True)) + match today: + case Day(tag="weekday", weekday=Weather(tag="sunny", sunny=s)): + assert s is True + case _: + assert False + + +@tagged_union +class Email: + email: str = case() + + +def test_single_case_union_works(): + email = Email(email="test@test.com") + + # Test attribute access + assert email.email == "test@test.com" + assert email.tag == "email" # type: ignore + + # Test pattern matching + match email: + case Email(email=e): + assert e == "test@test.com" + case _: # pyright: ignore + assert False + + +@tagged_union(frozen=True, repr=False) +class SecurePassword: + password: str = case() + + # Override __str__ and __repr__ to make sure we don't leak the password in logs + def __str__(self) -> str: + return "********" + + def __repr__(self) -> str: + return "SecurePassword(password='********')" + + +def test_single_case_union_secure_password_works(): + password = SecurePassword(password="secret") + + # Test attribute access + assert password.password == "secret" + assert password.tag == "password" # type: ignore + + # Test pattern matching + match password: + case SecurePassword(password=p): + assert p == "secret" + + # Test __str__ + assert str(password) == "********" + + # Test __repr__ + assert repr(password) == "SecurePassword(password='********')" + + +@tagged_union +class Suit: + tag: Literal["spades", "hearts", "clubs", "diamonds"] = tag() + + spades: bool = case() + hearts: bool = case() + clubs: bool = case() + diamonds: bool = case() + + @staticmethod + def Spades() -> Suit: + return Suit(spades=True) + + @staticmethod + def Hearts() -> Suit: + return Suit(hearts=True) + + @staticmethod + def Clubs() -> Suit: + return Suit(clubs=True) + + @staticmethod + def Diamonds() -> Suit: + return Suit(diamonds=True) + + +@tagged_union +class Face: + tag: Literal["jack", "queen", "king", "ace"] = tag() + + jack: bool = case() + queen: bool = case() + king: bool = case() + ace: bool = case() + + @staticmethod + def Jack() -> Face: + return Face(jack=True) + + @staticmethod + def Queen() -> Face: + return Face(queen=True) + + @staticmethod + def King() -> Face: + return Face(king=True) + + @staticmethod + def Ace() -> Face: + return Face(ace=True) + + +@tagged_union +class Card: + tag: Literal["value_card", "face_card", "joker"] = tag() + + face_card: tuple[Suit, Face] = case() + value_card: tuple[Suit, int] = case() + joker: bool = case() + + @staticmethod + def Face(suit: Suit, face: Face) -> Card: + return Card(face_card=(suit, face)) + + @staticmethod + def Value(suit: Suit, value: int) -> Card: + if value < 1 or value > 10: + raise ValueError("Value must be between 1 and 10") + return Card(value_card=(suit, value)) + + @staticmethod + def Joker() -> Card: + return Card(joker=True) + + +def test_rummy_score(): + def score(card: Card) -> int: + match card: + case Card(tag="face_card", face_card=(Suit(spades=True), Face(queen=True))): + return 40 + case Card(tag="face_card", face_card=(_suit, Face(ace=True))): + return 15 + case Card(tag="face_card", face_card=(_suit, _face)): + return 10 + case Card(tag="value_card", value_card=(_suit, value)): + return value + case Card(tag="joker", joker=True): + return 0 + case _: + raise AssertionError("Should not match") + + assert score(Card.Face(Suit.Spades(), Face.Jack())) == 10 + assert score(Card.Value(Suit.Spades(), 5)) == 5 + assert score(Card.Joker()) == 0 + assert score(Card.Face(Suit.Spades(), Face.Queen())) == 40 + assert score(Card.Face(Suit.Spades(), Face.King())) == 10 + assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Hearts(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Hearts(), Face.King())) == 10 + assert score(Card.Face(Suit.Clubs(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Clubs(), Face.King())) == 10 + assert score(Card.Face(Suit.Clubs(), Face.Queen())) == 10 + assert score(Card.Face(Suit.Clubs(), Face.Jack())) == 10 + assert score(Card.Face(Suit.Diamonds(), Face.Ace())) == 15 + assert score(Card.Face(Suit.Diamonds(), Face.King())) == 10 + assert score(Card.Face(Suit.Diamonds(), Face.Queen())) == 10 + assert score(Card.Face(Suit.Diamonds(), Face.Jack())) == 10 + assert score(Card.Value(Suit.Hearts(), 1)) == 1 + assert score(Card.Value(Suit.Hearts(), 2)) == 2 + assert score(Card.Value(Suit.Hearts(), 3)) == 3 + assert score(Card.Value(Suit.Hearts(), 4)) == 4 + assert score(Card.Value(Suit.Hearts(), 5)) == 5 + assert score(Card.Value(Suit.Hearts(), 6)) == 6 + assert score(Card.Value(Suit.Hearts(), 7)) == 7 + assert score(Card.Value(Suit.Hearts(), 8)) == 8 + assert score(Card.Value(Suit.Hearts(), 9)) == 9 + assert score(Card.Value(Suit.Hearts(), 10)) == 10 From 37032e47b187c7c1b07d93dc4e1a7f493a302f9c Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Wed, 10 Jan 2024 07:25:39 +0100 Subject: [PATCH 26/39] Reformatted --- expression/core/__init__.py | 2 +- expression/core/tagged_union.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/expression/core/__init__.py b/expression/core/__init__.py index e4104807..68caee65 100644 --- a/expression/core/__init__.py +++ b/expression/core/__init__.py @@ -11,6 +11,7 @@ from .option import Nothing, Option, Some, default_arg, is_none, is_some from .pipe import PipeMixin, pipe, pipe2, pipe3 from .result import Error, Ok, Result, is_error, is_ok +from .tagged_union import case, tag, tagged_union from .try_ import Failure, Success, Try from .typing import ( SupportsGreaterThan, @@ -21,7 +22,6 @@ try_downcast, upcast, ) -from .tagged_union import case, tag, tagged_union __all__ = [ diff --git a/expression/core/tagged_union.py b/expression/core/tagged_union.py index f4ccb02f..061ffaac 100644 --- a/expression/core/tagged_union.py +++ b/expression/core/tagged_union.py @@ -62,8 +62,6 @@ def __lt__(self: Any, other: Any) -> bool: if not isinstance(other, cls): return False - print("field names", field_names) - print((self.__index, getattr(self, self.tag)), (other.__index, getattr(other, other.tag))) return (self.__index, getattr(self, self.tag)) < (other.__index, getattr(other, other.tag)) # type: ignore cls.__lt__ = __lt__ # type: ignore @@ -105,7 +103,6 @@ def __deepcopy__(self: Any, memo: Any) -> Any: if repr: cls.__repr__ = __repr__ # type: ignore cls.__hash__ = __hash__ # type: ignore - print("match args", field_names) cls.__match_args__ = tuple(field_names) # type: ignore # We need to handle copy and deepcopy ourselves because they are needed by Pydantic From 5e01d52564640b9fb54cbc447a937fb1618c3cb9 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Wed, 10 Jan 2024 19:49:02 +0100 Subject: [PATCH 27/39] Cleanup --- .flake8 | 3 -- expression/core/tagged_union.py | 31 +++++++++++--------- tests/test_tagged_union.py | 50 ++++++++++++++++++++------------- 3 files changed, 47 insertions(+), 37 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 3587d243..00000000 --- a/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -ignore = E731, T484, T400 -max-line-length = 120 \ No newline at end of file diff --git a/expression/core/tagged_union.py b/expression/core/tagged_union.py index 061ffaac..d1daf4f2 100644 --- a/expression/core/tagged_union.py +++ b/expression/core/tagged_union.py @@ -32,18 +32,21 @@ def transform(cls: type[_T]) -> type[_T]: def __init__(self: Any, **kwargs: Any) -> None: tag = kwargs.pop("tag", None) - if len(kwargs) != 1: - raise TypeError(f"One and only one case can be specified. Not {kwargs}") + name, value = next(iter(kwargs.items())) if name not in field_names: raise TypeError(f"Unknown case name: {name}") - if tag is not None and tag != name: - raise TypeError(f"Tag {tag} does not match case name {name}") - # Cannot use setattr because it might be overridden for frozen classes - object.__setattr__(self, "tag", name) - object.__setattr__(self, name, value) - object.__setattr__(self, "__index", field_names.index(name)) + if len(kwargs) != 1: + raise TypeError(f"One and only one case can be specified. Not {kwargs}") + + match tag or name, name: + case str(tag), name if tag == name: + object.__setattr__(self, "tag", name) + object.__setattr__(self, name, value) + object.__setattr__(self, "_index", field_names.index(name)) + case tag, name: + raise TypeError(f"Tag {tag} does not match case name {name}") # Enables the use of dataclasses.asdict union_fields = dict((f.name, f) for f in fields_ if f.name in [name, "tag"]) @@ -53,21 +56,21 @@ def __init__(self: Any, **kwargs: Any) -> None: def __repr__(self: Any) -> str: return f"{cls.__name__}({self.tag}={getattr(self, self.tag)})" - def __hash__(self: Any) -> int: - return hash((cls.__name__, self.tag, getattr(self, self.tag))) - if order: def __lt__(self: Any, other: Any) -> bool: if not isinstance(other, cls): return False - return (self.__index, getattr(self, self.tag)) < (other.__index, getattr(other, other.tag)) # type: ignore + return (self._index, getattr(self, self.tag)) < (other._index, getattr(other, other.tag)) # type: ignore cls.__lt__ = __lt__ # type: ignore if frozen: + def __hash__(self: Any) -> int: + return hash((cls.__name__, self.tag, getattr(self, self.tag))) + def __setattr__(self: Any, name: str, value: Any) -> None: if name in field_names: raise TypeError("Cannot change the value of a tagged union case") @@ -81,6 +84,7 @@ def __delattr__(self: Any, name: str) -> None: cls.__setattr__ = __setattr__ cls.__delattr__ = __delattr__ # type: ignore + cls.__hash__ = __hash__ # type: ignore def __eq__(self: Any, other: Any) -> bool: return ( @@ -102,8 +106,7 @@ def __deepcopy__(self: Any, memo: Any) -> Any: cls.__init__ = __init__ # type: ignore if repr: cls.__repr__ = __repr__ # type: ignore - cls.__hash__ = __hash__ # type: ignore - cls.__match_args__ = tuple(field_names) # type: ignore + cls.__match_args__ = field_names # type: ignore # We need to handle copy and deepcopy ourselves because they are needed by Pydantic cls.__copy__ = __copy__ # type: ignore diff --git a/tests/test_tagged_union.py b/tests/test_tagged_union.py index 0f20ac12..6cf489fa 100644 --- a/tests/test_tagged_union.py +++ b/tests/test_tagged_union.py @@ -132,6 +132,16 @@ def test_maybe_nothing_works(): assert False +def test_maybe_pattern_match_positional_tag_arg_works(): + xs = Maybe(just=1) + match xs: + case Maybe("nothing"): + assert False + case Maybe("just", just=x): + assert x == 1 + case _: + assert False + def test_nested_unions_works(): xs = Maybe(just=Shape(circle=Circle(10.0))) match xs: @@ -174,8 +184,8 @@ def test_unions_can_be_composed(): class Weather: tag: Literal["sunny", "rainy"] = tag() - sunny: bool = case() - rainy: bool = case() + sunny: Literal[True] = case() + rainy: Literal[True] = case() @tagged_union class Day: @@ -247,10 +257,10 @@ def test_single_case_union_secure_password_works(): class Suit: tag: Literal["spades", "hearts", "clubs", "diamonds"] = tag() - spades: bool = case() - hearts: bool = case() - clubs: bool = case() - diamonds: bool = case() + spades: Literal[True] = case() + hearts: Literal[True] = case() + clubs: Literal[True] = case() + diamonds: Literal[True] = case() @staticmethod def Spades() -> Suit: @@ -273,10 +283,10 @@ def Diamonds() -> Suit: class Face: tag: Literal["jack", "queen", "king", "ace"] = tag() - jack: bool = case() - queen: bool = case() - king: bool = case() - ace: bool = case() + jack: Literal[True] = case() + queen: Literal[True] = case() + king: Literal[True] = case() + ace: Literal[True] = case() @staticmethod def Jack() -> Face: @@ -297,21 +307,21 @@ def Ace() -> Face: @tagged_union class Card: - tag: Literal["value_card", "face_card", "joker"] = tag() + tag: Literal["value", "face", "joker"] = tag() - face_card: tuple[Suit, Face] = case() - value_card: tuple[Suit, int] = case() - joker: bool = case() + face: tuple[Suit, Face] = case() + value: tuple[Suit, int] = case() + joker: Literal[True] = case() @staticmethod def Face(suit: Suit, face: Face) -> Card: - return Card(face_card=(suit, face)) + return Card(face=(suit, face)) @staticmethod def Value(suit: Suit, value: int) -> Card: if value < 1 or value > 10: raise ValueError("Value must be between 1 and 10") - return Card(value_card=(suit, value)) + return Card(value=(suit, value)) @staticmethod def Joker() -> Card: @@ -321,13 +331,13 @@ def Joker() -> Card: def test_rummy_score(): def score(card: Card) -> int: match card: - case Card(tag="face_card", face_card=(Suit(spades=True), Face(queen=True))): + case Card(tag="face", face=(Suit(spades=True), Face(queen=True))): return 40 - case Card(tag="face_card", face_card=(_suit, Face(ace=True))): + case Card(tag="face", face=(_suit, Face(ace=True))): return 15 - case Card(tag="face_card", face_card=(_suit, _face)): + case Card(tag="face", face=(_suit, _face)): return 10 - case Card(tag="value_card", value_card=(_suit, value)): + case Card(tag="value", value=(_suit, value)): return value case Card(tag="joker", joker=True): return 0 From bed684dedf724bd818ec4eca102d70268efa91c8 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 15:01:20 +0100 Subject: [PATCH 28/39] Add overloads to tagged_union --- expression/core/tagged_union.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/expression/core/tagged_union.py b/expression/core/tagged_union.py index d1daf4f2..ad188c21 100644 --- a/expression/core/tagged_union.py +++ b/expression/core/tagged_union.py @@ -1,12 +1,22 @@ from collections.abc import Callable from copy import deepcopy from dataclasses import dataclass, field, fields -from typing import Any, TypeVar, dataclass_transform +from typing import Any, TypeVar, dataclass_transform, overload _T = TypeVar("_T") +@overload +def tagged_union(*, frozen: bool = False, repr: bool = True) -> Callable[[type[_T]], type[_T]]: + ... + + +@overload +def tagged_union(_cls: type[_T], *, frozen: bool = False, repr: bool = True) -> type[_T]: + ... + + @dataclass_transform() def tagged_union( _cls: type[_T] | None = None, *, frozen: bool = False, repr: bool = True, order: bool = False From 00a94abf375f422270899bf7210bb4799b5bcf9b Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 15:01:43 +0100 Subject: [PATCH 29/39] Add docstring for Try --- expression/core/try_.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/expression/core/try_.py b/expression/core/try_.py index 72459d3c..8116dd6b 100644 --- a/expression/core/try_.py +++ b/expression/core/try_.py @@ -15,7 +15,11 @@ class Try(Result[_TSource, Exception]): - pass + """A try result. + + Same as `Result` but with error type pinned to `Exception`. Making it simpler + to use when the error type is an exception. + """ def Success(value: _TSource) -> Try[_TSource]: From abdcd5630948288fb6e1d912f941c211dbd122f4 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 15:02:18 +0100 Subject: [PATCH 30/39] Assert json output for option --- tests/test_option.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_option.py b/tests/test_option.py index 58d144ec..cebcdbfc 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -594,6 +594,8 @@ def test_parse_option_works(): def test_serialize_option_works(): model = Model(one=Some(10)) json = model.model_dump_json() + assert json == '{"one":10,"two":null,"three":null}' + model_ = Model.model_validate_json(json) assert model_.one.is_some() From 5430db0d9660cab427651d6939c4005774115c15 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 15:03:24 +0100 Subject: [PATCH 31/39] Update README --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 759ff53d..f5eb2977 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ on-demand as we go along. - **AsyncObservable** - Asynchronous observables. Provided separately by [aioreactive](https://github.com/dbrattli/aioreactive). - **Data Modelling** - sum and product types - - **TaggedUnion** - A tagged (discriminated) union type. + - **@tagged_union** - A tagged (discriminated) union type decorator. - **Parser Combinators** - A recursive decent string parser combinator library. - **Effects**: - lightweight computational expressions for Python. This @@ -403,7 +403,7 @@ class Shape: @staticmethod def Rectangle(width: float, length: float) -> Shape: - ""Optional static method for creating a tagged union case"" + """Optional static method for creating a tagged union case""" return Shape(rectangle=Rectangle(width, length)) @staticmethod @@ -414,7 +414,12 @@ class Shape: Note that the tag field is optional, but recommended. If you don't specify a tag field then then it will be created for you, but static type checkers will not be able to type -check correctly when pattern matching. +check correctly when pattern matching. The `tag` field if specified should be a literal +type with all the possible values for the tag. This is used by static type checkers to +check exhaustiveness of pattern matching. + +Each case is given the `case()` field initializer. This is optioal, but recommended for +static type checkers to work correctly. It's not required for the code to work properly, Now you may pattern match the shape to get back the actual value: @@ -428,9 +433,9 @@ Now you may pattern match the shape to get back the actual value: assert False ``` -Note that when matching keyword arguments, then the tag field must be specified for -static type checkers to work correctly. It's not required for the code to work properly, -but it's recommended. +Note that when matching keyword arguments, then the `tag` keyword argument must be +specified for static type checkers to check exhaustiveness correctly. It's not required +for the code to work properly, but it's recommended to avoid typing errors. ## Notable differences between Expression and F\# From 702c10c17bebe158207de02471a0aeb05d463d69 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 15:29:38 +0100 Subject: [PATCH 32/39] Use tagged union ordering for option --- expression/core/option.py | 27 +++------------------------ expression/core/tagged_union.py | 6 +++--- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/expression/core/option.py b/expression/core/option.py index d3acd459..d6d3a714 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -18,6 +18,7 @@ if TYPE_CHECKING: + # The following imports are only used for type checking and will be lazy imported. from pydantic import GetCoreSchemaHandler from pydantic_core import CoreSchema @@ -33,7 +34,7 @@ _T2 = TypeVar("_T2") -@tagged_union(frozen=True) +@tagged_union(frozen=True, order=True) class Option( Iterable[_TSource], PipeMixin, @@ -42,8 +43,8 @@ class Option( tag: Literal["some", "none"] = tag() - some: _TSource = case() none: None = case() + some: _TSource = case() @staticmethod def Some(value: _TSource) -> Option[_TSource]: @@ -267,21 +268,6 @@ def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: case _: raise EffectError(Nothing) - def __lt__(self, other: Any) -> bool: - if not isinstance(other, Option): - return False - - other = cast(Option[Any], other) - match self, other: - case Option(tag="some", some=self_value), Option(tag="some", some=other_value): # type: ignore - return self_value < other_value # type: ignore - case _, Option(tag="none"): - return False - case Option(tag="none"), _: - return True - case _: - return False - def __str__(self) -> str: match self: case Option(tag="some", some=some): @@ -292,13 +278,6 @@ def __str__(self) -> str: def __repr__(self) -> str: return self.__str__() - def __hash__(self) -> int: - match self: - case Option(tag="some", some=value): - return hash((self.tag, value)) - case _: - return hash((self.tag, 0)) - @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: from pydantic import ValidatorFunctionWrapHandler diff --git a/expression/core/tagged_union.py b/expression/core/tagged_union.py index ad188c21..cb068498 100644 --- a/expression/core/tagged_union.py +++ b/expression/core/tagged_union.py @@ -8,12 +8,12 @@ @overload -def tagged_union(*, frozen: bool = False, repr: bool = True) -> Callable[[type[_T]], type[_T]]: +def tagged_union(*, frozen: bool = False, repr: bool = True, order: bool = False) -> Callable[[type[_T]], type[_T]]: ... @overload -def tagged_union(_cls: type[_T], *, frozen: bool = False, repr: bool = True) -> type[_T]: +def tagged_union(_cls: type[_T], *, frozen: bool = False, repr: bool = True, order: bool = False) -> type[_T]: ... @@ -35,7 +35,7 @@ def tagged_union( """ def transform(cls: type[_T]) -> type[_T]: - cls = dataclass(cls) # TODO: decide if we should be a dataclass or not + cls = dataclass(init=False, repr=False, order=False, eq=False, kw_only=True)(cls) fields_ = fields(cls) # type: ignore field_names = tuple(f.name for f in fields_) original_init = cls.__init__ From e294b82c2edd3fbc79cfeea9cd08963586ac5663 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 15:34:37 +0100 Subject: [PATCH 33/39] Use hash from tagged union --- expression/core/result.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/expression/core/result.py b/expression/core/result.py index 6139dd0e..3bbc9421 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -42,7 +42,7 @@ _TError = TypeVar("_TError") -@tagged_union(frozen=True) +@tagged_union(frozen=True, order=True) class Result( Iterable[_TSource], PipeMixin, @@ -221,9 +221,6 @@ def __str__(self) -> str: def __repr__(self) -> str: return str(self) - def __hash__(self) -> int: - return hash(repr(self)) - @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: from pydantic import ValidatorFunctionWrapHandler From 05c7f90c6fa1f5324c0d84ee35387dd126a99dea Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 18:24:25 +0100 Subject: [PATCH 34/39] stash --- expression/collections/maptree.py | 24 +++++++------- expression/core/tagged_union.py | 55 ++++++++++++++++++------------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/expression/collections/maptree.py b/expression/collections/maptree.py index fcfa7a1e..b76f10a6 100644 --- a/expression/collections/maptree.py +++ b/expression/collections/maptree.py @@ -62,13 +62,13 @@ def is_empty(m: MapTree[Any, Any]): def size_aux(acc: int, m: MapTree[Key, Value]) -> int: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - return size_aux(size_aux(acc + 1, m2.left), m2.right) - else: + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right)): + return size_aux(size_aux(acc + 1, left), right) + case Option(tag="some", some=MapTreeLeaf()): return acc + 1 - else: - return acc + case _: + return acc def size(x: MapTree[Any, Any]): @@ -76,13 +76,13 @@ def size(x: MapTree[Any, Any]): def height(m: MapTree[Key, Value]) -> int: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - return m2.height - else: + match m: + case Option(tag="some", some=MapTreeNode(height=height)): + return height + case Option(tag="some", some=MapTreeLeaf()): return 1 - else: - return 0 + case _: + return 0 TOLERANCE = 2 diff --git a/expression/core/tagged_union.py b/expression/core/tagged_union.py index cb068498..b4cfa7f0 100644 --- a/expression/core/tagged_union.py +++ b/expression/core/tagged_union.py @@ -1,10 +1,29 @@ from collections.abc import Callable from copy import deepcopy from dataclasses import dataclass, field, fields -from typing import Any, TypeVar, dataclass_transform, overload +from typing import Any, Protocol, TypeVar, dataclass_transform, overload -_T = TypeVar("_T") +def case() -> Any: + """A case in a tagged union.""" + return field(init=False, kw_only=True) + + +def tag() -> Any: + """The tag of a tagged union.""" + return field(init=False, kw_only=True) + + +class HasTag(Protocol): + """Base class for tagged unions. + + A tagged union must include a tag field + """ + + tag: str = tag() + + +_T = TypeVar("_T", bound=HasTag) @overload @@ -68,46 +87,46 @@ def __repr__(self: Any) -> str: if order: - def __lt__(self: Any, other: Any) -> bool: - if not isinstance(other, cls): + def __lt__(self: _T, other: Any) -> bool: + if not hasattr(other, "tag"): return False - return (self._index, getattr(self, self.tag)) < (other._index, getattr(other, other.tag)) # type: ignore + return (self._index, getattr(self, self.tag)) < (other._index, getattr(other, other.tag)) cls.__lt__ = __lt__ # type: ignore if frozen: - def __hash__(self: Any) -> int: + def __hash__(self: _T) -> int: return hash((cls.__name__, self.tag, getattr(self, self.tag))) - def __setattr__(self: Any, name: str, value: Any) -> None: + def __setattr__(self: _T, name: str, value: Any) -> None: if name in field_names: raise TypeError("Cannot change the value of a tagged union case") object.__setattr__(self, name, value) - def __delattr__(self: Any, name: str) -> None: + def __delattr__(self: _T, name: str) -> None: if name in field_names: raise TypeError("Cannot delete a tagged union case") object.__delattr__(self, name) cls.__setattr__ = __setattr__ - cls.__delattr__ = __delattr__ # type: ignore + cls.__delattr__ = __delattr__ cls.__hash__ = __hash__ # type: ignore - def __eq__(self: Any, other: Any) -> bool: + def __eq__(self: _T, other: _T) -> bool: return ( - isinstance(other, cls) + hasattr(other, "tag") and self.tag == getattr(other, "tag") and getattr(self, self.tag) == getattr(other, self.tag) ) - def __copy__(self: Any) -> Any: + def __copy__(self: _T) -> _T: mapping = {self.tag: getattr(self, self.tag)} return cls(**mapping) - def __deepcopy__(self: Any, memo: Any) -> Any: + def __deepcopy__(self: _T, memo: Any) -> _T: value = deepcopy(getattr(self, self.tag), memo) mapping = {self.tag: value} return cls(**mapping) @@ -125,13 +144,3 @@ def __deepcopy__(self: Any, memo: Any) -> Any: return cls return transform if _cls is None else transform(_cls) - - -def case() -> Any: - """A case in a tagged union.""" - return field(init=False, kw_only=True) - - -def tag() -> Any: - """The tag of a tagged union.""" - return field(init=False, kw_only=True) From dc32427fd9103335834e5385ff65fce85925330c Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 20:47:02 +0100 Subject: [PATCH 35/39] Simplify types and cleanup --- expression/core/option.py | 2 +- expression/core/tagged_union.py | 92 +++++---- expression/core/union.py | 110 ---------- tests/test_union.py | 342 -------------------------------- 4 files changed, 46 insertions(+), 500 deletions(-) delete mode 100644 expression/core/union.py delete mode 100644 tests/test_union.py diff --git a/expression/core/option.py b/expression/core/option.py index d6d3a714..79aeec11 100644 --- a/expression/core/option.py +++ b/expression/core/option.py @@ -9,7 +9,7 @@ import builtins from collections.abc import Callable, Generator, Iterable -from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, cast, get_args, get_origin +from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, get_args, get_origin from .curry import curry_flip from .error import EffectError diff --git a/expression/core/tagged_union.py b/expression/core/tagged_union.py index b4cfa7f0..f26a7fc2 100644 --- a/expression/core/tagged_union.py +++ b/expression/core/tagged_union.py @@ -1,45 +1,30 @@ from collections.abc import Callable from copy import deepcopy from dataclasses import dataclass, field, fields -from typing import Any, Protocol, TypeVar, dataclass_transform, overload +from typing import Any, TypeVar, dataclass_transform, overload -def case() -> Any: - """A case in a tagged union.""" - return field(init=False, kw_only=True) - - -def tag() -> Any: - """The tag of a tagged union.""" - return field(init=False, kw_only=True) - - -class HasTag(Protocol): - """Base class for tagged unions. - - A tagged union must include a tag field - """ - - tag: str = tag() - - -_T = TypeVar("_T", bound=HasTag) +_T = TypeVar("_T") @overload -def tagged_union(*, frozen: bool = False, repr: bool = True, order: bool = False) -> Callable[[type[_T]], type[_T]]: +def tagged_union( + *, frozen: bool = False, repr: bool = True, eq: bool = True, order: bool = False +) -> Callable[[type[_T]], type[_T]]: ... @overload -def tagged_union(_cls: type[_T], *, frozen: bool = False, repr: bool = True, order: bool = False) -> type[_T]: +def tagged_union( + _cls: type[_T], *, frozen: bool = False, repr: bool = True, eq: bool = True, order: bool = False +) -> type[_T]: ... @dataclass_transform() def tagged_union( - _cls: type[_T] | None = None, *, frozen: bool = False, repr: bool = True, order: bool = False -) -> Callable[[type[_T]], type[_T]] | type[_T]: + _cls: Any = None, *, frozen: bool = False, repr: bool = True, eq: bool = True, order: bool = False +) -> Any: """Tagged union decorator. A decorator that turns a dataclass into a tagged union. @@ -51,9 +36,10 @@ def tagged_union( order: If True, the __lt__ method will be generated. The first case will be considered the smallest with index 0 and the items will be compared as the tuple (index, value) + eq: If True, the __eq__ method will be generated. """ - def transform(cls: type[_T]) -> type[_T]: + def transform(cls: Any) -> Any: cls = dataclass(init=False, repr=False, order=False, eq=False, kw_only=True)(cls) fields_ = fields(cls) # type: ignore field_names = tuple(f.name for f in fields_) @@ -87,25 +73,25 @@ def __repr__(self: Any) -> str: if order: - def __lt__(self: _T, other: Any) -> bool: - if not hasattr(other, "tag"): + def __lt__(self: Any, other: Any) -> bool: + if not isinstance(other, cls): return False - return (self._index, getattr(self, self.tag)) < (other._index, getattr(other, other.tag)) + return (self._index, getattr(self, self.tag)) < (other._index, getattr(other, other.tag)) # type: ignore cls.__lt__ = __lt__ # type: ignore if frozen: - def __hash__(self: _T) -> int: + def __hash__(self: Any) -> int: return hash((cls.__name__, self.tag, getattr(self, self.tag))) - def __setattr__(self: _T, name: str, value: Any) -> None: + def __setattr__(self: Any, name: str, value: Any) -> None: if name in field_names: raise TypeError("Cannot change the value of a tagged union case") object.__setattr__(self, name, value) - def __delattr__(self: _T, name: str) -> None: + def __delattr__(self: Any, name: str) -> None: if name in field_names: raise TypeError("Cannot delete a tagged union case") @@ -113,34 +99,46 @@ def __delattr__(self: _T, name: str) -> None: cls.__setattr__ = __setattr__ cls.__delattr__ = __delattr__ - cls.__hash__ = __hash__ # type: ignore + cls.__hash__ = __hash__ + if eq: + + def __eq__(self: Any, other: Any) -> bool: + return ( + isinstance(other, cls) + and self.tag == getattr(other, "tag") + and getattr(self, self.tag) == getattr(other, self.tag) + ) - def __eq__(self: _T, other: _T) -> bool: - return ( - hasattr(other, "tag") - and self.tag == getattr(other, "tag") - and getattr(self, self.tag) == getattr(other, self.tag) - ) + cls.__eq__ = __eq__ - def __copy__(self: _T) -> _T: + def __copy__(self: Any) -> Any: mapping = {self.tag: getattr(self, self.tag)} return cls(**mapping) - def __deepcopy__(self: _T, memo: Any) -> _T: + def __deepcopy__(self: Any, memo: Any) -> Any: value = deepcopy(getattr(self, self.tag), memo) mapping = {self.tag: value} return cls(**mapping) - cls.__eq__ = __eq__ # type: ignore - cls.__init__ = __init__ # type: ignore + cls.__init__ = __init__ if repr: - cls.__repr__ = __repr__ # type: ignore - cls.__match_args__ = field_names # type: ignore + cls.__repr__ = __repr__ + cls.__match_args__ = field_names # We need to handle copy and deepcopy ourselves because they are needed by Pydantic - cls.__copy__ = __copy__ # type: ignore - cls.__deepcopy__ = __deepcopy__ # type: ignore + cls.__copy__ = __copy__ + cls.__deepcopy__ = __deepcopy__ return cls return transform if _cls is None else transform(_cls) + + +def case() -> Any: + """A case in a tagged union.""" + return field(init=False, kw_only=True) + + +def tag() -> Any: + """The tag of a tagged union.""" + return field(init=False, kw_only=True) diff --git a/expression/core/union.py b/expression/core/union.py deleted file mode 100644 index cac10421..00000000 --- a/expression/core/union.py +++ /dev/null @@ -1,110 +0,0 @@ -from collections.abc import Callable -from copy import deepcopy -from dataclasses import dataclass, field, fields -from typing import Any, TypeVar, dataclass_transform - - -_T = TypeVar("_T") - - -@dataclass_transform() -def tagged_union( - _cls: type[_T] | None = None, *, frozen: bool = False, repr: bool = True -) -> Callable[[type[_T]], type[_T]] | type[_T]: - """Tagged union decorator. - - A decorator that turns a dataclass into a tagged union. - - Arguments: - frozen: Whether the tagged union should be frozen. - repr: If True, the __repr__ method will be generated. - """ - - def transform(cls: type[_T]) -> type[_T]: - cls = dataclass(cls) # TODO: decide if we should be a dataclass or not - fields_ = fields(cls) # type: ignore - field_names = {f.name for f in fields_} - field_names.add("tag") - original_init = cls.__init__ - - def __init__(self: Any, **kwargs: Any) -> None: - tag = kwargs.pop("tag", None) - if len(kwargs) != 1: - raise TypeError(f"One and only one case can be specified. Not {kwargs}") - name, value = next(iter(kwargs.items())) - if name not in field_names: - raise TypeError(f"Unknown case name: {name}") - if tag is not None and tag != name: - raise TypeError(f"Tag {tag} does not match case name {name}") - - # Cannot use setattr because it might be overridden for frozen classes - object.__setattr__(self, "tag", name) - object.__setattr__(self, name, value) - - # Enables the use of dataclasses.asdict - union_fields = dict((f.name, f) for f in fields_ if f.name in [name, "tag"]) - object.__setattr__(self, "__dataclass_fields__", union_fields) # type: ignore - original_init(self) - - def __repr__(self: Any) -> str: - return f"{cls.__name__}({self.tag}={getattr(self, self.tag)})" - - def __hash__(self: Any) -> int: - return hash((cls.__name__, self.tag, getattr(self, self.tag))) - - if frozen: - - def __setattr__(self: Any, name: str, value: Any) -> None: - if name in field_names: - raise TypeError("Cannot change the value of a tagged union case") - object.__setattr__(self, name, value) - - def __delattr__(self: Any, name: str) -> None: - if name in field_names: - raise TypeError("Cannot delete a tagged union case") - - object.__delattr__(self, name) - - cls.__setattr__ = __setattr__ - cls.__delattr__ = __delattr__ # type: ignore - - def __eq__(self: Any, other: Any) -> bool: - return ( - isinstance(other, cls) - and self.tag == getattr(other, "tag") - and getattr(self, self.tag) == getattr(other, self.tag) - ) - - def __copy__(self: Any) -> Any: - mapping = {self.tag: getattr(self, self.tag)} - return cls(**mapping) - - def __deepcopy__(self: Any, memo: Any) -> Any: - value = deepcopy(getattr(self, self.tag), memo) - mapping = {self.tag: value} - return cls(**mapping) - - cls.__eq__ = __eq__ # type: ignore - cls.__init__ = __init__ # type: ignore - if repr: - cls.__repr__ = __repr__ # type: ignore - cls.__hash__ = __hash__ # type: ignore - cls.__match_args__ = tuple(field_names) # type: ignore - - # We need to handle copy and deepcopy ourselves because they are needed by Pydantic - cls.__copy__ = __copy__ # type: ignore - cls.__deepcopy__ = __deepcopy__ # type: ignore - - return cls - - return transform if _cls is None else transform(_cls) - - -def case() -> Any: - """A case in a tagged union.""" - return field(init=False, kw_only=True) - - -def tag() -> Any: - """The tag of a tagged union.""" - return field(init=False, kw_only=True) diff --git a/tests/test_union.py b/tests/test_union.py deleted file mode 100644 index feafec3d..00000000 --- a/tests/test_union.py +++ /dev/null @@ -1,342 +0,0 @@ -from __future__ import annotations - -from dataclasses import asdict, dataclass -from typing import Generic, Literal, TypeVar - -import pytest - -from expression import case, tag, tagged_union - - -_T = TypeVar("_T") - - -@dataclass(unsafe_hash=True) -class Circle: - radius: float - - -@tagged_union(frozen=True) -class Shape: - tag: Literal["circle", "rectangle", "triangle"] = tag() - - circle: Circle = case() - rectangle: tuple[float, float] = case() - triangle: tuple[float, float] = case() - - -def test_union_create_shape_works(): - shape = Shape(circle=Circle(10.0)) - assert shape.circle.radius == 10.0 - - -def test_union_shape_tag_is_set(): - shape = Shape(circle=Circle(10.0)) - assert shape.tag == "circle" - - -def test_union_shape_circle_pattern_matching_works(): - shape = Shape(circle=Circle(10.0)) - - match shape: - case Shape(tag="rectangle", rectangle=(_, _)): - raise AssertionError("Should not match") - case Shape(tag="circle", circle=Circle(radius=r)): - assert r == 10.0 - case _: - assert False - - -def test_shape_rectangle_pattern_matching_works(): - shape = Shape(rectangle=(10.0, 20.0)) - - match shape: - case Shape(tag="circle", circle=Circle(radius=_)): - raise AssertionError("Should not match") - case Shape(tag="rectangle", rectangle=(w, h)): - assert w == 10.0 - assert h == 20.0 - case _: - assert False - - -def test_union_shape_hash_works(): - shape = Shape(circle=Circle(10.0)) - assert hash(shape) == hash(("Shape", "circle", Circle(10.0))) - - -def test_union_shape_repr_works(): - shape = Shape(circle=Circle(10.0)) - assert repr(shape) == "Shape(circle=Circle(radius=10.0))" - - -def test_union_can_add_custom_attributes_to_shape(): - shape = Shape(circle=Circle(10.0)) - setattr(shape, "custom", "rectangle") - assert getattr(shape, "custom") == "rectangle" - - -def test_union_cannot_change_case_value(): - shape = Shape(circle=Circle(10.0)) - with pytest.raises(TypeError): - shape.circle = Circle(20.0) # type: ignore - - -def test_union_compare_shapes(): - shape1 = Shape(circle=Circle(10.0)) - shape2 = Shape(circle=Circle(10.0)) - assert shape1 == shape2 - - shape3 = Shape(rectangle=(10.0, 20.0)) - assert shape1 != shape3 - - -def test_union_compare_shapes_with_different_tags(): - shape1 = Shape(circle=Circle(10.0)) - shape2 = Shape(rectangle=(10.0, 20.0)) - assert shape1 != shape2 - - -@tagged_union -class Maybe(Generic[_T]): - tag: Literal["just", "nothing"] = tag() - - just: _T = case() - nothing: None = case() - - -def test_maybe_works(): - xs = Maybe(just=1) - match xs: - case Maybe(tag="just", just=x): - assert x == 1 - case _: - assert False - - -def test_maybe_just_works(): - xs = Maybe(just=1) - match xs: - case Maybe(tag="just", just=x): - assert x == 1 - case Maybe(tag="nothing", nothing=None): - assert False - case _: - assert False - - -def test_maybe_nothing_works(): - xs = Maybe[int](nothing=None) - match xs: - case Maybe(tag="nothing", nothing=None): - assert True - case _: - assert False - - -def test_nested_unions_works(): - xs = Maybe(just=Shape(circle=Circle(10.0))) - match xs: - case Maybe(tag="just", just=Shape(tag="circle", circle=Circle(radius=r))): - assert r == 10.0 - case _: - assert False - - -def test_union_maybe_asdict_works(): - xs = Maybe(just=1) - assert asdict(xs) == {"tag": "just", "just": 1} - - -def test_unions_can_be_composed(): - @tagged_union - class Weather: - tag: Literal["sunny", "rainy"] = tag() - - sunny: bool = case() - rainy: bool = case() - - @tagged_union - class Day: - tag: Literal["weekday", "weekend"] = tag() - - weekday: Weather = case() - weekend: Weather = case() - - today = Day(weekday=Weather(sunny=True)) - match today: - case Day(tag="weekday", weekday=Weather(tag="sunny", sunny=s)): - assert s is True - case _: - assert False - - -@tagged_union -class Email: - email: str = case() - - -def test_single_case_union_works(): - email = Email(email="test@test.com") - - # Test attribute access - assert email.email == "test@test.com" - assert email.tag == "email" # type: ignore - - # Test pattern matching - match email: - case Email(email=e): - assert e == "test@test.com" - case _: # pyright: ignore - assert False - - -@tagged_union(frozen=True, repr=False) -class SecurePassword: - password: str = case() - - # Override __str__ and __repr__ to make sure we don't leak the password in logs - def __str__(self) -> str: - return "********" - - def __repr__(self) -> str: - return "SecurePassword(password='********')" - - -def test_single_case_union_secure_password_works(): - password = SecurePassword(password="secret") - - # Test attribute access - assert password.password == "secret" - assert password.tag == "password" # type: ignore - - # Test pattern matching - match password: - case SecurePassword(password=p): - assert p == "secret" - - # Test __str__ - assert str(password) == "********" - - # Test __repr__ - assert repr(password) == "SecurePassword(password='********')" - - -@tagged_union -class Suit: - tag: Literal["spades", "hearts", "clubs", "diamonds"] = tag() - - spades: bool = case() - hearts: bool = case() - clubs: bool = case() - diamonds: bool = case() - - @staticmethod - def Spades() -> Suit: - return Suit(spades=True) - - @staticmethod - def Hearts() -> Suit: - return Suit(hearts=True) - - @staticmethod - def Clubs() -> Suit: - return Suit(clubs=True) - - @staticmethod - def Diamonds() -> Suit: - return Suit(diamonds=True) - - -@tagged_union -class Face: - tag: Literal["jack", "queen", "king", "ace"] = tag() - - jack: bool = case() - queen: bool = case() - king: bool = case() - ace: bool = case() - - @staticmethod - def Jack() -> Face: - return Face(jack=True) - - @staticmethod - def Queen() -> Face: - return Face(queen=True) - - @staticmethod - def King() -> Face: - return Face(king=True) - - @staticmethod - def Ace() -> Face: - return Face(ace=True) - - -@tagged_union -class Card: - tag: Literal["value_card", "face_card", "joker"] = tag() - - face_card: tuple[Suit, Face] = case() - value_card: tuple[Suit, int] = case() - joker: bool = case() - - @staticmethod - def Face(suit: Suit, face: Face) -> Card: - return Card(face_card=(suit, face)) - - @staticmethod - def Value(suit: Suit, value: int) -> Card: - if value < 1 or value > 10: - raise ValueError("Value must be between 1 and 10") - return Card(value_card=(suit, value)) - - @staticmethod - def Joker() -> Card: - return Card(joker=True) - - -def test_rummy_score(): - def score(card: Card) -> int: - match card: - case Card(tag="face_card", face_card=(Suit(spades=True), Face(queen=True))): - return 40 - case Card(tag="face_card", face_card=(_suit, Face(ace=True))): - return 15 - case Card(tag="face_card", face_card=(_suit, _face)): - return 10 - case Card(tag="value_card", value_card=(_suit, value)): - return value - case Card(tag="joker", joker=True): - return 0 - case _: - raise AssertionError("Should not match") - - assert score(Card.Face(Suit.Spades(), Face.Jack())) == 10 - assert score(Card.Value(Suit.Spades(), 5)) == 5 - assert score(Card.Joker()) == 0 - assert score(Card.Face(Suit.Spades(), Face.Queen())) == 40 - assert score(Card.Face(Suit.Spades(), Face.King())) == 10 - assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 - assert score(Card.Face(Suit.Spades(), Face.Ace())) == 15 - assert score(Card.Face(Suit.Hearts(), Face.Ace())) == 15 - assert score(Card.Face(Suit.Hearts(), Face.King())) == 10 - assert score(Card.Face(Suit.Clubs(), Face.Ace())) == 15 - assert score(Card.Face(Suit.Clubs(), Face.King())) == 10 - assert score(Card.Face(Suit.Clubs(), Face.Queen())) == 10 - assert score(Card.Face(Suit.Clubs(), Face.Jack())) == 10 - assert score(Card.Face(Suit.Diamonds(), Face.Ace())) == 15 - assert score(Card.Face(Suit.Diamonds(), Face.King())) == 10 - assert score(Card.Face(Suit.Diamonds(), Face.Queen())) == 10 - assert score(Card.Face(Suit.Diamonds(), Face.Jack())) == 10 - assert score(Card.Value(Suit.Hearts(), 1)) == 1 - assert score(Card.Value(Suit.Hearts(), 2)) == 2 - assert score(Card.Value(Suit.Hearts(), 3)) == 3 - assert score(Card.Value(Suit.Hearts(), 4)) == 4 - assert score(Card.Value(Suit.Hearts(), 5)) == 5 - assert score(Card.Value(Suit.Hearts(), 6)) == 6 - assert score(Card.Value(Suit.Hearts(), 7)) == 7 - assert score(Card.Value(Suit.Hearts(), 8)) == 8 - assert score(Card.Value(Suit.Hearts(), 9)) == 9 - assert score(Card.Value(Suit.Hearts(), 10)) == 10 From daa9becdc966edc39e5a2fea0dc46cc59c1bc36a Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 21:16:10 +0100 Subject: [PATCH 36/39] Refactor maptree to use pattern matching --- expression/collections/maptree.py | 350 ++++++++++++++---------------- 1 file changed, 168 insertions(+), 182 deletions(-) diff --git a/expression/collections/maptree.py b/expression/collections/maptree.py index b76f10a6..402ba34f 100644 --- a/expression/collections/maptree.py +++ b/expression/collections/maptree.py @@ -145,25 +145,24 @@ def rebalance(t1: MapTree[Key, Value], k: Key, v: Value, t2: MapTree[Key, Value] def add(k: Key, v: Value, m: MapTree[Key, Value]) -> MapTree[Key, Value]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - if k < mn.key: - return rebalance(add(k, v, mn.left), mn.key, mn.value, mn.right) - elif k == mn.key: - return Some(MapTreeNode(k, v, mn.left, mn.right, mn.height)) + match m: + case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right, height=height)): + if k < key: + return rebalance(add(k, v, left), key, value, right) + elif k == key: + return Some(MapTreeNode(k, v, left, right, height)) else: - return rebalance(mn.left, mn.key, mn.value, add(k, v, mn.right)) - else: - if k < m2.key: + return rebalance(left, key, value, add(k, v, right)) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + if k < key: node = MapTreeNode(k, v, empty, m, 2) return Some(node) - elif k == m2.key: + elif k == key: return Some(MapTreeLeaf(k, v)) else: return Some(MapTreeNode(k, v, m, empty, 2)) - else: - return Some(MapTreeLeaf(k, v)) + case _: + return Some(MapTreeLeaf(k, v)) def try_find(k: Key, m: MapTree[Key, Value]) -> Option[Value]: @@ -206,16 +205,15 @@ def partition_aux( m: MapTree[Key, Value], acc: tuple[MapTree[Key, Value], MapTree[Key, Value]], ) -> tuple[MapTree[Key, Value], MapTree[Key, Value]]: - for m2 in m: - if isinstance(m2, MapTreeNode): - mn = m2 - acc = partition_aux(predicate, mn.right, acc) - acc = partition1(predicate, mn.key, mn.value, acc) - return partition_aux(predicate, mn.left, acc) - else: - return partition1(predicate, m2.key, m2.value, acc) - else: # Nothing - return acc + match m: + case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right)): + acc = partition_aux(predicate, right, acc) + acc = partition1(predicate, key, value, acc) + return partition_aux(predicate, left, acc) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return partition1(predicate, key, value, acc) + case _: + return acc def partition( @@ -236,16 +234,15 @@ def filter_aux( m: MapTree[Key, Value], acc: MapTree[Key, Value], ) -> MapTree[Key, Value]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - acc = filter_aux(predicate, mn.left, acc) - acc = filter1(predicate, mn.key, mn.value, acc) - return filter_aux(predicate, mn.right, acc) - else: - return filter1(predicate, m2.key, m2.value, acc) - else: # Nothing - return acc + match m: + case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right)): + acc = filter_aux(predicate, left, acc) + acc = filter1(predicate, key, value, acc) + return filter_aux(predicate, right, acc) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return filter1(predicate, key, value, acc) + case _: + return acc def filter(f: Callable[[Key, Value], bool], m: MapTree[Key, Value]) -> MapTree[Key, Value]: @@ -253,72 +250,69 @@ def filter(f: Callable[[Key, Value], bool], m: MapTree[Key, Value]) -> MapTree[K def splice_out_successor(m: MapTree[Key, Value]) -> tuple[Key, Value, Option[MapTreeLeaf[Key, Value]]]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - if is_empty(mn.left): - return mn.key, mn.value, mn.right + match m: + case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right)): + if is_empty(left): + return key, value, right else: - k3, v3, l_ = splice_out_successor(mn.left) - return k3, v3, mk(l_, mn.key, mn.value, mn.right) - else: - return m2.key, m2.value, empty - else: # Nothing - failwith("internal error: Map.splice_out_successor") + k3, v3, l_ = splice_out_successor(left) + return k3, v3, mk(l_, key, value, right) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return key, value, empty + case _: + failwith("internal error: Map.splice_out_successor") def remove(k: Key, m: MapTree[Key, Value]) -> Option[MapTreeLeaf[Key, Value]]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - if k < mn.key: - return rebalance(remove(k, mn.left), mn.key, mn.value, mn.right) - elif k == mn.key: - if is_empty(mn.left): - return mn.right - elif is_empty(mn.right): - return mn.left + match m: + case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right)): + if k < key: + return rebalance(remove(k, left), key, value, right) + elif k == key: + if is_empty(left): + return right + elif is_empty(right): + return left else: - sk, sv, r_ = splice_out_successor(mn.right) - return mk(mn.left, sk, sv, r_) + sk, sv, r_ = splice_out_successor(right) + return mk(left, sk, sv, r_) else: - return rebalance(mn.left, mn.key, mn.value, remove(k, mn.right)) - else: - if k == m2.key: + return rebalance(left, key, value, remove(k, right)) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + if k == key: return empty else: return m - else: # Nothing - return empty + case _: + return empty def change(k: Key, u: Callable[[Option[Value]], Option[Value]], m: MapTree[Key, Value]) -> MapTree[Key, Value]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - if k < mn.key: - return rebalance(change(k, u, mn.left), mn.key, mn.value, mn.right) - elif k == mn.key: - for v in u(Some(mn.value)).to_list(): - return Some(MapTreeNode(k, v, mn.left, mn.right, mn.height)) + match m: + case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right)): + if k < key: + return rebalance(change(k, u, left), key, value, right) + elif k == key: + for v in u(Some(value)).to_list(): + return Some(MapTreeNode(k, v, left, right, height)) else: - if is_empty(mn.left): - return mn.right - elif is_empty(mn.right): - return mn.left + if is_empty(left): + return right + elif is_empty(right): + return left else: - sk, sv, r_ = splice_out_successor(mn.right) - return mk(mn.left, sk, sv, r_) + sk, sv, r_ = splice_out_successor(right) + return mk(left, sk, sv, r_) else: - return rebalance(mn.left, mn.key, mn.value, change(k, u, mn.right)) - else: - if k < m2.key: + return rebalance(left, key, value, change(k, u, right)) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + if k < key: for v in u(Nothing).to_list(): return Some(MapTreeNode(k, v, empty, m, 2)) else: return m - elif k == m2.key: - for v in u(Some(m2.value)).to_list(): + elif k == key: + for v in u(Some(value)).to_list(): return Some(MapTreeLeaf(k, v)) else: return empty @@ -328,130 +322,123 @@ def change(k: Key, u: Callable[[Option[Value]], Option[Value]], m: MapTree[Key, else: return m - else: - for v in u(Nothing): - return Some(MapTreeLeaf(k, v)) - else: - return m + case _: + for v in u(Nothing): + return Some(MapTreeLeaf(k, v)) + else: + return m def mem(k: Key, m: MapTree[Key, Value]) -> bool: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - if k < mn.key: - return mem(k, mn.left) + match m: + case Option(tag="some", some=MapTreeNode(key=key, left=left, right=right)): + if k < key: + return mem(k, left) else: - return k == mn.key or mem(k, mn.right) - else: - return k == m2.key - else: - return False + return k == key or mem(k, right) + case Option(tag="some", some=MapTreeLeaf(key=key)): + return k == key + case _: + return False def iter(fn: Callable[[Key, Value], None], m: MapTree[Key, Value]) -> None: """Iterate maptree.""" - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - iter(fn, mn.left) - fn(mn.key, mn.value) - iter(fn, mn.right) - else: - fn(m2.key, m2.value) + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + iter(fn, left) + fn(key, value) + iter(fn, right) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + fn(key, value) + case _: + pass def try_pick(f: Callable[[Key, Value], Option[Result]], m: MapTree[Key, Value]) -> Option[Result]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - res = try_pick(f, mn.left) + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + res = try_pick(f, left) if res.is_some(): return res else: - res = f(mn.key, mn.value) + res = f(key, value) if res.is_some(): return res else: - return try_pick(f, mn.right) - else: - return f(m2.key, m2.value) - else: - return Nothing + return try_pick(f, right) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return f(key, value) + case _: + return Nothing def exists(f: Callable[[Key, Value], bool], m: MapTree[Key, Value]) -> bool: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - return exists(f, mn.left) or f(mn.key, mn.value) or exists(f, mn.right) - else: - return f(m2.key, m2.value) - else: - return False + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + return exists(f, left) or f(key, value) or exists(f, right) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return f(key, value) + case _: + return False def forall(f: Callable[[Key, Value], bool], m: MapTree[Key, Value]) -> bool: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - return forall(f, mn.left) and f(mn.key, mn.value) and forall(f, mn.right) - else: - return f(m2.key, m2.value) - else: - return True + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + return forall(f, left) and f(key, value) and forall(f, right) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return f(key, value) + case _: + return True def map(f: Callable[[Key, Value], Result], m: MapTree[Key, Value]) -> MapTree[Key, Result]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - l2 = map(f, mn.left) - v2 = f(mn.key, mn.value) - r2 = map(f, mn.right) - return Some(MapTreeNode(mn.key, v2, l2, r2, mn.height)) - else: - return Some(MapTreeLeaf(m2.key, f(m2.key, m2.value))) - else: - return empty + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value, height=height)): + l2 = map(f, left) + v2 = f(key, value) + r2 = map(f, right) + return Some(MapTreeNode(key, v2, l2, r2, height)) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return Some(MapTreeLeaf(key, f(key, value))) + case _: + return empty def fold_back(f: Callable[[tuple[Key, Value], Result], Result], m: MapTree[Key, Value], x: Result) -> Result: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - x = fold_back(f, mn.right, x) - x = f((mn.key, mn.value), x) - return fold_back(f, mn.left, x) - else: - return f((m2.key, m2.value), x) - else: - return x + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + x = fold_back(f, right, x) + x = f((key, value), x) + return fold_back(f, left, x) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return f((key, value), x) + case _: + return x def fold(f: Callable[[Result, tuple[Key, Value]], Result], x: Result, m: MapTree[Key, Value]) -> Result: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - x = fold(f, x, mn.left) - x = f(x, (mn.key, mn.value)) - return fold(f, x, mn.right) - else: - return f(x, (m2.key, m2.value)) - else: - return x + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + x = fold(f, x, left) + x = f(x, (key, value)) + return fold(f, x, right) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return f(x, (key, value)) + case _: + return x def to_list(m: MapTree[Key, Value]) -> Block[tuple[Key, Value]]: def loop(m: MapTree[Key, Value], acc: Block[tuple[Key, Value]]) -> Block[tuple[Key, Value]]: - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - return loop(mn.left, loop(mn.right, acc).cons((mn.key, mn.value))) - else: - return acc.cons((m2.key, m2.value)) - else: - return acc + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + return loop(left, loop(right, acc).cons((key, value))) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): + return acc.cons((key, value)) + case _: + return acc return loop(m, block.empty) @@ -488,15 +475,14 @@ def collapseLHS(stack: Block[MapTree[Key, Value]]) -> Block[MapTree[Key, Value]] if stack.is_empty(): return block.empty m, rest = stack.head(), stack.tail() - for m2 in m.to_list(): - if isinstance(m2, MapTreeNode): - mn = m2 - tree = Some(MapTreeLeaf(mn.key, mn.value)) - return collapseLHS(rest.cons(mn.right).cons(tree).cons(mn.left)) - else: + match m: + case Option(tag="some", some=MapTreeNode(left=left, right=right, key=key, value=value)): + tree = Some(MapTreeLeaf(key, value)) + return collapseLHS(rest.cons(right).cons(tree).cons(left)) + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): return stack - else: - return collapseLHS(rest) + case _: + return collapseLHS(rest) class MkIterator(Iterator[tuple[Key, Value]]): @@ -508,14 +494,14 @@ def __next__(self) -> tuple[Key, Value]: raise StopIteration rest = self.stack.tail() - for m in self.stack.head(): - if isinstance(m, MapTreeNode): + match self.stack.head(): + case Option(tag="some", some=MapTreeNode()): failwith("Please report error: Map iterator, unexpected stack for next()") - else: + case Option(tag="some", some=MapTreeLeaf(key=key, value=value)): self.stack = collapseLHS(rest) - return m.key, m.value - else: - failwith("Please report error: Map iterator, unexpected stack for next()") + return key, value + case _: + failwith("Please report error: Map iterator, unexpected stack for next()") def not_started() -> None: From 39976affd027e8beebb3904c7a8dfbeb5c63f00b Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 21:18:57 +0100 Subject: [PATCH 37/39] Make result use tagged union eq --- expression/collections/maptree.py | 2 +- expression/core/result.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/expression/collections/maptree.py b/expression/collections/maptree.py index 402ba34f..2270876a 100644 --- a/expression/collections/maptree.py +++ b/expression/collections/maptree.py @@ -289,7 +289,7 @@ def remove(k: Key, m: MapTree[Key, Value]) -> Option[MapTreeLeaf[Key, Value]]: def change(k: Key, u: Callable[[Option[Value]], Option[Value]], m: MapTree[Key, Value]) -> MapTree[Key, Value]: match m: - case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right)): + case Option(tag="some", some=MapTreeNode(key=key, value=value, left=left, right=right, height=height)): if k < key: return rebalance(change(k, u, left), key, value, right) elif k == key: diff --git a/expression/core/result.py b/expression/core/result.py index 3bbc9421..5605d5f6 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -201,9 +201,6 @@ def of_option_with(cls, value: Option[_TSource], error: Callable[[], _TError]) - """Convert option to a result.""" return of_option_with(value, error) - def __eq__(self, o: Any) -> bool: - return isinstance(o, Result) and self.tag == o.tag and getattr(self, self.tag) == getattr(o, self.tag) # type: ignore - def __iter__(self) -> Generator[_TSource, _TSource, _TSource]: match self: case Result(tag="ok", ok=value): From 24a41ad4aafcf641ce1429fd0eba6d2013d19bcf Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 21:23:45 +0100 Subject: [PATCH 38/39] Fix result dict handling --- expression/core/result.py | 6 +++--- tests/test_result.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/expression/core/result.py b/expression/core/result.py index 5605d5f6..37614928 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -157,19 +157,19 @@ def is_ok(self) -> bool: case _: return False - def dict(self) -> builtins.dict[str, _TSource | _TError]: + def dict(self) -> builtins.dict[str, _TSource | _TError | Literal["ok", "error"]]: """Return a json serializable representation of the result.""" match self: case Result(tag="ok", ok=value): attr = getattr(value, "model_dump", None) or getattr(value, "dict", None) if attr and callable(attr): value = attr() - return {"ok": value} + return {"tag": "ok", "ok": value} case Result(error=error): attr = getattr(error, "model_dump", None) or getattr(error, "dict", None) if attr and callable(attr): error = attr() - return {"error": error} + return {"tag": "error", "error": error} def swap(self) -> Result[_TError, _TSource]: """Swaps the value in the result so an Ok becomes an Error and an Error becomes an Ok.""" diff --git a/tests/test_result.py b/tests/test_result.py index 67836c6c..1028433a 100644 --- a/tests/test_result.py +++ b/tests/test_result.py @@ -383,14 +383,14 @@ def test_parse_block_works(): def test_ok_to_dict_works(): result = Ok(10) obj = result.dict() - assert obj == dict(ok=10) + assert obj == dict(tag="ok", ok=10) def test_error_to_dict_works(): error = MyError(message="got error") result = Error(error) obj = result.dict() - assert obj == dict(error=dict(message="got error")) + assert obj == dict(tag="error", error=dict(message="got error")) def test_ok_from_from_dict_works(): @@ -424,7 +424,7 @@ def test_error_from_dict_works(): def test_model_to_json_works(): model = Model(one=Ok(10)) obj = model.model_dump_json() - assert obj == '{"one":{"ok":10},"two":{"error":{"message":"error"}},"three":{"error":{"message":"error"}}}' + assert obj == '{"one":{"tag":"ok","ok":10},"two":{"tag":"error","error":{"message":"error"}},"three":{"tag":"error","error":{"message":"error"}}}' def test_error_default_value(): From 4391ca49ea4dccb07af4783b528a0a97b3f11023 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Thu, 11 Jan 2024 21:26:24 +0100 Subject: [PATCH 39/39] Fix for return type --- expression/core/result.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expression/core/result.py b/expression/core/result.py index 37614928..a8d6c4b4 100644 --- a/expression/core/result.py +++ b/expression/core/result.py @@ -352,7 +352,7 @@ def bind( return result.bind(mapper) -def dict(source: Result[_TSource, _TError]) -> builtins.dict[str, _TSource | _TError]: +def dict(source: Result[_TSource, _TError]) -> builtins.dict[str, _TSource | _TError | Literal["ok", "error"]]: return source.dict()