From c214bfc87661a71dc4c2a868b94321c364a963ce Mon Sep 17 00:00:00 2001 From: alainburindi Date: Thu, 12 Sep 2024 13:47:29 +0200 Subject: [PATCH 1/5] add django 5 support --- .gitignore | 2 + poetry.lock | 1108 +++++++++++++++++++++++++++++------------------- pyproject.toml | 6 +- tox.ini | 28 +- 4 files changed, 701 insertions(+), 443 deletions(-) diff --git a/.gitignore b/.gitignore index eaf6ef3..8f06ad9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ __pycache__ .coverage* .tox/ .pytest*/ + +.DS_Store diff --git a/poetry.lock b/poetry.lock index a96801a..f4a1b18 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,94 +1,177 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + [[package]] name = "aniso8601" version = "9.0.1" description = "A library for parsing ISO 8601 strings." -category = "main" optional = false python-versions = "*" +files = [ + {file = "aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"}, + {file = "aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"}, +] [package.extras] dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"] [[package]] name = "appnope" -version = "0.1.3" +version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" -category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] [[package]] name = "asgiref" -version = "3.6.0" +version = "3.8.1" description = "ASGI specs, helper code, and adapters" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, + {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, +] [package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} [package.extras] -tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[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 = "atomicwrites" version = "1.4.1" description = "Atomic file writes." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +] [[package]] name = "attrs" -version = "22.2.0" +version = "24.2.0" description = "Classes Without Boilerplate" -category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] [package.extras] -cov = ["attrs", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs"] -docs = ["furo", "sphinx", "myst-parser", "zope.interface", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] -tests = ["attrs", "zope.interface"] -tests-no-zope = ["hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist", "cloudpickle", "mypy (>=0.971,<0.990)", "pytest-mypy-plugins"] -tests_no_zope = ["hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist", "cloudpickle", "mypy (>=0.971,<0.990)", "pytest-mypy-plugins"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" -category = "dev" 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 = "backports-zoneinfo" +version = "0.2.1" +description = "Backport of the standard library zoneinfo module" +optional = false +python-versions = ">=3.6" +files = [ + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, + {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, +] + +[package.extras] +tzdata = ["tzdata"] [[package]] name = "bandit" -version = "1.7.4" +version = "1.7.9" description = "Security oriented static analyser for python code." -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "bandit-1.7.9-py3-none-any.whl", hash = "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec"}, + {file = "bandit-1.7.9.tar.gz", hash = "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"}, +] [package.dependencies] colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} -GitPython = ">=1.0.1" PyYAML = ">=5.3.1" +rich = "*" stevedore = ">=1.20.0" [package.extras] -test = ["coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml", "beautifulsoup4 (>=4.8.0)", "pylint (==1.9.4)"] -toml = ["toml"] -yaml = ["pyyaml"] +baseline = ["GitPython (>=3.1.30)"] +sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"] +toml = ["tomli (>=1.1.0)"] +yaml = ["PyYAML"] [[package]] name = "black" version = "22.12.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, + {file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"}, + {file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"}, + {file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"}, + {file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"}, + {file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"}, + {file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"}, + {file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"}, + {file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"}, + {file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"}, + {file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"}, + {file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"}, +] [package.dependencies] click = ">=8.0.0" @@ -96,7 +179,6 @@ mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] @@ -107,31 +189,109 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "click" -version = "8.1.3" +version = "8.1.7" description = "Composable command line interface toolkit" -category = "dev" 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\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] [[package]] name = "coverage" -version = "7.0.5" +version = "7.6.1" description = "Code coverage measurement for Python" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +] [package.extras] toml = ["tomli"] @@ -140,30 +300,40 @@ toml = ["tomli"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "dev" 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.6" +version = "0.3.8" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, +] [[package]] name = "django" -version = "3.2.16" -description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." -category = "main" +version = "4.2.16" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "Django-4.2.16-py3-none-any.whl", hash = "sha256:1ddc333a16fc139fd253035a1606bb24261951bbc3a6ca256717fa06cc41a898"}, + {file = "Django-4.2.16.tar.gz", hash = "sha256:6f1616c2786c408ce86ab7e10f792b8f15742f7b7b7460243929cb371e7f1dad"}, +] [package.dependencies] -asgiref = ">=3.3.2,<4" -pytz = "*" -sqlparse = ">=0.2.2" +asgiref = ">=3.6.0,<4" +"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} +sqlparse = ">=0.3.1" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} [package.extras] argon2 = ["argon2-cffi (>=19.1.0)"] @@ -171,106 +341,117 @@ bcrypt = ["bcrypt"] [[package]] name = "django-filter" -version = "22.1" +version = "24.3" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "django_filter-24.3-py3-none-any.whl", hash = "sha256:c4852822928ce17fb699bcfccd644b3574f1a2d80aeb2b4ff4f16b02dd49dc64"}, + {file = "django_filter-24.3.tar.gz", hash = "sha256:d8ccaf6732afd21ca0542f6733b11591030fa98669f8d15599b358e24a2cd9c3"}, +] [package.dependencies] -Django = ">=3.2" +Django = ">=4.2" [[package]] name = "djangorestframework" -version = "3.14.0" +version = "3.15.2" description = "Web APIs for Django, made easy." -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "djangorestframework-3.15.2-py3-none-any.whl", hash = "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20"}, + {file = "djangorestframework-3.15.2.tar.gz", hash = "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad"}, +] [package.dependencies] -django = ">=3.0" -pytz = "*" +"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} +django = ">=4.2" + +[[package]] +name = "executing" +version = "2.1.0" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.8" +files = [ + {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, + {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] [[package]] name = "factory-boy" version = "2.12.0" description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "factory_boy-2.12.0-py2.py3-none-any.whl", hash = "sha256:728df59b372c9588b83153facf26d3d28947fc750e8e3c95cefa9bed0e6394ee"}, + {file = "factory_boy-2.12.0.tar.gz", hash = "sha256:faf48d608a1735f0d0a3c9cbf536d64f9132b547dae7ba452c4d99a79e84a370"}, +] [package.dependencies] Faker = ">=0.7.0" [[package]] name = "faker" -version = "16.6.0" +version = "28.4.1" description = "Faker is a Python package that generates fake data for you." -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "Faker-28.4.1-py3-none-any.whl", hash = "sha256:e59c01d1e8b8e20a83255ab8232c143cb2af3b4f5ab6a3f5ce495f385ad8ab4c"}, + {file = "faker-28.4.1.tar.gz", hash = "sha256:4294d169255a045990720d6f3fa4134b764a4cdf46ef0d3c7553d2506f1adaa1"}, +] [package.dependencies] python-dateutil = ">=2.4" -typing-extensions = {version = ">=3.10.0.1", markers = "python_version < \"3.8\""} [[package]] name = "filelock" -version = "3.9.0" +version = "3.16.0" description = "A platform independent file lock." -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "filelock-3.16.0-py3-none-any.whl", hash = "sha256:f6ed4c963184f4c84dd5557ce8fece759a3724b37b80c6c4f20a2f63a4dc6609"}, + {file = "filelock-3.16.0.tar.gz", hash = "sha256:81de9eb8453c769b63369f87f11131a7ab04e367f8d97ad39dc230daa07e3bec"}, +] [package.extras] -docs = ["furo (>=2022.12.7)", "sphinx-autodoc-typehints (>=1.19.5)", "sphinx (>=5.3)"] -testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)", "pytest (>=7.2)"] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.1.1)", "pytest (>=8.3.2)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.3)"] +typing = ["typing-extensions (>=4.12.2)"] [[package]] name = "flake8" version = "3.9.2" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.7.0,<2.8.0" pyflakes = ">=2.3.0,<2.4.0" -[[package]] -name = "gitdb" -version = "4.0.10" -description = "Git Object Database" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -smmap = ">=3.0.1,<6" - -[[package]] -name = "gitpython" -version = "3.1.30" -description = "GitPython is a python library used to interact with Git repositories" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} - [[package]] name = "graphene" -version = "3.2.1" +version = "3.3" description = "GraphQL Framework for Python" -category = "main" optional = false python-versions = "*" +files = [ + {file = "graphene-3.3-py2.py3-none-any.whl", hash = "sha256:bb3810be33b54cb3e6969506671eb72319e8d7ba0d5ca9c8066472f75bf35a38"}, + {file = "graphene-3.3.tar.gz", hash = "sha256:529bf40c2a698954217d3713c6041d69d3f719ad0080857d7ee31327112446b0"}, +] [package.dependencies] aniso8601 = ">=8,<10" @@ -278,16 +459,19 @@ graphql-core = ">=3.1,<3.3" graphql-relay = ">=3.1,<3.3" [package.extras] -dev = ["black (==22.3.0)", "flake8 (>=4,<5)", "pytest (>=6,<7)", "pytest-benchmark (>=3.4,<4)", "pytest-cov (>=3,<4)", "pytest-mock (>=3,<4)", "pytest-asyncio (>=0.16,<2)", "snapshottest (>=0.6,<1)", "coveralls (>=3.3,<4)", "mock (>=4,<5)", "pytz (==2022.1)", "iso8601 (>=1,<2)"] -test = ["pytest (>=6,<7)", "pytest-benchmark (>=3.4,<4)", "pytest-cov (>=3,<4)", "pytest-mock (>=3,<4)", "pytest-asyncio (>=0.16,<2)", "snapshottest (>=0.6,<1)", "coveralls (>=3.3,<4)", "mock (>=4,<5)", "pytz (==2022.1)", "iso8601 (>=1,<2)"] +dev = ["black (==22.3.0)", "coveralls (>=3.3,<4)", "flake8 (>=4,<5)", "iso8601 (>=1,<2)", "mock (>=4,<5)", "pytest (>=6,<7)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=3.4,<4)", "pytest-cov (>=3,<4)", "pytest-mock (>=3,<4)", "pytz (==2022.1)", "snapshottest (>=0.6,<1)"] +test = ["coveralls (>=3.3,<4)", "iso8601 (>=1,<2)", "mock (>=4,<5)", "pytest (>=6,<7)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=3.4,<4)", "pytest-cov (>=3,<4)", "pytest-mock (>=3,<4)", "pytz (==2022.1)", "snapshottest (>=0.6,<1)"] [[package]] name = "graphene-django" -version = "3.0.0" +version = "3.2.2" description = "Graphene Django integration" -category = "main" optional = false python-versions = "*" +files = [ + {file = "graphene-django-3.2.2.tar.gz", hash = "sha256:059ccf25d9a5159f28d7ebf1a648c993ab34deb064e80b70ca096aa22a609556"}, + {file = "graphene_django-3.2.2-py2.py3-none-any.whl", hash = "sha256:0fd95c8c1cbe77ae2a5940045ce276803c3acbf200a156731e0c730f2776ae2c"}, +] [package.dependencies] Django = ">=3.2" @@ -298,78 +482,72 @@ promise = ">=2.1" text-unidecode = "*" [package.extras] -dev = ["black (==22.8.0)", "flake8 (==5.0.4)", "flake8-black (==0.3.3)", "flake8-bugbear (==22.9.11)", "pytest (>=7.1.3)", "pytest-cov", "pytest-random-order", "coveralls", "mock", "pytz", "django-filter (>=22.1)", "pytest-django (>=4.5.2)", "djangorestframework (>=3.6.3)"] -rest_framework = ["djangorestframework (>=3.6.3)"] -test = ["pytest (>=7.1.3)", "pytest-cov", "pytest-random-order", "coveralls", "mock", "pytz", "django-filter (>=22.1)", "pytest-django (>=4.5.2)", "djangorestframework (>=3.6.3)"] +dev = ["coveralls", "django-filter (>=22.1)", "djangorestframework (>=3.6.3)", "mock", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-django (>=4.5.2)", "pytest-random-order", "pytz", "ruff (==0.1.2)"] +rest-framework = ["djangorestframework (>=3.6.3)"] +test = ["coveralls", "django-filter (>=22.1)", "djangorestframework (>=3.6.3)", "mock", "pytest (>=7.3.1)", "pytest-cov", "pytest-django (>=4.5.2)", "pytest-random-order", "pytz"] [[package]] name = "graphql-core" -version = "3.2.3" +version = "3.2.4" description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL." -category = "main" optional = false -python-versions = ">=3.6,<4" - -[package.dependencies] -typing-extensions = {version = ">=4.2,<5", markers = "python_version < \"3.8\""} +python-versions = "<4,>=3.6" +files = [ + {file = "graphql-core-3.2.4.tar.gz", hash = "sha256:acbe2e800980d0e39b4685dd058c2f4042660b89ebca38af83020fd872ff1264"}, + {file = "graphql_core-3.2.4-py3-none-any.whl", hash = "sha256:1604f2042edc5f3114f49cac9d77e25863be51b23a54a61a23245cf32f6476f0"}, +] [[package]] name = "graphql-relay" version = "3.2.0" description = "Relay library for graphql-core" -category = "main" optional = false python-versions = ">=3.6,<4" +files = [ + {file = "graphql-relay-3.2.0.tar.gz", hash = "sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c"}, + {file = "graphql_relay-3.2.0-py3-none-any.whl", hash = "sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5"}, +] [package.dependencies] graphql-core = ">=3.2,<3.3" -typing-extensions = {version = ">=4.1,<5", markers = "python_version < \"3.8\""} - -[[package]] -name = "importlib-metadata" -version = "6.0.0" -description = "Read metadata from Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" - -[package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "sphinx-lint", "jaraco.tidelift (>=1.4)"] -perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] [[package]] name = "ipdb" -version = "0.13.11" +version = "0.13.13" description = "IPython-enabled pdb" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"}, + {file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"}, +] [package.dependencies] -decorator = {version = "*", markers = "python_version > \"3.6\" and python_version < \"3.11\" or python_version >= \"3.11\""} -ipython = {version = ">=7.31.1", markers = "python_version > \"3.6\" and python_version < \"3.11\" or python_version >= \"3.11\""} +decorator = {version = "*", markers = "python_version > \"3.6\""} +ipython = {version = ">=7.31.1", markers = "python_version > \"3.6\""} tomli = {version = "*", markers = "python_version > \"3.6\" and python_version < \"3.11\""} [[package]] name = "ipython" -version = "7.34.0" +version = "8.12.3" description = "IPython: Productive Interactive Computing" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, + {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, +] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} @@ -380,44 +558,78 @@ jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" -prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" -pygments = "*" -traitlets = ">=4.2" +prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] -doc = ["Sphinx (>=1.3)"] +all = ["black", "curio", "docrepr", "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"] +black = ["black"] +doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] -notebook = ["notebook", "ipywidgets"] +notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] +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"] [[package]] name = "jedi" -version = "0.18.2" +version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." -category = "dev" optional = false python-versions = ">=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"}, +] [package.dependencies] -parso = ">=0.8.0,<0.9.0" +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-rtd-theme (==0.4.3)", "sphinx (==1.8.5)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +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)"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[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 = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "matplotlib-inline" -version = "0.1.6" +version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" -category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" +files = [ + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, +] [package.dependencies] traitlets = "*" @@ -426,61 +638,93 @@ traitlets = "*" name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] + +[[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 = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = "*" +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 = "packaging" -version = "23.0" +version = "24.1" description = "Core utilities for Python packages" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] [[package]] name = "parso" -version = "0.8.3" +version = "0.8.4" description = "A Python Parser" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, +] [package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] [[package]] name = "pathspec" -version = "0.10.3" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false -python-versions = ">=3.7" +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 = "pbr" -version = "5.11.1" +version = "6.1.0" description = "Python Build Reasonableness" -category = "dev" optional = false python-versions = ">=2.6" +files = [ + {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"}, + {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"}, +] [[package]] name = "pexpect" -version = "4.8.0" +version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." -category = "dev" 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" @@ -489,35 +733,39 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" -category = "dev" 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 = "2.6.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" +version = "4.3.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.7" - -[package.dependencies] -typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"}, + {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"}, +] [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx-autodoc-typehints (>=1.19.5)", "sphinx (>=5.3)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest (>=7.2)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" -version = "1.0.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false -python-versions = ">=3.6" - -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] [package.extras] dev = ["pre-commit", "tox"] @@ -527,23 +775,28 @@ testing = ["pytest", "pytest-benchmark"] name = "promise" version = "2.3" description = "Promises/A+ implementation for Python" -category = "main" optional = false python-versions = "*" +files = [ + {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"}, +] [package.dependencies] six = "*" [package.extras] -test = ["pytest (>=2.7.3)", "pytest-cov", "coveralls", "futures", "pytest-benchmark", "mock"] +test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", "pytest-cov"] [[package]] name = "prompt-toolkit" -version = "3.0.36" +version = "3.0.47" description = "Library for building powerful interactive command lines in Python" -category = "dev" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, +] [package.dependencies] wcwidth = "*" @@ -552,58 +805,89 @@ wcwidth = "*" name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "dev" 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.3" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, +] + +[package.extras] +tests = ["pytest"] [[package]] name = "py" version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] [[package]] name = "pycodestyle" version = "2.7.0" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] [[package]] name = "pyflakes" version = "2.3.1" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] [[package]] name = "pygments" -version = "2.14.0" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] [package.extras] -plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pytest" version = "6.2.5" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, +] [package.dependencies] atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" @@ -617,9 +901,12 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm name = "pytest-cov" version = "2.12.1" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, + {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, +] [package.dependencies] coverage = ">=5.2.1" @@ -627,122 +914,227 @@ pytest = ">=4.6" toml = "*" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "pytest-django" version = "3.10.0" description = "A Django plugin for pytest." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pytest-django-3.10.0.tar.gz", hash = "sha256:4de6dbd077ed8606616958f77655fed0d5e3ee45159475671c7fa67596c6dba6"}, + {file = "pytest_django-3.10.0-py2.py3-none-any.whl", hash = "sha256:c33e3d3da14d8409b125d825d4e74da17bb252191bf6fc3da6856e27a8b73ea4"}, +] [package.dependencies] pytest = ">=3.6" [package.extras] docs = ["sphinx", "sphinx-rtd-theme"] -testing = ["django", "django-configurations (>=2.0)", "six"] +testing = ["Django", "django-configurations (>=2.0)", "six"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] [package.dependencies] six = ">=1.5" [[package]] -name = "pytz" -version = "2022.7.1" -description = "World timezone definitions, modern and historical" -category = "main" +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" optional = false -python-versions = "*" +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] [[package]] -name = "pyyaml" -version = "6.0" -description = "YAML parser and emitter for Python" -category = "dev" +name = "rich" +version = "13.8.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.8.1-py3-none-any.whl", hash = "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06"}, + {file = "rich-13.8.1.tar.gz", hash = "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" 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 = "smmap" -version = "5.0.0" -description = "A pure Python implementation of a sliding window memory map manager" -category = "dev" +name = "sqlparse" +version = "0.5.1" +description = "A non-validating SQL parser." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "sqlparse-0.5.1-py3-none-any.whl", hash = "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4"}, + {file = "sqlparse-0.5.1.tar.gz", hash = "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"}, +] + +[package.extras] +dev = ["build", "hatch"] +doc = ["sphinx"] [[package]] -name = "sqlparse" -version = "0.4.3" -description = "A non-validating SQL parser." -category = "main" +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" optional = false -python-versions = ">=3.5" +python-versions = "*" +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"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "stevedore" -version = "3.5.2" +version = "5.3.0" description = "Manage dynamic plugins for Python applications" -category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "stevedore-5.3.0-py3-none-any.whl", hash = "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78"}, + {file = "stevedore-5.3.0.tar.gz", hash = "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"}, +] [package.dependencies] -importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" [[package]] name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" -category = "main" optional = false python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] [[package]] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" 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 = "tox" version = "3.28.0" description = "tox is a generic virtualenv management and test command line tool" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "tox-3.28.0-py2.py3-none-any.whl", hash = "sha256:57b5ab7e8bb3074edc3c0c0b4b192a4f3799d3723b2c5b76f1fa9f2d40316eea"}, + {file = "tox-3.28.0.tar.gz", hash = "sha256:d0d28f3fe6d6d7195c27f8b054c3e99d5451952b54abdae673b71609a581f640"}, +] [package.dependencies] colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} filelock = ">=3.0.0" -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} packaging = ">=14" pluggy = ">=0.12.0" py = ">=1.4.17" @@ -752,237 +1144,77 @@ virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2, [package.extras] docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] -testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "psutil (>=5.6.1)", "pathlib2 (>=2.3.3)"] +testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)"] [[package]] name = "traitlets" -version = "5.8.1" +version = "5.14.3" description = "Traitlets Python configuration system" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, +] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] [[package]] -name = "typed-ast" -version = "1.5.4" -description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] [[package]] -name = "typing-extensions" -version = "4.4.0" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" optional = false -python-versions = ">=3.7" +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] [[package]] name = "virtualenv" -version = "20.17.1" +version = "20.26.4" description = "Virtual Python Environment builder" -category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"}, + {file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"}, +] [package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.4.1,<4" -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.8\""} -platformdirs = ">=2.4,<3" +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] -testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "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.6" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" -category = "dev" optional = false python-versions = "*" - -[[package]] -name = "zipp" -version = "3.11.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8"] +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] [metadata] -lock-version = "1.1" -python-versions = "^3.7 || ^3.8 || ^3.9 || ^3.10" -content-hash = "4978d34233f3a57717d957ac3ddbf6215a16a488477efe52309925f2fa5f43d8" - -[metadata.files] -aniso8601 = [] -appnope = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, -] -asgiref = [] -atomicwrites = [] -attrs = [] -backcall = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] -bandit = [] -black = [] -click = [] -colorama = [] -coverage = [] -decorator = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] -distlib = [] -django = [] -django-filter = [] -djangorestframework = [] -factory-boy = [] -faker = [] -filelock = [] -flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, -] -gitdb = [] -gitpython = [] -graphene = [] -graphene-django = [] -graphql-core = [] -graphql-relay = [] -importlib-metadata = [] -iniconfig = [] -ipdb = [] -ipython = [] -jedi = [] -matplotlib-inline = [] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -packaging = [] -parso = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, -] -pathspec = [] -pbr = [] -pexpect = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] -pickleshare = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] -platformdirs = [] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -promise = [] -prompt-toolkit = [] -ptyprocess = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] -pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, -] -pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, -] -pygments = [] -pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] -pytest-cov = [] -pytest-django = [] -python-dateutil = [ - {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"}, -] -pytz = [] -pyyaml = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -smmap = [] -sqlparse = [] -stevedore = [] -text-unidecode = [] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tomli = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] -tox = [] -traitlets = [] -typed-ast = [] -typing-extensions = [] -virtualenv = [] -wcwidth = [] -zipp = [] +lock-version = "2.0" +python-versions = "^3.8 || ^3.9 || ^3.10 || ^3.11 || ^3.12" +content-hash = "3708b587fa272e17264c64e6fa432f3443a2397ce632d61c0221a0d94118fc52" diff --git a/pyproject.toml b/pyproject.toml index 542ac32..220ed95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,11 +41,11 @@ classifiers = [ keywords = ["api", "graphql", "protocol", "graphene", "django"] [tool.poetry.dependencies] -python = "^3.7 || ^3.8 || ^3.9 || ^3.10" -django-filter = "^22.1" +python = "^3.8 || ^3.9 || ^3.10 || ^3.11 || ^3.12" +django-filter = "^24.3" djangorestframework = "^3" python-dateutil = "^2.8.0" -graphene-django = "^3.0" +graphene-django = "^3.2" [tool.poetry.dev-dependencies] pytest = "^6.2" diff --git a/tox.ini b/tox.ini index bf88cbe..514862c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,11 @@ [tox] isolated_build = true envlist = - py{37,38,39}-django32 + py{38,39}-django32 py{38,39,310}-django40 py{38,39,310}-django41 + py{310,311,312}-django50 + py{310,311,312}-django51 quality security build @@ -13,6 +15,8 @@ DJANGO = 3.2: django32 4.0: django40 4.1: django41 + 5.0: django50 + 5.1: django51 [testenv] allowlist_externals = poetry @@ -21,7 +25,7 @@ commands = poetry install -vvv poetry run pytest tests/ --cov=graphene_django_extras -[testenv:py{37,38,39}-django32] +[testenv:py{38,39}-django32] allowlist_externals = poetry skip_install = true commands = @@ -48,6 +52,26 @@ commands = poetry run pip install 'django~=4.1' poetry run pytest tests/ --cov=graphene_django_extras + +[testenv:py{310,311,312}-django50] +allowlist_externals = poetry +skip_install = true +commands = + poetry update --lock + poetry install -vvv + poetry run pip install 'django~=5.0' + poetry run pytest tests/ --cov=graphene_django_extras + + +[testenv:py{310,311,312}-django51] +allowlist_externals = poetry +skip_install = true +commands = + poetry update --lock + poetry install -vvv + poetry run pip install 'django~=5.1' + poetry run pytest tests/ --cov=graphene_django_extras + [testenv:quality] allowlist_externals = poetry skip_install = true From b43f226a52a4b437e3686907943fc6a6eb5af45c Mon Sep 17 00:00:00 2001 From: alainburindi Date: Thu, 12 Sep 2024 15:15:39 +0200 Subject: [PATCH 2/5] format codes with black --- .flake8 | 4 + .gitignore | 2 + graphene_django_extras/base_types.py | 12 +-- graphene_django_extras/converter.py | 86 ++++++++++++++----- graphene_django_extras/directives/date.py | 12 ++- graphene_django_extras/directives/list.py | 6 +- graphene_django_extras/directives/string.py | 52 ++++++++--- graphene_django_extras/fields.py | 74 ++++++++++++---- graphene_django_extras/filters/filter.py | 6 +- graphene_django_extras/middleware.py | 4 +- graphene_django_extras/mutation.py | 23 +++-- graphene_django_extras/paginations/fields.py | 28 ++++-- .../paginations/pagination.py | 26 ++++-- graphene_django_extras/paginations/utils.py | 8 +- graphene_django_extras/types.py | 43 +++++++--- graphene_django_extras/utils.py | 21 ++++- graphene_django_extras/views.py | 4 +- scripts/bump.py | 8 +- tests/conftest.py | 4 +- tests/schema.py | 16 +++- tests/test_fields.py | 28 ++++-- tests/urls.py | 4 +- 22 files changed, 359 insertions(+), 112 deletions(-) diff --git a/.flake8 b/.flake8 index 5ccf34c..5d9d9a9 100644 --- a/.flake8 +++ b/.flake8 @@ -5,3 +5,7 @@ ignore = E203, E266, E501, W503 max-line-length = 80 max-complexity = 18 select = B,C,E,F,W,T4,B9 +exclude = + .venv + .tox + dist diff --git a/.gitignore b/.gitignore index 8f06ad9..9b7f759 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ __pycache__ .pytest*/ .DS_Store + +.venv/ diff --git a/graphene_django_extras/base_types.py b/graphene_django_extras/base_types.py index 411360a..42058eb 100644 --- a/graphene_django_extras/base_types.py +++ b/graphene_django_extras/base_types.py @@ -154,9 +154,9 @@ def serialize(time): if isinstance(time, datetime.datetime): time = time.time() - assert isinstance(time, datetime.time), 'Received not compatible time "{}"'.format( - repr(time) - ) + assert isinstance( + time, datetime.time + ), 'Received not compatible time "{}"'.format(repr(time)) return time.isoformat() @@ -168,9 +168,9 @@ def serialize(date): if isinstance(date, datetime.datetime): date = date.date() - assert isinstance(date, datetime.date), 'Received not compatible date "{}"'.format( - repr(date) - ) + assert isinstance( + date, datetime.date + ), 'Received not compatible date "{}"'.format(repr(date)) return date.isoformat() diff --git a/graphene_django_extras/converter.py b/graphene_django_extras/converter.py index 86cc519..b11516f 100644 --- a/graphene_django_extras/converter.py +++ b/graphene_django_extras/converter.py @@ -4,10 +4,26 @@ from functools import singledispatch from django.conf import settings -from django.contrib.contenttypes.fields import GenericForeignKey, GenericRel, GenericRelation +from django.contrib.contenttypes.fields import ( + GenericForeignKey, + GenericRel, + GenericRelation, +) from django.db import models from django.utils.encoding import force_str -from graphene import ID, UUID, Boolean, Dynamic, Enum, Field, Float, Int, List, NonNull, String +from graphene import ( + ID, + UUID, + Boolean, + Dynamic, + Enum, + Field, + Float, + Int, + List, + NonNull, + String, +) from graphene.types.json import JSONString from graphene.utils.str_converters import to_camel_case from graphene_django.compat import ArrayField, HStoreField, JSONField, RangeField @@ -30,9 +46,9 @@ def assert_valid_name(name): """Helper to assert that provided names are valid.""" - assert COMPILED_NAME_PATTERN.match(name), 'Names must match /{}/ but "{}" does not.'.format( - NAME_PATTERN, name - ) + assert COMPILED_NAME_PATTERN.match( + name + ), 'Names must match /{}/ but "{}" does not.'.format(NAME_PATTERN, name) def convert_choice_name(name): @@ -59,7 +75,9 @@ def get_choices(choices): yield name, value, description -def convert_django_field_with_choices(field, registry=None, input_flag=None, nested_field=False): +def convert_django_field_with_choices( + field, registry=None, input_flag=None, nested_field=False +): choices = getattr(field, "choices", None) if choices: meta = field.model._meta @@ -109,14 +127,18 @@ def construct_fields( if settings.DEBUG: if input_flag == "create": - _model_fields = sorted(_model_fields, key=lambda f: (not is_required(f[1]), f[0])) + _model_fields = sorted( + _model_fields, key=lambda f: (not is_required(f[1]), f[0]) + ) elif not input_flag: _model_fields = sorted(_model_fields, key=lambda f: f[0]) fields = OrderedDict() if input_flag == "delete": - converted = convert_django_field_with_choices(dict(_model_fields)["id"], registry) + converted = convert_django_field_with_choices( + dict(_model_fields)["id"], registry + ) fields["id"] = converted else: for name, field in _model_fields: @@ -126,7 +148,9 @@ def construct_fields( nested_field = name in nested_fields is_not_in_only = only_fields and name not in only_fields # is_already_created = name in options.fields - is_excluded = exclude_fields and name in exclude_fields # or is_already_created + is_excluded = ( + exclude_fields and name in exclude_fields + ) # or is_already_created # https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_query_name is_no_backref = str(name).endswith("+") # if is_not_in_only or is_excluded or is_no_backref: @@ -144,7 +168,9 @@ def construct_fields( ): continue - converted = convert_django_field_with_choices(field, registry, input_flag, nested_field) + converted = convert_django_field_with_choices( + field, registry, input_flag, nested_field + ) fields[name] = converted return fields @@ -152,7 +178,9 @@ def construct_fields( @singledispatch def convert_django_field(field, registry=None, input_flag=None, nested_field=False): raise Exception( - "Don't know how to convert the Django field {} ({})".format(field, field.__class__) + "Don't know how to convert the Django field {} ({})".format( + field, field.__class__ + ) ) @@ -212,7 +240,9 @@ def convert_field_to_boolean(field, registry=None, input_flag=None, nested_field @convert_django_field.register(models.NullBooleanField) -def convert_field_to_nullboolean(field, registry=None, input_flag=None, nested_field=False): +def convert_field_to_nullboolean( + field, registry=None, input_flag=None, nested_field=False +): return Boolean( description=field.help_text or field.verbose_name, required=is_required(field) and input_flag == "create", @@ -246,7 +276,9 @@ def convert_date_to_string(field, registry=None, input_flag=None, nested_field=F @convert_django_field.register(models.DateTimeField) -def convert_datetime_to_string(field, registry=None, input_flag=None, nested_field=False): +def convert_datetime_to_string( + field, registry=None, input_flag=None, nested_field=False +): return CustomDateTime( description=field.help_text or field.verbose_name, required=is_required(field) and input_flag == "create", @@ -279,7 +311,9 @@ def dynamic_type(): @convert_django_field.register(models.ManyToManyField) -def convert_field_to_list_or_connection(field, registry=None, input_flag=None, nested_field=False): +def convert_field_to_list_or_connection( + field, registry=None, input_flag=None, nested_field=False +): model = get_related_model(field) def dynamic_type(): @@ -315,7 +349,9 @@ def dynamic_type(): @convert_django_field.register(GenericRel) @convert_django_field.register(models.ManyToManyRel) @convert_django_field.register(models.ManyToOneRel) -def convert_many_rel_to_djangomodel(field, registry=None, input_flag=None, nested_field=False): +def convert_many_rel_to_djangomodel( + field, registry=None, input_flag=None, nested_field=False +): model = field.related_model def dynamic_type(): @@ -343,12 +379,16 @@ def dynamic_type(): @convert_django_field.register(models.OneToOneField) @convert_django_field.register(models.ForeignKey) -def convert_field_to_djangomodel(field, registry=None, input_flag=None, nested_field=False): +def convert_field_to_djangomodel( + field, registry=None, input_flag=None, nested_field=False +): model = get_related_model(field) def dynamic_type(): # Avoid create field for auto generate OneToOneField product of an inheritance - if isinstance(field, models.OneToOneField) and issubclass(field.model, field.related_model): + if isinstance(field, models.OneToOneField) and issubclass( + field.model, field.related_model + ): return if input_flag and not nested_field: return ID( @@ -433,7 +473,9 @@ def dynamic_type(): @convert_django_field.register(ArrayField) -def convert_postgres_array_to_list(field, registry=None, input_flag=None, nested_field=False): +def convert_postgres_array_to_list( + field, registry=None, input_flag=None, nested_field=False +): base_type = convert_django_field(field.base_field) if not isinstance(base_type, (List, NonNull)): base_type = type(base_type) @@ -446,7 +488,9 @@ def convert_postgres_array_to_list(field, registry=None, input_flag=None, nested @convert_django_field.register(HStoreField) @convert_django_field.register(JSONField) -def convert_postgres_field_to_string(field, registry=None, input_flag=None, nested_field=False): +def convert_postgres_field_to_string( + field, registry=None, input_flag=None, nested_field=False +): return JSONString( description=field.help_text or field.verbose_name, required=is_required(field) and input_flag == "create", @@ -454,7 +498,9 @@ def convert_postgres_field_to_string(field, registry=None, input_flag=None, nest @convert_django_field.register(RangeField) -def convert_postgres_range_to_string(field, registry=None, input_flag=None, nested_field=False): +def convert_postgres_range_to_string( + field, registry=None, input_flag=None, nested_field=False +): inner_type = convert_django_field(field.base_field) if not isinstance(inner_type, (List, NonNull)): inner_type = type(inner_type) diff --git a/graphene_django_extras/directives/date.py b/graphene_django_extras/directives/date.py index 963e077..f96ae8d 100644 --- a/graphene_django_extras/directives/date.py +++ b/graphene_django_extras/directives/date.py @@ -140,7 +140,9 @@ def _format_relativedelta(rdelta, full=False, two_days=False, original_dt=None): def _format_time_ago(dt, now=None, full=False, ago_in=False, two_days=False): if not isinstance(dt, timedelta): if now is None: - now = timezone.localtime(timezone=timezone.get_fixed_timezone(-int(t.timezone / 60))) + now = timezone.localtime( + timezone=timezone.get_fixed_timezone(-int(t.timezone / 60)) + ) original_dt = dt dt = _parse(dt) @@ -201,7 +203,9 @@ def _format_dt(dt, format="default"): else: if temp_format != "": if temp_format in FORMATS_MAP: - translate_format_list.append(FORMATS_MAP.get(temp_format, "")) + translate_format_list.append( + FORMATS_MAP.get(temp_format, "") + ) else: return None if str_in_dict_keys(char, FORMATS_MAP): @@ -236,7 +240,9 @@ def get_args(): @staticmethod def resolve(value, directive, root, info, **kwargs): - format_argument = [arg for arg in directive.arguments if arg.name.value == "format"] + format_argument = [ + arg for arg in directive.arguments if arg.name.value == "format" + ] format_argument = format_argument[0] if len(format_argument) > 0 else None custom_format = format_argument.value.value if format_argument else "default" diff --git a/graphene_django_extras/directives/list.py b/graphene_django_extras/directives/list.py index 7b995b6..a82fac5 100644 --- a/graphene_django_extras/directives/list.py +++ b/graphene_django_extras/directives/list.py @@ -24,7 +24,11 @@ def resolve(value, directive, root, info, **kwargs): class SampleGraphQLDirective(BaseExtraGraphQLDirective): @staticmethod def get_args(): - return {"k": GraphQLArgument(GraphQLNonNull(GraphQLInt), description="Value to default to")} + return { + "k": GraphQLArgument( + GraphQLNonNull(GraphQLInt), description="Value to default to" + ) + } @staticmethod def resolve(value, directive, root, info, **kwargs): diff --git a/graphene_django_extras/directives/string.py b/graphene_django_extras/directives/string.py index e78a124..8b27f6f 100644 --- a/graphene_django_extras/directives/string.py +++ b/graphene_django_extras/directives/string.py @@ -35,13 +35,17 @@ class DefaultGraphQLDirective(BaseExtraGraphQLDirective): @staticmethod def get_args(): return { - "to": GraphQLArgument(GraphQLNonNull(GraphQLString), description="Value to default to") + "to": GraphQLArgument( + GraphQLNonNull(GraphQLString), description="Value to default to" + ) } @staticmethod def resolve(value, directive, root, info, **kwargs): if not value: - to_argument = [arg for arg in directive.arguments if arg.name.value == "to"][0] + to_argument = [ + arg for arg in directive.arguments if arg.name.value == "to" + ][0] return to_argument.value.value return value @@ -82,7 +86,9 @@ class NumberGraphQLDirective(BaseExtraGraphQLDirective): @staticmethod def get_args(): return { - "as": GraphQLArgument(GraphQLNonNull(GraphQLString), description="Value to default to") + "as": GraphQLArgument( + GraphQLNonNull(GraphQLString), description="Value to default to" + ) } @staticmethod @@ -95,7 +101,9 @@ class CurrencyGraphQLDirective(BaseExtraGraphQLDirective): @staticmethod def get_args(): return { - "symbol": GraphQLArgument(GraphQLString, description="Currency symbol (default: $)") + "symbol": GraphQLArgument( + GraphQLString, description="Currency symbol (default: $)" + ) } @staticmethod @@ -204,8 +212,12 @@ def get_args(): @staticmethod def resolve(value, directive, root, info, **kwargs): - chars_argument = [arg for arg in directive.arguments if arg.name.value == "chars"] - chars_argument = chars_argument[0].value.value if len(chars_argument) > 0 else " " + chars_argument = [ + arg for arg in directive.arguments if arg.name.value == "chars" + ] + chars_argument = ( + chars_argument[0].value.value if len(chars_argument) > 0 else " " + ) value = value if isinstance(value, six.string_types) else str(value) return value.strip(chars_argument) @@ -242,11 +254,19 @@ def get_args(): @staticmethod def resolve(value, directive, root, info, **kwargs): - width_argument = [arg for arg in directive.arguments if arg.name.value == "width"] - width_argument = width_argument[0].value.value if len(width_argument) > 0 else len(value) + width_argument = [ + arg for arg in directive.arguments if arg.name.value == "width" + ] + width_argument = ( + width_argument[0].value.value if len(width_argument) > 0 else len(value) + ) - fillchar_argument = [arg for arg in directive.arguments if arg.name.value == "fillchar"] - fillchar_argument = fillchar_argument[0].value.value if len(fillchar_argument) > 0 else " " + fillchar_argument = [ + arg for arg in directive.arguments if arg.name.value == "fillchar" + ] + fillchar_argument = ( + fillchar_argument[0].value.value if len(fillchar_argument) > 0 else " " + ) value = value if isinstance(value, six.string_types) else str(value) return value.center(int(width_argument), fillchar_argument) @@ -269,7 +289,9 @@ def get_args(): GraphQLNonNull(GraphQLString), description="Value of new character to replace", ), - "count": GraphQLArgument(GraphQLInt, description="Value to returned str lenght"), + "count": GraphQLArgument( + GraphQLInt, description="Value to returned str lenght" + ), } @staticmethod @@ -280,8 +302,12 @@ def resolve(value, directive, root, info, **kwargs): new_argument = [arg for arg in directive.arguments if arg.name.value == "new"] new_argument = new_argument[0].value.value if len(new_argument) > 0 else None - count_argument = [arg for arg in directive.arguments if arg.name.value == "count"] - count_argument = count_argument[0].value.value if len(count_argument) > 0 else -1 + count_argument = [ + arg for arg in directive.arguments if arg.name.value == "count" + ] + count_argument = ( + count_argument[0].value.value if len(count_argument) > 0 else -1 + ) value = value if isinstance(value, six.string_types) else str(value) return value.replace(old_argument, new_argument, int(count_argument)) diff --git a/graphene_django_extras/fields.py b/graphene_django_extras/fields.py index f5eed8f..5c86bce 100644 --- a/graphene_django_extras/fields.py +++ b/graphene_django_extras/fields.py @@ -6,7 +6,11 @@ from graphene.types.structures import NonNull, Structure from graphene_django.fields import DjangoListField as DLF from graphene_django.filter.utils import get_filtering_args_from_filterset -from graphene_django.utils import DJANGO_FILTER_INSTALLED, is_valid_django_model, maybe_queryset +from graphene_django.utils import ( + DJANGO_FILTER_INSTALLED, + is_valid_django_model, + maybe_queryset, +) from graphene_django_extras.filters.filter import get_filterset_class from graphene_django_extras.settings import graphql_api_settings @@ -21,7 +25,9 @@ # *********************************************** # class DjangoObjectField(Field): def __init__(self, _type, *args, **kwargs): - kwargs["id"] = ID(required=True, description="Django object unique identification field") + kwargs["id"] = ID( + required=True, description="Django object unique identification field" + ) super(DjangoObjectField, self).__init__(_type, *args, **kwargs) @@ -73,16 +79,26 @@ def __init__( meta.update(extra_filter_meta) filterset_class = filterset_class or _type._meta.filterset_class self.filterset_class = get_filterset_class(filterset_class, **meta) - self.filtering_args = get_filtering_args_from_filterset(self.filterset_class, _type) + self.filtering_args = get_filtering_args_from_filterset( + self.filterset_class, _type + ) kwargs.setdefault("args", {}) kwargs["args"].update(self.filtering_args) if "id" not in kwargs["args"].keys(): self.filtering_args.update( - {"id": Argument(ID, description="Django object unique identification field")} + { + "id": Argument( + ID, description="Django object unique identification field" + ) + } ) kwargs["args"].update( - {"id": Argument(ID, description="Django object unique identification field")} + { + "id": Argument( + ID, description="Django object unique identification field" + ) + } ) if not kwargs.get("description", None): @@ -108,18 +124,24 @@ def list_resolver(manager, filterset_class, filtering_args, root, info, **kwargs try: if filter_kwargs: qs = operator.attrgetter( - "{}.filter".format(getattr(field, "related_name", None) or field.name) + "{}.filter".format( + getattr(field, "related_name", None) or field.name + ) )(root)(**filter_kwargs) else: qs = operator.attrgetter( - "{}.all".format(getattr(field, "related_name", None) or field.name) + "{}.all".format( + getattr(field, "related_name", None) or field.name + ) )(root)() except AttributeError: qs = None if qs is None: qs = queryset_factory(manager, root, info, **kwargs) - qs = filterset_class(data=filter_kwargs, queryset=qs, request=info.context).qs + qs = filterset_class( + data=filter_kwargs, queryset=qs, request=info.context + ).qs if root and is_valid_django_model(root._meta.model): extra_filters = get_extra_filters(root, manager.model) @@ -160,16 +182,26 @@ def __init__( filterset_class = filterset_class or _type._meta.filterset_class self.filterset_class = get_filterset_class(filterset_class, **meta) - self.filtering_args = get_filtering_args_from_filterset(self.filterset_class, _type) + self.filtering_args = get_filtering_args_from_filterset( + self.filterset_class, _type + ) kwargs.setdefault("args", {}) kwargs["args"].update(self.filtering_args) if "id" not in kwargs["args"].keys(): self.filtering_args.update( - {"id": Argument(ID, description="Django object unique identification field")} + { + "id": Argument( + ID, description="Django object unique identification field" + ) + } ) kwargs["args"].update( - {"id": Argument(ID, description="Django object unique identification field")} + { + "id": Argument( + ID, description="Django object unique identification field" + ) + } ) pagination = pagination or graphql_api_settings.DEFAULT_PAGINATION_CLASS() @@ -187,7 +219,9 @@ def __init__( if not kwargs.get("description", None): kwargs["description"] = "{} list".format(_type._meta.model.__name__) - super(DjangoFilterPaginateListField, self).__init__(List(NonNull(_type)), *args, **kwargs) + super(DjangoFilterPaginateListField, self).__init__( + List(NonNull(_type)), *args, **kwargs + ) @property def model(self): @@ -196,7 +230,9 @@ def model(self): def get_queryset(self, manager, root, info, **kwargs): return queryset_factory(manager, root, info, **kwargs) - def list_resolver(self, manager, filterset_class, filtering_args, root, info, **kwargs): + def list_resolver( + self, manager, filterset_class, filtering_args, root, info, **kwargs + ): filter_kwargs = {k: v for k, v in kwargs.items() if k in filtering_args} qs = self.get_queryset(manager, root, info, **kwargs) qs = filterset_class(data=filter_kwargs, queryset=qs, request=info.context).qs @@ -244,13 +280,17 @@ def __init__( filterset_class = filterset_class or _type._meta.filterset_class self.filterset_class = get_filterset_class(filterset_class, **meta) - self.filtering_args = get_filtering_args_from_filterset(self.filterset_class, _type) + self.filtering_args = get_filtering_args_from_filterset( + self.filterset_class, _type + ) kwargs.setdefault("args", {}) kwargs["args"].update(self.filtering_args) if "id" not in kwargs["args"].keys(): id_description = "Django object unique identification field" - self.filtering_args.update({"id": Argument(ID, description=id_description)}) + self.filtering_args.update( + {"id": Argument(ID, description=id_description)} + ) kwargs["args"].update({"id": Argument(ID, description=id_description)}) if not kwargs.get("description", None): @@ -262,7 +302,9 @@ def __init__( def model(self): return self.type._meta.model - def list_resolver(self, manager, filterset_class, filtering_args, root, info, **kwargs): + def list_resolver( + self, manager, filterset_class, filtering_args, root, info, **kwargs + ): qs = queryset_factory(manager, root, info, **kwargs) filter_kwargs = {k: v for k, v in kwargs.items() if k in filtering_args} diff --git a/graphene_django_extras/filters/filter.py b/graphene_django_extras/filters/filter.py index 07155c1..a52c597 100644 --- a/graphene_django_extras/filters/filter.py +++ b/graphene_django_extras/filters/filter.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- -from django_filters.filterset import FILTER_FOR_DBFIELD_DEFAULTS, BaseFilterSet, FilterSet +from django_filters.filterset import ( + FILTER_FOR_DBFIELD_DEFAULTS, + BaseFilterSet, + FilterSet, +) from graphene_django.filter.utils import replace_csv_filters diff --git a/graphene_django_extras/middleware.py b/graphene_django_extras/middleware.py index 24cf619..ea0031f 100644 --- a/graphene_django_extras/middleware.py +++ b/graphene_django_extras/middleware.py @@ -22,6 +22,8 @@ def __process_value(self, value, root, info, **kwargs): GraphQLSkipDirective.name, ): directive_class = registry.get_directive(directive.name.value) - new_value = directive_class.resolve(new_value, directive, root, info, **kwargs) + new_value = directive_class.resolve( + new_value, directive, root, info, **kwargs + ) return new_value diff --git a/graphene_django_extras/mutation.py b/graphene_django_extras/mutation.py index f83cac9..3ee7784 100644 --- a/graphene_django_extras/mutation.py +++ b/graphene_django_extras/mutation.py @@ -50,11 +50,15 @@ def __init_subclass_with_meta__( **options, ): if not serializer_class: - raise Exception("serializer_class is required on all DjangoSerializerMutation") + raise Exception( + "serializer_class is required on all DjangoSerializerMutation" + ) model = serializer_class.Meta.model - description = description or "SerializerMutation for {} model".format(model.__name__) + description = description or "SerializerMutation for {} model".format( + model.__name__ + ) input_field_name = input_field_name or "new_{}".format(model._meta.model_name) output_field_name = output_field_name or model._meta.model_name @@ -206,7 +210,9 @@ def delete(cls, root, info, **kwargs): ErrorType( field="id", messages=[ - "A {} obj with id {} do not exist".format(cls._meta.model.__name__, pk) + "A {} obj with id {} do not exist".format( + cls._meta.model.__name__, pk + ) ], ) ] @@ -242,7 +248,9 @@ def update(cls, root, info, **kwargs): ErrorType( field="id", messages=[ - "A {} obj with id: {} do not exist".format(cls._meta.model.__name__, pk) + "A {} obj with id: {} do not exist".format( + cls._meta.model.__name__, pk + ) ], ) ] @@ -256,14 +264,17 @@ def save(cls, serialized_obj, root, info, **kwargs): """ for key in serialized_obj.initial_data: if "Enum" in type(serialized_obj.initial_data[key]).__name__: - serialized_obj.initial_data[key] = serialized_obj.initial_data[key].value + serialized_obj.initial_data[key] = serialized_obj.initial_data[ + key + ].value if serialized_obj.is_valid(): obj = serialized_obj.save() return True, obj else: errors = [ - ErrorType(field=key, messages=value) for key, value in serialized_obj.errors.items() + ErrorType(field=key, messages=value) + for key, value in serialized_obj.errors.items() ] return False, errors diff --git a/graphene_django_extras/paginations/fields.py b/graphene_django_extras/paginations/fields.py index 7b9efa7..1188f1c 100644 --- a/graphene_django_extras/paginations/fields.py +++ b/graphene_django_extras/paginations/fields.py @@ -16,7 +16,9 @@ def model(self): return self.type.of_type._meta.node._meta.model def wrap_resolve(self, parent_resolver): - return partial(self.list_resolver, self.type.of_type._meta.model._default_manager) + return partial( + self.list_resolver, self.type.of_type._meta.model._default_manager + ) # *********************************************** # @@ -47,7 +49,9 @@ def __init__( kwargs[limit_query_param] = Int( default_value=self.default_limit, description="Number of results to return per page. Actual " - "'default_limit': {}, and 'max_limit': {}".format(self.default_limit, self.max_limit), + "'default_limit': {}, and 'max_limit': {}".format( + self.default_limit, self.max_limit + ), ) kwargs[offset_query_param] = Int( @@ -120,7 +124,9 @@ def __init__( self.ordering_param = ordering_param self.page_size_query_description = ( - "Number of results to return per page. Actual 'page_size': {}".format(self.page_size) + "Number of results to return per page. Actual 'page_size': {}".format( + self.page_size + ) ) kwargs[self.page_query_param] = Int( @@ -171,7 +177,9 @@ def list_resolver(self, manager, root, info, **kwargs): "declaration to specify a custom page size value through a query parameters" ) - offset = int(count - fabs(page_size * page)) if page < 0 else page_size * (page - 1) + offset = ( + int(count - fabs(page_size * page)) if page < 0 else page_size * (page - 1) + ) order = kwargs.pop(self.ordering_param, None) or self.ordering if order: @@ -186,7 +194,9 @@ def list_resolver(self, manager, root, info, **kwargs): class CursorPaginationField(AbstractPaginationField): - def __init__(self, _type, ordering="-created", cursor_query_param="cursor", *args, **kwargs): + def __init__( + self, _type, ordering="-created", cursor_query_param="cursor", *args, **kwargs + ): kwargs.setdefault("args", {}) self.page_size = graphql_api_settings.DEFAULT_PAGE_SIZE @@ -196,7 +206,9 @@ def __init__(self, _type, ordering="-created", cursor_query_param="cursor", *arg self.cursor_query_description = "The pagination cursor value." self.page_size_query_description = "Number of results to return per page." - kwargs[self.cursor_query_param] = NonNull(String, description=self.cursor_query_description) + kwargs[self.cursor_query_param] = NonNull( + String, description=self.cursor_query_description + ) if self.page_size_query_param: if not self.page_size: @@ -212,5 +224,7 @@ def __init__(self, _type, ordering="-created", cursor_query_param="cursor", *arg def list_resolver(self, manager, root, info, **kwargs): raise NotImplementedError( - "{} list_resolver() are not implemented yet.".format(self.__class__.__name__) + "{} list_resolver() are not implemented yet.".format( + self.__class__.__name__ + ) ) diff --git a/graphene_django_extras/paginations/pagination.py b/graphene_django_extras/paginations/pagination.py index 6811147..b01600d 100644 --- a/graphene_django_extras/paginations/pagination.py +++ b/graphene_django_extras/paginations/pagination.py @@ -32,7 +32,9 @@ def to_graphql_fields(self): ) def to_dict(self): - raise NotImplementedError("to_dict() function must be implemented into child classes.") + raise NotImplementedError( + "to_dict() function must be implemented into child classes." + ) def paginate_queryset(self, qs, **kwargs): raise NotImplementedError( @@ -156,7 +158,9 @@ def __init__( self.ordering_param = ordering_param self.page_size_query_description = ( - "Number of results to return per page. Default 'page_size': {}".format(self.page_size) + "Number of results to return per page. Default 'page_size': {}".format( + self.page_size + ) ) def to_dict(self): @@ -183,7 +187,11 @@ def to_graphql_fields(self): if self.page_size_query_param: paginator_dict.update( - {self.page_size_query_param: Int(description=self.page_size_query_description)} + { + self.page_size_query_param: Int( + description=self.page_size_query_description + ) + } ) return paginator_dict @@ -212,7 +220,11 @@ def paginate_queryset(self, qs, **kwargs): """ return None - offset = max(0, int(count + page_size * page)) if page < 0 else page_size * (page - 1) + offset = ( + max(0, int(count + page_size * page)) + if page < 0 + else page_size * (page - 1) + ) order = kwargs.pop(self.ordering_param, None) or self.ordering if order: @@ -245,7 +257,11 @@ def to_dict(self): } def to_graphql_fields(self): - return {self.cursor_query_param: NonNull(String, description=self.cursor_query_description)} + return { + self.cursor_query_param: NonNull( + String, description=self.cursor_query_description + ) + } def paginate_queryset(self, qs, **kwargs): raise NotImplementedError( diff --git a/graphene_django_extras/paginations/utils.py b/graphene_django_extras/paginations/utils.py index b35d97b..01b2be3 100644 --- a/graphene_django_extras/paginations/utils.py +++ b/graphene_django_extras/paginations/utils.py @@ -26,7 +26,9 @@ def __init__(self, _type, paginator_instance, *args, **kwargs): } ) - super(GenericPaginationField, self).__init__(graphene.List(_type), *args, **kwargs) + super(GenericPaginationField, self).__init__( + graphene.List(_type), *args, **kwargs + ) @property def model(self): @@ -38,7 +40,9 @@ def list_resolver(self, manager, root, info, **kwargs): return None def wrap_resolve(self, parent_resolver): - return partial(self.list_resolver, self.type.of_type._meta.model._default_manager) + return partial( + self.list_resolver, self.type.of_type._meta.model._default_manager + ) def _positive_int(integer_string, strict=False, cutoff=None): diff --git a/graphene_django_extras/types.py b/graphene_django_extras/types.py index c0504a0..cb1a129 100644 --- a/graphene_django_extras/types.py +++ b/graphene_django_extras/types.py @@ -10,7 +10,11 @@ from graphene.utils.deprecated import warn_deprecation from graphene.utils.props import props from graphene_django.types import ErrorType -from graphene_django.utils import DJANGO_FILTER_INSTALLED, is_valid_django_model, maybe_queryset +from graphene_django.utils import ( + DJANGO_FILTER_INSTALLED, + is_valid_django_model, + maybe_queryset, +) from .base_types import DjangoListObjectBase, factory_type from .converter import construct_fields @@ -84,7 +88,8 @@ def __init_subclass_with_meta__( registry = get_global_registry() assert isinstance(registry, Registry), ( - "The attribute registry in {} needs to be an instance of " 'Registry, received "{}".' + "The attribute registry in {} needs to be an instance of " + 'Registry, received "{}".' ).format(cls.__name__, registry) if not DJANGO_FILTER_INSTALLED and (filter_fields or filterset_class): @@ -93,7 +98,9 @@ def __init_subclass_with_meta__( ) django_fields = yank_fields_from_attrs( - construct_fields(model, registry, only_fields, include_fields, exclude_fields), + construct_fields( + model, registry, only_fields, include_fields, exclude_fields + ), _as=Field, ) @@ -162,7 +169,8 @@ def __init_subclass_with_meta__( registry = get_global_registry() assert isinstance(registry, Registry), ( - "The attribute registry in {} needs to be an instance of " 'Registry, received "{}".' + "The attribute registry in {} needs to be an instance of " + 'Registry, received "{}".' ).format(cls.__name__, registry) assert input_for.lower not in ("create", "delete", "update"), ( @@ -189,7 +197,9 @@ def __init_subclass_with_meta__( ) for base in reversed(cls.__mro__): - django_input_fields.update(yank_fields_from_attrs(base.__dict__, _as=InputField)) + django_input_fields.update( + yank_fields_from_attrs(base.__dict__, _as=InputField) + ) if container is None: container = type(cls.__name__, (InputObjectTypeContainer, cls), {}) @@ -314,7 +324,9 @@ def __init_subclass_with_meta__( ] ) - super(DjangoListObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options) + super(DjangoListObjectType, cls).__init_subclass_with_meta__( + _meta=_meta, **options + ) @classmethod def RetrieveField(cls, *args, **kwargs): @@ -359,7 +371,9 @@ def __init_subclass_with_meta__( model = serializer_class.Meta.model - description = description or "ModelSerializerType for {} model".format(model.__name__) + description = description or "ModelSerializerType for {} model".format( + model.__name__ + ) input_field_name = input_field_name or "new_{}".format(model._meta.model_name) output_field_name = output_field_name or model._meta.model_name @@ -529,7 +543,9 @@ def delete(cls, root, info, **kwargs): ErrorType( field="id", messages=[ - "A {} obj with id {} do not exist".format(cls._meta.model.__name__, pk) + "A {} obj with id {} do not exist".format( + cls._meta.model.__name__, pk + ) ], ) ] @@ -565,7 +581,9 @@ def update(cls, root, info, **kwargs): ErrorType( field="id", messages=[ - "A {} obj with id: {} do not exist".format(cls._meta.model.__name__, pk) + "A {} obj with id: {} do not exist".format( + cls._meta.model.__name__, pk + ) ], ) ] @@ -579,7 +597,8 @@ def save(cls, serialized_obj, root, info, **kwargs): else: errors = [ - ErrorType(field=key, messages=value) for key, value in serialized_obj.errors.items() + ErrorType(field=key, messages=value) + for key, value in serialized_obj.errors.items() ] return False, errors @@ -613,7 +632,9 @@ def RetrieveField(cls, *args, **kwargs): @classmethod def ListField(cls, *args, **kwargs): - return DjangoListObjectField(cls._meta.output_list_type, resolver=cls.list, **kwargs) + return DjangoListObjectField( + cls._meta.output_list_type, resolver=cls.list, **kwargs + ) @classmethod def CreateField(cls, *args, **kwargs): diff --git a/graphene_django_extras/utils.py b/graphene_django_extras/utils.py index 05931f9..8b057e0 100644 --- a/graphene_django_extras/utils.py +++ b/graphene_django_extras/utils.py @@ -8,7 +8,14 @@ from django.apps import apps from django.contrib.contenttypes.fields import GenericForeignKey, GenericRel from django.core.exceptions import ImproperlyConfigured, ValidationError -from django.db.models import NOT_PROVIDED, Manager, ManyToManyRel, ManyToOneRel, Model, QuerySet +from django.db.models import ( + NOT_PROVIDED, + Manager, + ManyToManyRel, + ManyToOneRel, + Model, + QuerySet, +) from django.db.models.base import ModelBase from graphene.utils.str_converters import to_snake_case from graphene_django.utils import is_valid_django_model @@ -85,7 +92,9 @@ def get_model_fields(model): reverse_fields = list(get_reverse_fields(model)) exclude_fields = [field[1] for field in reverse_fields] - local_fields = [(field.name, field) for field in all_fields_list if field not in exclude_fields] + local_fields = [ + (field.name, field) for field in all_fields_list if field not in exclude_fields + ] all_fields = local_fields + reverse_fields @@ -165,7 +174,9 @@ def clean_dict(d): return d if isinstance(d, list): return [v for v in (clean_dict(v) for v in d) if v] - return OrderedDict([(k, v) for k, v in ((k, clean_dict(v)) for k, v in list(d.items())) if v]) + return OrderedDict( + [(k, v) for k, v in ((k, clean_dict(v)) for k, v in list(d.items())) if v] + ) def get_type(_type): @@ -289,7 +300,9 @@ def get_related_fields(model): def find_field(field, fields_dict): - temp = fields_dict.get(field.name.value, fields_dict.get(to_snake_case(field.name.value), None)) + temp = fields_dict.get( + field.name.value, fields_dict.get(to_snake_case(field.name.value), None) + ) return temp diff --git a/graphene_django_extras/views.py b/graphene_django_extras/views.py index 442ced1..942fd16 100644 --- a/graphene_django_extras/views.py +++ b/graphene_django_extras/views.py @@ -105,7 +105,9 @@ def get_response(self, request, data, show_graphiql=False): response = {} if execution_result.errors: - response["errors"] = [self.format_error(e) for e in execution_result.errors] + response["errors"] = [ + self.format_error(e) for e in execution_result.errors + ] if execution_result.invalid: status_code = 400 diff --git a/scripts/bump.py b/scripts/bump.py index 14c3423..7335dc4 100755 --- a/scripts/bump.py +++ b/scripts/bump.py @@ -28,7 +28,9 @@ def get_args(): nargs="*", help="Patch version bump. Empty flag will auto bump current version.", ) - parser.add_argument("--dry-run", type=str, default="yes", choices=["yes", "no"], help="Dry run") + parser.add_argument( + "--dry-run", type=str, default="yes", choices=["yes", "no"], help="Dry run" + ) return parser.parse_args() @@ -129,4 +131,6 @@ def bump_version(major, minor, patch): NV = f'version = "{NEW_VERSION}"' content = content.replace(CV, NV) file.write(content) - print(f"Successfully updated package version from {CURRENT_VERSION} to {NEW_VERSION}") + print( + f"Successfully updated package version from {CURRENT_VERSION} to {NEW_VERSION}" + ) diff --git a/tests/conftest.py b/tests/conftest.py index f6f6daa..5a95c13 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,7 +29,9 @@ def pytest_configure(config): settings.configure( ALLOWED_HOSTS=["*"], DEBUG_PROPAGATE_EXCEPTIONS=True, - DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}, + DATABASES={ + "default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"} + }, SITE_ID=1, SECRET_KEY="not very secret in tests", USE_I18N=True, diff --git a/tests/schema.py b/tests/schema.py index cc1de71..b75de89 100644 --- a/tests/schema.py +++ b/tests/schema.py @@ -40,14 +40,18 @@ class User1ListType(DjangoListObjectType): class Meta: description = " Type definition for user list " model = User - pagination = LimitOffsetGraphqlPagination(default_limit=25, ordering="-username") + pagination = LimitOffsetGraphqlPagination( + default_limit=25, ordering="-username" + ) class UserModelType(DjangoSerializerType): class Meta: description = " Serializer Type definition for user " serializer_class = UserSerializer - pagination = LimitOffsetGraphqlPagination(default_limit=25, ordering="-username") + pagination = LimitOffsetGraphqlPagination( + default_limit=25, ordering="-username" + ) filterset_class = UserFilterSet @@ -71,7 +75,9 @@ class Meta: class Query(graphene.ObjectType): # Possible User list queries definitions all_users = DjangoListObjectField(User1ListType, description=_("All Users query")) - all_users1 = DjangoFilterPaginateListField(UserType, pagination=LimitOffsetGraphqlPagination()) + all_users1 = DjangoFilterPaginateListField( + UserType, pagination=LimitOffsetGraphqlPagination() + ) all_users2 = DjangoFilterListField(UserType) all_users3 = DjangoListObjectField( User1ListType, filterset_class=UserFilterSet, description=_("All Users query") @@ -84,7 +90,9 @@ class Query(graphene.ObjectType): user = DjangoObjectField(UserType, description=_("Single User query")) # Another way to define a query to single user - user1 = User1ListType.RetrieveField(description=_("User List with pagination and filtering")) + user1 = User1ListType.RetrieveField( + description=_("User List with pagination and filtering") + ) # Exist two ways to define single or list user queries with DjangoSerializerType user2, users = UserModelType.QueryFields() diff --git a/tests/test_fields.py b/tests/test_fields.py index ca090c1..70a8a35 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -24,7 +24,9 @@ def test_should_return_expected_status_code(self): self.assertEqual(self.response.status_code, self.expected_status_code) def test_should_return_expected_payload(self): - self.assertEqual(self.response.json(), self.expected_return_payload, self.response.content) + self.assertEqual( + self.response.json(), self.expected_return_payload, self.response.content + ) class DjangoListObjectFieldTest(ParentTest, TestCase): @@ -32,7 +34,9 @@ class DjangoListObjectFieldTest(ParentTest, TestCase): expected_return_payload = {"data": {"allUsers": {"results": [{"id": "1"}]}}} def test_field(self): - self.assertEqual(self.data["data"]["allUsers"]["results"][0]["id"], str(self.user.id)) + self.assertEqual( + self.data["data"]["allUsers"]["results"][0]["id"], str(self.user.id) + ) class DjangoFilterPaginateListFieldTest(ParentTest, TestCase): @@ -58,7 +62,9 @@ class DjangoFilterListFieldTest(ParentTest, TestCase): class DjangoListObjectFieldWithFilterSetTest(ParentTest, TestCase): - expected_return_payload = {"data": {"allUsers3": {"results": [{"username": "graphql"}]}}} + expected_return_payload = { + "data": {"allUsers3": {"results": [{"username": "graphql"}]}} + } @property def query(self): @@ -78,7 +84,9 @@ def test_filter_charfield_icontains(self): self.assertIn("allUsers3", data["data"]) self.assertIn("results", data["data"]["allUsers3"]) self.assertTrue(data["data"]["allUsers3"]["results"]) - self.assertEqual(data["data"]["allUsers3"]["results"][0]["username"], self.user.username) + self.assertEqual( + data["data"]["allUsers3"]["results"][0]["username"], self.user.username + ) def test_filter_charfield_iexact(self): query = queries.ALL_USERS3_WITH_FILTER % { @@ -91,14 +99,18 @@ def test_filter_charfield_iexact(self): self.assertIn("allUsers3", data["data"]) self.assertIn("results", data["data"]["allUsers3"]) self.assertTrue(data["data"]["allUsers3"]["results"]) - self.assertEqual(data["data"]["allUsers3"]["results"][0]["username"], self.user.username) + self.assertEqual( + data["data"]["allUsers3"]["results"][0]["username"], self.user.username + ) class DjangoSerializerTypeTest(ParentTest, TestCase): expected_return_payload = { "data": { "users": { - "results": [{"id": "1", "username": "graphql", "email": "eamigop86@gmail.com"}], + "results": [ + {"id": "1", "username": "graphql", "email": "eamigop86@gmail.com"} + ], "totalCount": 1, } } @@ -129,7 +141,9 @@ class DjangoCustomResolverTest(ParentTest, TestCase): query = queries.ALL_USERS4 def setUp(self): - self.staff_user = factories.UserFactory(username=uuid.uuid4().hex, is_staff=True) + self.staff_user = factories.UserFactory( + username=uuid.uuid4().hex, is_staff=True + ) super().setUp() @property diff --git a/tests/urls.py b/tests/urls.py index 000e0d5..0f66a07 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -8,7 +8,9 @@ urlpatterns = [ path("admin/", admin.site.urls), - path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True)), name="graphql"), + path( + "graphql", csrf_exempt(GraphQLView.as_view(graphiql=True)), name="graphql" + ), ] else: from django.conf.urls import url From bf32a9f67b9d3791c9e516ac04adc9747ff114bb Mon Sep 17 00:00:00 2001 From: alainburindi Date: Thu, 12 Sep 2024 15:32:38 +0200 Subject: [PATCH 3/5] upgrade pip version --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index 514862c..3b68d5a 100644 --- a/tox.ini +++ b/tox.ini @@ -59,6 +59,7 @@ skip_install = true commands = poetry update --lock poetry install -vvv + poetry run python -m ensurepip --upgrade poetry run pip install 'django~=5.0' poetry run pytest tests/ --cov=graphene_django_extras @@ -69,6 +70,7 @@ skip_install = true commands = poetry update --lock poetry install -vvv + poetry run python -m ensurepip --upgrade poetry run pip install 'django~=5.1' poetry run pytest tests/ --cov=graphene_django_extras From d5af9c492dbcd4c5552e35e9c4dbf02692004684 Mon Sep 17 00:00:00 2001 From: alainburindi Date: Thu, 12 Sep 2024 15:35:58 +0200 Subject: [PATCH 4/5] remove USE_L10N deprecated attribute --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 5a95c13..24714b8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,7 +35,6 @@ def pytest_configure(config): SITE_ID=1, SECRET_KEY="not very secret in tests", USE_I18N=True, - USE_L10N=True, STATIC_URL="/static/", ROOT_URLCONF="tests.urls", TEMPLATES=[ From c4f77d7a54db742f35659e14dacc874762642e37 Mon Sep 17 00:00:00 2001 From: alainburindi Date: Tue, 22 Oct 2024 12:30:59 +0200 Subject: [PATCH 5/5] update CI jobs --- .github/workflows/cicd.yaml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index 06156f0..0752e54 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -10,9 +10,6 @@ jobs: strategy: matrix: include: - - python: 3.7 - django: 3.2 - toxenv: py37-django32 - python: 3.8 django: 3.2 toxenv: py38-django32 @@ -37,6 +34,24 @@ jobs: - python: '3.10' django: 4.1 toxenv: py310-django41 + - python: '3.10' + django: 5.0 + toxenv: py310-django50 + - python: '3.11' + django: 5.0 + toxenv: py311-django50 + - python: '3.12' + django: 5.0 + toxenv: py312-django50 + - python: '3.10' + django: 5.1 + toxenv: py310-django51 + - python: '3.11' + django: 5.1 + toxenv: py311-django51 + - python: '3.12' + django: 5.1 + toxenv: py312-django51 steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v1