From b56fe0a0025951d4ceeb1b11682ce917403c8152 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 6 Jul 2023 09:03:34 +0200
Subject: [PATCH 01/42] update pydantic dep
update minimum python version according to https://github.com/pydantic/pydantic/issues/6426
---
pyproject.toml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index db75cb7d..85d6418a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "autodoc_pydantic"
-version = "1.9.0"
+version = "1.10.0"
description = "Seamlessly integrate pydantic models in your Sphinx documentation."
authors = ["mansenfranzen "]
packages = [{ include = "sphinxcontrib" }]
@@ -18,9 +18,9 @@ classifiers = [
include = ["sphinxcontrib/autodoc_pydantic/css/autodoc_pydantic.css"]
[tool.poetry.dependencies]
-python = ">=3.7.1,<4.0.0"
+python = ">=3.7.2,<4.0.0"
Sphinx = ">=3.4"
-pydantic = ">=1.5,<2.0.0"
+pydantic = ">=2.0,<3.0.0"
sphinx-rtd-theme = { version = "^1.0", optional = true }
sphinx-tabs = { version = "^3", optional = true }
From ffd7fbb5d9ca5ef5b69c564c44ebe799abbd425b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 6 Jul 2023 09:06:19 +0200
Subject: [PATCH 02/42] poetry lock
---
poetry.lock | 1111 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1111 insertions(+)
create mode 100644 poetry.lock
diff --git a/poetry.lock b/poetry.lock
new file mode 100644
index 00000000..dfa1d716
--- /dev/null
+++ b/poetry.lock
@@ -0,0 +1,1111 @@
+# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
+
+[[package]]
+name = "alabaster"
+version = "0.7.13"
+description = "A configurable sidebar-enabled Sphinx theme"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
+ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
+]
+
+[[package]]
+name = "annotated-types"
+version = "0.5.0"
+description = "Reusable constraint types to use with typing.Annotated"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"},
+ {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""}
+
+[[package]]
+name = "babel"
+version = "2.12.1"
+description = "Internationalization utilities"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
+ {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+]
+
+[package.dependencies]
+pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
+
+[[package]]
+name = "certifi"
+version = "2023.5.7"
+description = "Python package for providing Mozilla's CA Bundle."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"},
+ {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"},
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.1.0"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
+ {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
+]
+
+[[package]]
+name = "click"
+version = "8.1.3"
+description = "Composable command line interface toolkit"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
+ {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+]
+
+[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."
+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.2.7"
+description = "Code coverage measurement for Python"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"},
+ {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"},
+ {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"},
+ {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"},
+ {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"},
+ {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"},
+ {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"},
+ {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"},
+ {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"},
+ {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"},
+ {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"},
+ {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"},
+ {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"},
+ {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"},
+ {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"},
+ {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"},
+ {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"},
+ {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"},
+ {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"},
+ {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"},
+ {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"},
+ {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"},
+ {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"},
+ {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"},
+ {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"},
+ {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"},
+ {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"},
+ {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"},
+ {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"},
+ {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"},
+ {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"},
+ {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"},
+ {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"},
+ {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"},
+ {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"},
+ {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"},
+ {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"},
+ {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"},
+ {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"},
+ {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"},
+ {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"},
+ {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"},
+ {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"},
+ {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"},
+ {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"},
+ {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"},
+ {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"},
+ {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"},
+ {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"},
+ {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"},
+ {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"},
+ {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"},
+ {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"},
+ {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"},
+ {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"},
+ {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"},
+ {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"},
+ {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"},
+ {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"},
+ {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"},
+]
+
+[package.extras]
+toml = ["tomli"]
+
+[[package]]
+name = "distlib"
+version = "0.3.6"
+description = "Distribution utilities"
+optional = true
+python-versions = "*"
+files = [
+ {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
+ {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
+]
+
+[[package]]
+name = "docutils"
+version = "0.18.1"
+description = "Docutils -- Python Documentation Utilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
+ {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
+]
+
+[[package]]
+name = "erdantic"
+version = "0.5.0"
+description = "Entity relationship diagrams for Python data model classes like Pydantic."
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "erdantic-0.5.0-py3-none-any.whl", hash = "sha256:43fbe1787d272958991d3b16ffa217b595957e66b394f79be76b4b6dd72dc773"},
+ {file = "erdantic-0.5.0.tar.gz", hash = "sha256:475389523b37b1ac06a96837d782a41b889fb27d099a1576183f1721a6a38e23"},
+]
+
+[package.dependencies]
+importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
+pydantic = "*"
+pygraphviz = "*"
+typer = "*"
+typing-extensions = "*"
+
+[[package]]
+name = "exceptiongroup"
+version = "1.1.2"
+description = "Backport of PEP 654 (exception groups)"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"},
+ {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
+
+[[package]]
+name = "filelock"
+version = "3.12.2"
+description = "A platform independent file lock."
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"},
+ {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
+
+[[package]]
+name = "flake8"
+version = "3.9.2"
+description = "the modular source code checker: pep8 pyflakes and co"
+optional = true
+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 = "idna"
+version = "3.4"
+description = "Internationalized Domain Names in Applications (IDNA)"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+]
+
+[[package]]
+name = "imagesize"
+version = "1.4.1"
+description = "Getting image size from png/jpeg/jpeg2000/gif file"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
+ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
+]
+
+[[package]]
+name = "importlib-metadata"
+version = "6.7.0"
+description = "Read metadata from Python packages"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"},
+ {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
+zipp = ">=0.5"
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+perf = ["ipython"]
+testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"]
+
+[[package]]
+name = "iniconfig"
+version = "2.0.0"
+description = "brain-dead simple config-ini parsing"
+optional = true
+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 = "jinja2"
+version = "3.1.2"
+description = "A very fast and expressive template engine."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
+ {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.3"
+description = "Safely add untrusted strings to HTML/XML markup."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
+ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
+]
+
+[[package]]
+name = "mccabe"
+version = "0.6.1"
+description = "McCabe checker, plugin for flake8"
+optional = true
+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 = "packaging"
+version = "23.1"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
+ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
+]
+
+[[package]]
+name = "platformdirs"
+version = "3.8.0"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"},
+ {file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=4.6.3", markers = "python_version < \"3.8\""}
+
+[package.extras]
+docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
+
+[[package]]
+name = "pluggy"
+version = "1.2.0"
+description = "plugin and hook calling mechanisms for python"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"},
+ {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"},
+]
+
+[package.dependencies]
+importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
+
+[package.extras]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
+
+[[package]]
+name = "py"
+version = "1.11.0"
+description = "library with cross-python path, ini-parsing, io, code, log facilities"
+optional = true
+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"
+optional = true
+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 = "pydantic"
+version = "2.0.2"
+description = "Data validation using Python type hints"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pydantic-2.0.2-py3-none-any.whl", hash = "sha256:f5581e0c79b2ec2fa25a9d30d766629811cdda022107fa73d022ab5578873ae3"},
+ {file = "pydantic-2.0.2.tar.gz", hash = "sha256:b802f5245b8576315fe619e5989fd083448fa1258638ef9dac301ca60878396d"},
+]
+
+[package.dependencies]
+annotated-types = ">=0.4.0"
+pydantic-core = "2.1.2"
+typing-extensions = ">=4.6.1"
+
+[package.extras]
+email = ["email-validator (>=2.0.0)"]
+
+[[package]]
+name = "pydantic-core"
+version = "2.1.2"
+description = ""
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pydantic_core-2.1.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:b4815720c266e832b20e27a7a5f3772bb09fdedb31a9a34bab7b49d98967ef5a"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8884a1dbfc5cb8c54b48446ca916d4577c1f4d901126091e4ab25d00194e065f"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74a33aa69d476773230396396afb8e11908f8dafdcfd422e746770599a3f889d"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af832edd384755826e494ffdcf1fdda86e4babc42a0b18d342943fb18181040e"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_armv7l.whl", hash = "sha256:017700236ea2e7afbef5d3803559c80bd8720306778ebd49268de7ce9972e83e"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:c2d00a96fdf26295c6f25eaf9e4a233f353146a73713cd97a5f5dc6090c3aef2"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_s390x.whl", hash = "sha256:2575664f0a559a7b951a518f6f34c23cab7190f34f8220b8c8218c4f403147ee"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24c3c9180a2d19d640bacc2d00f497a9a1f2abadb2a9ee201b56bb03bc5343bd"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:88a56f0f6d020b4d17641f4b4d1f9540a536d4146768d059c430e97bdb485fc1"},
+ {file = "pydantic_core-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fa38a76e832743866aed6b715869757074b06357d1a260163ec26d84974245fe"},
+ {file = "pydantic_core-2.1.2-cp310-none-win32.whl", hash = "sha256:a772c652603855d7180015849d483a1f539351a263bb9b81bfe85193a33ce124"},
+ {file = "pydantic_core-2.1.2-cp310-none-win_amd64.whl", hash = "sha256:b4673d1f29487608d613ebcc5caa99ba15eb58450a7449fb6d800f29d90bebc1"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:76c9c55462740d728b344e3a087775846516c3fee31ec56e2075faa7cfcafcbf"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb854ec52e6e2e05b83d647695f4d913452fdd45a3dfa8233d7dab5967b3908f"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ac140d54da366672f6b91f9a1e8e2d4e7e72720143353501ae886d3fca03272"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:818f5cb1b209ab1295087c45717178f4bbbd2bd7eda421f7a119e7b9b736a3cb"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_armv7l.whl", hash = "sha256:db4564aea8b3cb6cf1e5f3fd80f1ced73a255d492396d1bd8abd688795b34d63"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:2ca2d2d5ab65fb40dd05259965006edcc62a9d9b30102737c0a6f45bcbd254e8"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_s390x.whl", hash = "sha256:7c7ad8958aadfbcd664078002246796ecd5566b64b22f6af4fd1bbcec6bf8f60"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:080a7af828388284a68ad7d3d3eac3bcfff6a580292849aff087e7d556ec42d4"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bad7029fb2251c1ac7d3acdd607e540d40d137a7d43a5e5acdcfdbd38db3fc0a"},
+ {file = "pydantic_core-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1635a37137fafbc6ee0a8c879857e05b30b1aabaa927e653872b71f1501b1502"},
+ {file = "pydantic_core-2.1.2-cp311-none-win32.whl", hash = "sha256:eb4301f009a44bb5db5edfe4e51a8175a4112b566baec07f4af8b1f8cb4649a2"},
+ {file = "pydantic_core-2.1.2-cp311-none-win_amd64.whl", hash = "sha256:ebf583f4d9b52abd15cc59e5f6eeca7e3e9741c6ea62d8711c00ac3acb067875"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:90b06bb47e60173d24c7cb79670aa8dd6081797290353b9d3c66d3a23e88eb34"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e5761ce986ec709897b1b965fad9743f301500434bea3cbab2b6e662571580f"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b9f8bf1d7008a58fbb6eb334dc6e2f2905400cced8dadb46c4ca28f005a8562"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a014ee88980013d192a718cbb88e8cea20acd3afad69bc6d15672d05a49cdb6"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_armv7l.whl", hash = "sha256:8125152b03dd91deca5afe5b933a1994b39405adf6be2fe8dce3632319283f85"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_ppc64le.whl", hash = "sha256:dc737506b4a0ba2922a2626fc6d620ce50a46aebd0fe2fbcad1b93bbdd8c7e78"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_s390x.whl", hash = "sha256:bb471ea8650796060afc99909d9b75da583d317e52f660faf64c45f70b3bf1e2"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1fad38db1744d27061df516e59c5025b09b0a50a337c04e6eebdbddc18951bc"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:94d368af9e6563de6e7170a74710a2cbace7a1e9c8e507d9e3ac34c7065d7ae3"},
+ {file = "pydantic_core-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bd95d223de5162811a7b36c73d48eac4fee03b075132f3a1b73c132ce157a60c"},
+ {file = "pydantic_core-2.1.2-cp312-none-win32.whl", hash = "sha256:cd62f73830d4715bc643ae39de0bd4fb9c81d6d743530074da91e77a2cccfe67"},
+ {file = "pydantic_core-2.1.2-cp312-none-win_amd64.whl", hash = "sha256:51968887d6bd1eaa7fc7759701ea8ccb470c04654beaa8ede6835b0533f206a9"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:7ff6bfe63f447a509ed4d368a7f4ba6a7abc03bc4744fc3fb30f2ffab73f3821"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:4e67f9b9dfda2e42b39459cbf99d319ccb90da151e35cead3521975b2afbf673"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b815a769b019dd96be6571096f246b74f63330547e9b30244c51b4a2eb0277fc"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aff436c23c68449601b3fba7075b4f37ef8fbb893c8c1ed3ef898f090332b1e"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_armv7l.whl", hash = "sha256:2ee3ae58f271851362f6c9b33e4c9f9e866557ec7d8c03dc091e9b5aa5566cec"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:cf92dccca8f66e987f6c4378700447f82b79e86407912ab1ee06b16b82f05120"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_s390x.whl", hash = "sha256:4663293a36a851a860b1299c50837914269fca127434911297dd39fea9667a01"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c917f7a41d9d09b8b024a5d65cf37e5588ccdb6e610d2df565fb7186b1f3b1c"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:06ae67547251135a1b3f8dd465797b13146295a3866bc12ddd73f7512787bb7c"},
+ {file = "pydantic_core-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4938b32c09dbcecbeb652327cb4a449b1ef1a1bf6c8fc2c8241aa6b8f6d63b54"},
+ {file = "pydantic_core-2.1.2-cp37-none-win32.whl", hash = "sha256:682ff9228c838018c47dfa89b3d84cca45f88cacde28807ab8296ec221862af4"},
+ {file = "pydantic_core-2.1.2-cp37-none-win_amd64.whl", hash = "sha256:6e3bcb4a9bc209a61ea2aceb7433ce2ece32c7e670b0c06848bf870c9b3e7d87"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:2278ca0b0dfbcfb1e12fa58570916dc260dc72bee5e6e342debf5329d8204688"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87cff210af3258ca0c829e3ebc849d7981bfde23a99d6cb7a3c17a163b3dbad2"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7684b5fb906b37e940c5df3f57118f32e033af5e4770e5ae2ae56fbd2fe1a30a"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3747a4178139ebf3f19541285b2eb7c886890ca4eb7eec851578c02a13cc1385"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_armv7l.whl", hash = "sha256:e17056390068afd4583d88dcf4d4495764e4e2c7d756464468e0d21abcb8931e"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:c720e55cef609d50418bdfdfb5c44a76efc020ae7455505788d0113c54c7df55"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_s390x.whl", hash = "sha256:b59a64c367f350873c40a126ffe9184d903d2126c701380b4b55753484df5948"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68a2a767953c707d9575dcf14d8edee7930527ee0141a8bb612c22d1f1059f9a"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae46769d9a7138d58cd190441cac14ce954010a0081f28462ed916c8e55a4f"},
+ {file = "pydantic_core-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fc909f62325a631e1401dd07dfc386986dbcac15f98c9ff2145d930678a9d25a"},
+ {file = "pydantic_core-2.1.2-cp38-none-win32.whl", hash = "sha256:b4038869ba1d8fa33863b4b1286ab07e6075a641ae269b865f94d7e10b3e800e"},
+ {file = "pydantic_core-2.1.2-cp38-none-win_amd64.whl", hash = "sha256:5948af62f323252d56acaec8ebfca5f15933f6b72f8dbe3bf21ee97b2d10e3f0"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:8e6ce261ccb9a986953c4dce070327e4954f9dd4cd214746dfc70efbc713b6a1"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d35d634d9d1ed280c87bc2a7a6217b8787eedc86f368fc2fa1c0c8c78f7d3c93"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be2e2812a43205728a06c9d0fd090432cd76a9bb5bff2bfcfdf8b0e27d51851"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0eb54b11cd4fe0c6404611eef77086ade03eb1457e92910bbb4f3479efa3f79"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_armv7l.whl", hash = "sha256:087ddbb754575618a8832ee4ab52fe7eb332f502e2a56088b53dbeb5c4efdf9f"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:b74906e01c7fc938ac889588ef438de812989817095c3c4904721f647d64a4d1"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_s390x.whl", hash = "sha256:60b7239206a2f61ad89c7518adfacb3ccd6662eaa07c5e437317aea2615a1f18"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:be3419204952bbe9b72b90008977379c52f99ae1c6e640488de4be783c345d71"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:804cf8f6a859620f8eb754c02f7770f61c3e9c519f8338c331d555b3d6976e3c"},
+ {file = "pydantic_core-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cbba32fb14e199d0493c6b9c44870dab0a9c37af9f0f729068459d1849279ffd"},
+ {file = "pydantic_core-2.1.2-cp39-none-win32.whl", hash = "sha256:6bf00f56a4468f5b03dadb672a5f1d24aea303d4ccffe8a0f548c9e36017edd3"},
+ {file = "pydantic_core-2.1.2-cp39-none-win_amd64.whl", hash = "sha256:ac462a28218ea7d592c7ad51b517558f4ac6565a4e53db7a4811eeaf9c9660b0"},
+ {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:047e782b9918f35ef534ced36f1fd2064f5581229b7a15e4d3177387a6b53134"},
+ {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c0213891898fa5b404cf3edf4797e3ac7819a0708ea5473fc6432a2aa27c189"},
+ {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0f481aaf0119f77b200e5a5e2799b3e14c015a317eaa948f42263908735cc9f"},
+ {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15eb4cb543ed36f6a4f16e3bee7aa7ed1c3757be95a3f3bbb2b82b9887131e0f"},
+ {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ef71e73a81a4cd7e87c93e8ff0170140fd93ba33b0f61e83da3f55f6e0a84fb4"},
+ {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:840238c845b0f80777151fef0003088ab91c6f7b3467edaff4932b425c4e3c3f"},
+ {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7648e48ba263ca0a8a2dc55a60a219c9133fb101ba52c89a14a29fb3d4322ca3"},
+ {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:8eb4e2b71562375609c66a79f89acd4fe95c5cba23473d04952c8b14b6f908f5"},
+ {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056afea59651c4e47ec6dadbb77ccae4742c059a3d12bc1c0e393d189d2970d"},
+ {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46cd323371aa7e4053010ccdb94063a4273aa9e5dbe97f8a1147faa769de8d8d"},
+ {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa39499625239da4ec960cf4fc66b023929b24cc77fb8520289cfdb3c1986428"},
+ {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f5de2d4167fd4bc5ad205fb7297e25867b8e335ca08d64ed7a561d2955a2c32d"},
+ {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:9a5fba9168fc27805553760fa8198db46eef83bf52b4e87ebbe1333b823d0e70"},
+ {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e68a404fad8493989d6f07b7b9e066f1d2524d7cb64db2d4e9a84c920032c67f"},
+ {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:1a5c4475510d1a9cc1458a26cfc21442223e52ce9adb640775c38739315d03c7"},
+ {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0681472245ef182554208a25d16884c84f1c5a69f14e6169b88932e5da739a1c"},
+ {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7fd334b40c5e13a97becfcaba314de0dcc6f7fe21ec8f992139bcc64700e9dc"},
+ {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7345b1741bf66a9d8ed0ec291c3eabd534444e139e1ea6db5742ac9fd3be2530"},
+ {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0855cf8b760fb40f97f0226cb527c8a94a2ab9d8179628beae20d6939aaeacb0"},
+ {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d281a10837d98db997c0247f45d138522c91ce30cf3ae7a6afdb5e709707d360"},
+ {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:82e09f27edab289187dd924d4d93f2a35f21aa969699b2504aa643da7fbfeff9"},
+ {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:aa54902fa51f7d921ba80923cf1c7ff3dce796a7903300bd8824deb90e357744"},
+ {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b9a5fc4058d64c9c826684dcdb43891c1b474a4a88dcf8dfc3e1fb5889496f8"},
+ {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:817681d111cb65f07d46496eafec815f48e1aff37713b73135a0a9eb4d3610ab"},
+ {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b5d37aedea5963f2097bddbcdb255483191646a52d40d8bb66d61c190fcac91"},
+ {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f2de65752fff248319bcd3b29da24e205fa505607539fcd4acc4037355175b63"},
+ {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a8b9c2cc4c5f8169b943d24be4bd1548fe81c016d704126e3a3124a2fc164885"},
+ {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f7bcdf70c8b6e70be11c78d3c00b80a24cccfb408128f23e91ec3019bed1ecc1"},
+ {file = "pydantic_core-2.1.2.tar.gz", hash = "sha256:d2c790f0d928b672484eac4f5696dd0b78f3d6d148a641ea196eb49c0875e30a"},
+]
+
+[package.dependencies]
+typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
+
+[[package]]
+name = "pyflakes"
+version = "2.3.1"
+description = "passive checker of Python programs"
+optional = true
+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.15.1"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
+ {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
+]
+
+[package.extras]
+plugins = ["importlib-metadata"]
+
+[[package]]
+name = "pygraphviz"
+version = "1.7"
+description = "Python interface to Graphviz"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "pygraphviz-1.7.zip", hash = "sha256:a7bec6609f37cf1e64898c59f075afd659106cf9356c5f387cecaa2e0cdb2304"},
+]
+
+[[package]]
+name = "pytest"
+version = "7.4.0"
+description = "pytest: simple powerful testing with Python"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"},
+ {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
+importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
+iniconfig = "*"
+packaging = "*"
+pluggy = ">=0.12,<2.0"
+tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
+
+[package.extras]
+testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+
+[[package]]
+name = "pytz"
+version = "2023.3"
+description = "World timezone definitions, modern and historical"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
+ {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
+]
+
+[[package]]
+name = "requests"
+version = "2.31.0"
+description = "Python HTTP for Humans."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
+ {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+]
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<3"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+optional = true
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[[package]]
+name = "snowballstemmer"
+version = "2.2.0"
+description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
+optional = false
+python-versions = "*"
+files = [
+ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
+]
+
+[[package]]
+name = "sphinx"
+version = "5.3.0"
+description = "Python documentation generator"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"},
+ {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"},
+]
+
+[package.dependencies]
+alabaster = ">=0.7,<0.8"
+babel = ">=2.9"
+colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
+docutils = ">=0.14,<0.20"
+imagesize = ">=1.3"
+importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""}
+Jinja2 = ">=3.0"
+packaging = ">=21.0"
+Pygments = ">=2.12"
+requests = ">=2.5.0"
+snowballstemmer = ">=2.0"
+sphinxcontrib-applehelp = "*"
+sphinxcontrib-devhelp = "*"
+sphinxcontrib-htmlhelp = ">=2.0.0"
+sphinxcontrib-jsmath = "*"
+sphinxcontrib-qthelp = "*"
+sphinxcontrib-serializinghtml = ">=1.1.5"
+
+[package.extras]
+docs = ["sphinxcontrib-websupport"]
+lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"]
+test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
+
+[[package]]
+name = "sphinx-copybutton"
+version = "0.4.0"
+description = "Add a copy button to each of your code cells."
+optional = true
+python-versions = ">=3.6"
+files = [
+ {file = "sphinx-copybutton-0.4.0.tar.gz", hash = "sha256:8daed13a87afd5013c3a9af3575cc4d5bec052075ccd3db243f895c07a689386"},
+ {file = "sphinx_copybutton-0.4.0-py3-none-any.whl", hash = "sha256:4340d33c169dac6dd82dce2c83333412aa786a42dd01a81a8decac3b130dc8b0"},
+]
+
+[package.dependencies]
+sphinx = ">=1.8"
+
+[package.extras]
+code-style = ["pre-commit (==2.12.1)"]
+rtd = ["ipython", "sphinx", "sphinx-book-theme"]
+
+[[package]]
+name = "sphinx-rtd-theme"
+version = "1.2.2"
+description = "Read the Docs theme for Sphinx"
+optional = true
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
+files = [
+ {file = "sphinx_rtd_theme-1.2.2-py2.py3-none-any.whl", hash = "sha256:6a7e7d8af34eb8fc57d52a09c6b6b9c46ff44aea5951bc831eeb9245378f3689"},
+ {file = "sphinx_rtd_theme-1.2.2.tar.gz", hash = "sha256:01c5c5a72e2d025bd23d1f06c59a4831b06e6ce6c01fdd5ebfe9986c0a880fc7"},
+]
+
+[package.dependencies]
+docutils = "<0.19"
+sphinx = ">=1.6,<7"
+sphinxcontrib-jquery = ">=4,<5"
+
+[package.extras]
+dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"]
+
+[[package]]
+name = "sphinx-tabs"
+version = "3.4.1"
+description = "Tabbed views for Sphinx"
+optional = true
+python-versions = "~=3.7"
+files = [
+ {file = "sphinx-tabs-3.4.1.tar.gz", hash = "sha256:d2a09f9e8316e400d57503f6df1c78005fdde220e5af589cc79d493159e1b832"},
+ {file = "sphinx_tabs-3.4.1-py3-none-any.whl", hash = "sha256:7cea8942aeccc5d01a995789c01804b787334b55927f29b36ba16ed1e7cb27c6"},
+]
+
+[package.dependencies]
+docutils = ">=0.18.0,<0.19.0"
+pygments = "*"
+sphinx = "*"
+
+[package.extras]
+code-style = ["pre-commit (==2.13.0)"]
+testing = ["bs4", "coverage", "pygments", "pytest (>=7.1,<8)", "pytest-cov", "pytest-regressions", "rinohtype", "sphinx-testing"]
+
+[[package]]
+name = "sphinxcontrib-applehelp"
+version = "1.0.2"
+description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"},
+ {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-devhelp"
+version = "1.0.2"
+description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
+ {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-htmlhelp"
+version = "2.0.0"
+description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"},
+ {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["html5lib", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-jquery"
+version = "4.1"
+description = "Extension to include jQuery on newer Sphinx releases"
+optional = true
+python-versions = ">=2.7"
+files = [
+ {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
+ {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
+]
+
+[package.dependencies]
+Sphinx = ">=1.8"
+
+[[package]]
+name = "sphinxcontrib-jsmath"
+version = "1.0.1"
+description = "A sphinx extension which renders display math in HTML via JavaScript"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
+ {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
+]
+
+[package.extras]
+test = ["flake8", "mypy", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-mermaid"
+version = "0.7.1"
+description = "Mermaid diagrams in yours Sphinx powered docs"
+optional = true
+python-versions = "*"
+files = [
+ {file = "sphinxcontrib-mermaid-0.7.1.tar.gz", hash = "sha256:aa8a40b50ec86ad12824b62180240ca52a9bda8424455d7eb252eae9aa5d293c"},
+ {file = "sphinxcontrib_mermaid-0.7.1-py2.py3-none-any.whl", hash = "sha256:3e20de1937c30dfa807e446bf99983d73d0dd3dc5c6524addda59800fe928762"},
+]
+
+[[package]]
+name = "sphinxcontrib-qthelp"
+version = "1.0.3"
+description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
+ {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-serializinghtml"
+version = "1.1.5"
+description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
+ {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
+optional = true
+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"
+optional = true
+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"
+six = ">=1.14.0"
+tomli = {version = ">=2.0.1", markers = "python_version >= \"3.7\" and python_version < \"3.11\""}
+virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7"
+
+[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)", "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 = "typer"
+version = "0.9.0"
+description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
+optional = true
+python-versions = ">=3.6"
+files = [
+ {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"},
+ {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"},
+]
+
+[package.dependencies]
+click = ">=7.1.1,<9.0.0"
+typing-extensions = ">=3.7.4.3"
+
+[package.extras]
+all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
+dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
+doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"]
+test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
+
+[[package]]
+name = "typing-extensions"
+version = "4.7.1"
+description = "Backported and Experimental Type Hints for Python 3.7+"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
+ {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
+]
+
+[[package]]
+name = "urllib3"
+version = "2.0.3"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"},
+ {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"},
+]
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
+socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
+zstd = ["zstandard (>=0.18.0)"]
+
+[[package]]
+name = "virtualenv"
+version = "20.23.1"
+description = "Virtual Python Environment builder"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"},
+ {file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"},
+]
+
+[package.dependencies]
+distlib = ">=0.3.6,<1"
+filelock = ">=3.12,<4"
+importlib-metadata = {version = ">=6.6", markers = "python_version < \"3.8\""}
+platformdirs = ">=3.5.1,<4"
+
+[package.extras]
+docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "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.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"]
+
+[[package]]
+name = "zipp"
+version = "3.15.0"
+description = "Backport of pathlib-compatible object wrapper for zip files"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"},
+ {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
+
+[extras]
+dev = ["coverage", "flake8", "pytest", "sphinx-copybutton", "sphinx-rtd-theme", "sphinx-tabs", "sphinxcontrib-mermaid", "tox"]
+docs = ["sphinx-copybutton", "sphinx-rtd-theme", "sphinx-tabs", "sphinxcontrib-mermaid"]
+erdantic = ["erdantic"]
+test = ["coverage", "pytest"]
+
+[metadata]
+lock-version = "2.0"
+python-versions = ">=3.7.2,<4.0.0"
+content-hash = "0c801daeb2d8773d84db0113edd17b3032b80eeb8fc51fe3dbf814884b10c97d"
From 6785aa617af6e7cfcfcea0c00a45353dcd755b02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 6 Jul 2023 09:11:12 +0200
Subject: [PATCH 03/42] up sphinx default to 4
sphinx 4 was released in 2021
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index 85d6418a..97b6aa98 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -19,7 +19,7 @@ include = ["sphinxcontrib/autodoc_pydantic/css/autodoc_pydantic.css"]
[tool.poetry.dependencies]
python = ">=3.7.2,<4.0.0"
-Sphinx = ">=3.4"
+Sphinx = ">=4.0"
pydantic = ">=2.0,<3.0.0"
sphinx-rtd-theme = { version = "^1.0", optional = true }
From 40111d78905eda29c57b5e372ceda1550c354a36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 6 Jul 2023 09:11:36 +0200
Subject: [PATCH 04/42] poetry lock
---
poetry.lock | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/poetry.lock b/poetry.lock
index dfa1d716..9b5e2040 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1108,4 +1108,4 @@ test = ["coverage", "pytest"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.7.2,<4.0.0"
-content-hash = "0c801daeb2d8773d84db0113edd17b3032b80eeb8fc51fe3dbf814884b10c97d"
+content-hash = "1c8749d49968701ecdf548046584d95c5c666e353e3c86539c161e42fedb367f"
From ecf9486a2300fe3e59f8be328c378e2c128bff1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 6 Jul 2023 09:41:50 +0200
Subject: [PATCH 05/42] pyproject: add pydantic-settings
---
pyproject.toml | 1 +
1 file changed, 1 insertion(+)
diff --git a/pyproject.toml b/pyproject.toml
index 97b6aa98..a6c1b615 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,6 +21,7 @@ include = ["sphinxcontrib/autodoc_pydantic/css/autodoc_pydantic.css"]
python = ">=3.7.2,<4.0.0"
Sphinx = ">=4.0"
pydantic = ">=2.0,<3.0.0"
+pydantic-settings = ">=2.0,<3.0.0"
sphinx-rtd-theme = { version = "^1.0", optional = true }
sphinx-tabs = { version = "^3", optional = true }
From 84d34935af13356d31c4d5a11bfddf7c9779605e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 6 Jul 2023 09:41:56 +0200
Subject: [PATCH 06/42] ock
---
poetry.lock | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/poetry.lock b/poetry.lock
index 9b5e2040..34b83f71 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -659,6 +659,21 @@ files = [
[package.dependencies]
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
+[[package]]
+name = "pydantic-settings"
+version = "2.0.1"
+description = "Settings management using Pydantic"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pydantic_settings-2.0.1-py3-none-any.whl", hash = "sha256:579bbcbec3501e62bab73867b097ae10218201950e897463c98a182ffe7ed104"},
+ {file = "pydantic_settings-2.0.1.tar.gz", hash = "sha256:f440ec7cfb6dc63f03226c47b0e7803750d1b66a49ed944ac23eb4f0c84f8722"},
+]
+
+[package.dependencies]
+pydantic = ">=2.0.1"
+python-dotenv = ">=0.21.0"
+
[[package]]
name = "pyflakes"
version = "2.3.1"
@@ -717,6 +732,20 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras]
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+[[package]]
+name = "python-dotenv"
+version = "0.21.1"
+description = "Read key-value pairs from a .env file and set them as environment variables"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"},
+ {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"},
+]
+
+[package.extras]
+cli = ["click (>=5.0)"]
+
[[package]]
name = "pytz"
version = "2023.3"
@@ -1108,4 +1137,4 @@ test = ["coverage", "pytest"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.7.2,<4.0.0"
-content-hash = "1c8749d49968701ecdf548046584d95c5c666e353e3c86539c161e42fedb367f"
+content-hash = "4848e0572b46e35592999b9d96fb0169fe6a9c49bcc0140225a7bc3d135bbefa"
From cb9c3d8ea9f823d2e009b22d59976e51b85bd03d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 6 Jul 2023 10:34:51 +0200
Subject: [PATCH 07/42] pydantic v2 early compat
---
sphinxcontrib/autodoc_pydantic/events.py | 5 ---
sphinxcontrib/autodoc_pydantic/inspection.py | 37 ++++++++-----------
tests/roots/test-base/target/configuration.py | 3 +-
.../roots/test-base/target/example_setting.py | 3 +-
.../test-base/target/usage_automodule.py | 3 +-
.../test-base/target/usage_autosummary.py | 3 +-
tests/roots/test-base/target/usage_setting.py | 3 +-
.../target/example_setting.py | 3 +-
.../target/external.py | 2 +-
.../add_css_fallback.py | 3 +-
tox.ini | 18 ++-------
11 files changed, 34 insertions(+), 49 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/events.py b/sphinxcontrib/autodoc_pydantic/events.py
index c1908467..f616104c 100644
--- a/sphinxcontrib/autodoc_pydantic/events.py
+++ b/sphinxcontrib/autodoc_pydantic/events.py
@@ -1,4 +1,3 @@
-import sphinx
from sphinx.addnodes import desc_content
from sphinx.application import Sphinx
@@ -23,10 +22,6 @@ def add_fallback_css_class(app: Sphinx,
classes = contentnode.parent.attributes["classes"]
- # for older sphinx versions, add objtype explicitly
- if sphinx.version_info < (3, 6):
- classes.append(objtype)
-
if not app.env.config["autodoc_pydantic_add_fallback_css_class"]:
return
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index 7d355bde..cf4cf56e 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -14,8 +14,9 @@
import pydantic
from pydantic import BaseModel, create_model
from pydantic.class_validators import Validator
-from pydantic.fields import ModelField
+from pydantic.fields import FieldInfo
from pydantic.schema import get_field_schema_validations
+from pydantic_settings import SettingsConfigDict
from sphinx.addnodes import desc_signature
ASTERISK_FIELD_NAME = "all fields"
@@ -123,7 +124,7 @@ class FieldInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
- self.attribute = self.model.__fields__
+ self.attribute = self.model.model_fields
@property
def names(self) -> List[str]:
@@ -133,8 +134,8 @@ def names(self) -> List[str]:
return list(self.attribute.keys())
- def get(self, name: str) -> ModelField:
- """Get the instance of `ModelField` for given field `name`.
+ def get(self, name: str) -> FieldInfo:
+ """Get the instance of `FieldInfo` for given field `name`.
"""
@@ -163,7 +164,7 @@ def get_property_from_field_info(self,
"""
field = self.get(field_name)
- return getattr(field.field_info, property_name, None)
+ return getattr(field, property_name, None)
def get_constraints(self, field_name: str) -> Dict[str, Any]:
"""Get constraints for given `field_name`.
@@ -189,7 +190,7 @@ def is_required(self, field_name: str) -> bool:
"""
- return self.get(field_name).required
+ return self.get(field_name).is_required()
def has_default_factory(self, field_name: str) -> bool:
"""Check if field has a `default_factory` being set. This information
@@ -210,26 +211,18 @@ def is_json_serializable(self, field_name: str) -> bool:
return self._is_json_serializable(field)
@classmethod
- def _is_json_serializable(cls, field: ModelField):
- """Ensure JSON serializability for given pydantic `ModelField`.
+ def _is_json_serializable(cls, field: FieldInfo):
+ """Ensure JSON serializability for given pydantic `FieldInfo`.
"""
-
- # check for sub fields in case of `Union` or alike, see #98
- if field.sub_fields:
- return all(
- cls._is_json_serializable(sub_field)
- for sub_field in field.sub_fields
- )
-
# hide user warnings in sphinx output
with warnings.catch_warnings():
warnings.simplefilter("ignore")
return cls._test_field_serializabiltiy(field)
@staticmethod
- def _test_field_serializabiltiy(field: ModelField) -> bool:
- """Test JSON serializability for given pydantic `ModelField`.
+ def _test_field_serializabiltiy(field: FieldInfo) -> bool:
+ """Test JSON serializability for given pydantic `FieldInfo`.
"""
@@ -237,9 +230,9 @@ class Cfg:
arbitrary_types_allowed = True
try:
- field_args = (field.type_, field.default)
+ field_args = (field.annotation, field.default)
model = create_model("_", test_field=field_args, Config=Cfg)
- model.schema()
+ model.model_json_schema()
return True
except Exception:
@@ -345,7 +338,7 @@ def is_configured(self) -> bool:
cfg = self.attribute
is_main_config = cfg is pydantic.main.BaseConfig
- is_setting_config = cfg is pydantic.env_settings.BaseSettings.Config
+ is_setting_config = cfg is SettingsConfigDict
is_default_config = is_main_config or is_setting_config
return not is_default_config
@@ -452,7 +445,7 @@ def sanitized(self) -> Dict:
except (TypeError, ValueError):
new_model = self.create_sanitized_model()
- return new_model.schema()
+ return new_model.model_json_schema()
def create_sanitized_model(self) -> BaseModel:
"""Generates a new pydantic model from the original one while
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index c142dd16..f9b35add 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -1,6 +1,7 @@
from typing import Optional
-from pydantic import BaseModel, validator, Field, BaseSettings, root_validator
+from pydantic import BaseModel, validator, Field, root_validator
+from pydantic_settings import BaseSettings
class ModelShowJson(BaseModel):
diff --git a/tests/roots/test-base/target/example_setting.py b/tests/roots/test-base/target/example_setting.py
index ac69a1a4..b870ed98 100644
--- a/tests/roots/test-base/target/example_setting.py
+++ b/tests/roots/test-base/target/example_setting.py
@@ -1,4 +1,5 @@
-from pydantic import BaseSettings, validator, Field
+from pydantic import validator, Field
+from pydantic_settings import BaseSettings
class ExampleSettings(BaseSettings):
diff --git a/tests/roots/test-base/target/usage_automodule.py b/tests/roots/test-base/target/usage_automodule.py
index cf818e75..752bd548 100644
--- a/tests/roots/test-base/target/usage_automodule.py
+++ b/tests/roots/test-base/target/usage_automodule.py
@@ -1,4 +1,5 @@
-from pydantic import BaseSettings, validator, Field
+from pydantic import validator, Field
+from pydantic_settings import BaseSettings
class AutoModuleSettings(BaseSettings):
diff --git a/tests/roots/test-base/target/usage_autosummary.py b/tests/roots/test-base/target/usage_autosummary.py
index 3c4dabbe..0a18feae 100644
--- a/tests/roots/test-base/target/usage_autosummary.py
+++ b/tests/roots/test-base/target/usage_autosummary.py
@@ -1,4 +1,5 @@
-from pydantic import BaseModel, Field, validator, BaseSettings
+from pydantic import BaseModel, Field, validator
+from pydantic_settings import BaseSettings
class AutoSummaryModel(BaseModel):
diff --git a/tests/roots/test-base/target/usage_setting.py b/tests/roots/test-base/target/usage_setting.py
index ac69a1a4..b870ed98 100644
--- a/tests/roots/test-base/target/usage_setting.py
+++ b/tests/roots/test-base/target/usage_setting.py
@@ -1,4 +1,5 @@
-from pydantic import BaseSettings, validator, Field
+from pydantic import validator, Field
+from pydantic_settings import BaseSettings
class ExampleSettings(BaseSettings):
diff --git a/tests/roots/test-edgecase-any-reference/target/example_setting.py b/tests/roots/test-edgecase-any-reference/target/example_setting.py
index 178e4154..88b75b22 100644
--- a/tests/roots/test-edgecase-any-reference/target/example_setting.py
+++ b/tests/roots/test-edgecase-any-reference/target/example_setting.py
@@ -1,4 +1,5 @@
-from pydantic import BaseSettings, validator, Field
+from pydantic import validator, Field
+from pydantic_settings import BaseSettings
class ExampleSettings(BaseSettings):
diff --git a/tests/roots/test-edgecase-typed-field-reference/target/external.py b/tests/roots/test-edgecase-typed-field-reference/target/external.py
index 9a283f04..51e52cb1 100644
--- a/tests/roots/test-edgecase-typed-field-reference/target/external.py
+++ b/tests/roots/test-edgecase-typed-field-reference/target/external.py
@@ -1,4 +1,4 @@
-from pydantic import BaseSettings
+from pydantic_settings import BaseSettings
class TestSettingsExternal(BaseSettings):
diff --git a/tests/roots/test-events-add-css-fallback/add_css_fallback.py b/tests/roots/test-events-add-css-fallback/add_css_fallback.py
index 5f927a27..42fb566f 100644
--- a/tests/roots/test-events-add-css-fallback/add_css_fallback.py
+++ b/tests/roots/test-events-add-css-fallback/add_css_fallback.py
@@ -1,4 +1,5 @@
-from pydantic import BaseModel, Field, validator, BaseSettings
+from pydantic import BaseModel, Field, validator
+from pydantic_settings import BaseSettings
class AutoSummaryModel(BaseModel):
diff --git a/tox.ini b/tox.ini
index a1cd1700..38c5af8e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py{37,38,39,310}-pydantic{15,16,17,18,19,110,latest}-sphinx{34,35,40,41,42,43,44,45,50,51,52,60,61,62,70,latest}, latest, development, no_erdantic, linter
+envlist = py{37,38,39,310}-pydantic{20,latest}-sphinx{40,41,42,43,44,45,50,51,52,60,61,62,70,latest}, latest, development, no_erdantic, linter
isolated_build = True
[testenv]
@@ -12,21 +12,11 @@ commands =
coverage report -m
coverage xml
-[testenv:pydantic{15,16,17,18,19,110,latest}-sphinx{34,35,40,41,42,43,44,45,50,51,52,60,61,62,70,latest}]
+[testenv:pydantic{20,latest}-sphinx{40,41,42,43,44,45,50,51,52,60,61,62,70,latest}]
description = "Test specific historical stable versions."
deps =
- pydantic15: pydantic~=1.5.0
- pydantic16: pydantic~=1.6.0
- pydantic17: pydantic~=1.7.0
- pydantic18: pydantic~=1.8.0
- pydantic19: pydantic~=1.9.0
- pydantic110: pydantic~=1.10.0
+ pydantic20: pydantic~=2.0.0
pydanticlatest: pydantic
- sphinx34: sphinx~=3.4.0
- sphinx34: docutils>=0.14,<0.18
- sphinx34: jinja2<3.1.0
- sphinx35: sphinx~=3.5.0
- sphinx35: jinja2<3.1.0
sphinx40: sphinx~=4.0.0
sphinx41: sphinx~=4.1.0
sphinx42: sphinx~=4.2.0
@@ -77,4 +67,4 @@ commands =
[flake8]
ignore =
TYP001
- TYP004
\ No newline at end of file
+ TYP004
From caa140172703b8dc878ca36df64535a079c293b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Thu, 13 Jul 2023 00:26:45 +0200
Subject: [PATCH 08/42] no import error, limited warnings
---
docs/source/developers/design.rst | 2 +-
docs/source/developers/guides.rst | 4 +-
docs/source/users/examples.rst | 4 +-
docs/source/users/usage.rst | 4 +-
poetry.lock | 179 +++++++++---------
pyproject.toml | 2 +-
.../directives/autodocumenters.py | 5 +-
sphinxcontrib/autodoc_pydantic/inspection.py | 42 ++--
tests/conftest.py | 12 +-
tests/roots/test-base/target/configuration.py | 78 +++-----
.../target/edgecase_json_compliant.py | 5 +-
.../target/edgecase_model_as_attr.py | 2 +-
.../test-base/target/example_generics.py | 2 +-
tests/roots/test-base/target/example_model.py | 11 +-
.../roots/test-base/target/example_setting.py | 2 +-
.../target/example_swap_name_with_alias.py | 2 +-
.../test-base/target/example_validators.py | 2 +-
tests/roots/test-base/target/examples.py | 12 +-
.../test-base/target/faq/model_as_attr.py | 2 +-
.../test-base/target/usage_automodule.py | 2 +-
.../test-base/target/usage_autosummary.py | 2 +-
tests/roots/test-base/target/usage_model.py | 11 +-
tests/roots/test-base/target/usage_setting.py | 2 +-
.../target/example_setting.py | 2 +-
.../add_css_fallback.py | 9 +-
tests/test_edgecases.py | 2 +-
tests/test_inspection.py | 7 +-
27 files changed, 190 insertions(+), 219 deletions(-)
diff --git a/docs/source/developers/design.rst b/docs/source/developers/design.rst
index 920ba3ff..fda2b964 100644
--- a/docs/source/developers/design.rst
+++ b/docs/source/developers/design.rst
@@ -92,7 +92,7 @@ programmatically to inspect pydantic models:
field_a: int = Field(1, min=0, max=10)
field_b: str = "FooBar"
- @validator("field_a")
+ @field_validator("field_a")
def validate_field_a(cls, v):
return v
diff --git a/docs/source/developers/guides.rst b/docs/source/developers/guides.rst
index 9d5a59a3..0d47bb42 100644
--- a/docs/source/developers/guides.rst
+++ b/docs/source/developers/guides.rst
@@ -144,11 +144,11 @@ This requires at least two pydantic fields and validators to be sortable.
field_b: int = 1
field_a: int = 1
- @validator("field_b")
+ @field_validator("field_b")
def validate_b(cls, v):
return v
- @validator("field_a")
+ @field_validator("field_a")
def validate_a(cls, v):
return v
diff --git a/docs/source/users/examples.rst b/docs/source/users/examples.rst
index c2e6abad..31a1ed9a 100644
--- a/docs/source/users/examples.rst
+++ b/docs/source/users/examples.rst
@@ -153,7 +153,7 @@ Asterisk and root validators
----------------------------
This example highlights how `asterisk `_
-(``@validator('*')``) and `root validators `_ (``@root_validator``)
+(``@field_validator('*')``) and `root validators `_ (``@root_validator``)
are represented. Since they validate all fields, their corresponding field reference is replaced
with a simple ``all fields`` marker which hyperlinks to the related model itself.
@@ -333,4 +333,4 @@ and the
.. tab:: python
- .. autocodeblock:: target.example_reused_validators
\ No newline at end of file
+ .. autocodeblock:: target.example_reused_validators
diff --git a/docs/source/users/usage.rst b/docs/source/users/usage.rst
index 7a97887a..2f9b6a52 100644
--- a/docs/source/users/usage.rst
+++ b/docs/source/users/usage.rst
@@ -126,11 +126,11 @@ sensible default settings.
.. code-block:: rest
- .. autopydantic_model:: target.usage_model.ExampleModel
+ .. autopydantic_model:: target.usage_model.ExampleSettings
.. tab:: *rendered output*
- .. autopydantic_model:: target.usage_model.ExampleModel
+ .. autopydantic_model:: target.usage_model.ExampleSettings
:noindex:
.. tab:: python
diff --git a/poetry.lock b/poetry.lock
index 34b83f71..c1581667 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -52,97 +52,97 @@ files = [
[[package]]
name = "charset-normalizer"
-version = "3.1.0"
+version = "3.2.0"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7.0"
files = [
- {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
- {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
+ {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"},
+ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"},
]
[[package]]
name = "click"
-version = "8.1.3"
+version = "8.1.4"
description = "Composable command line interface toolkit"
optional = true
python-versions = ">=3.7"
files = [
- {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
- {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+ {file = "click-8.1.4-py3-none-any.whl", hash = "sha256:2739815aaa5d2c986a88f1e9230c55e17f0caad3d958a5e13ad0797c166db9e3"},
+ {file = "click-8.1.4.tar.gz", hash = "sha256:b97d0c74955da062a7d4ef92fadb583806a585b2ea81958a81bd72726cbb8e37"},
]
[package.dependencies]
@@ -256,21 +256,22 @@ files = [
[[package]]
name = "erdantic"
-version = "0.5.0"
+version = "0.6.0"
description = "Entity relationship diagrams for Python data model classes like Pydantic."
optional = true
python-versions = ">=3.7"
files = [
- {file = "erdantic-0.5.0-py3-none-any.whl", hash = "sha256:43fbe1787d272958991d3b16ffa217b595957e66b394f79be76b4b6dd72dc773"},
- {file = "erdantic-0.5.0.tar.gz", hash = "sha256:475389523b37b1ac06a96837d782a41b889fb27d099a1576183f1721a6a38e23"},
+ {file = "erdantic-0.6.0-py3-none-any.whl", hash = "sha256:50ae472a04fc7a68a16698f1fb81c6f448fe4b9086717f95a4cebd5c8591a2bf"},
+ {file = "erdantic-0.6.0.tar.gz", hash = "sha256:b9d38852ae5ed76adc50589e9924bdba4fdd2bd315fa047fd675a43fc5d9957f"},
]
[package.dependencies]
-importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
-pydantic = "*"
+importlib_metadata = {version = "*", markers = "python_version < \"3.8\""}
+pydantic = ">=2"
+pydantic-core = "*"
pygraphviz = "*"
typer = "*"
-typing-extensions = "*"
+typing_extensions = {version = ">4", markers = "python_version < \"3.8\""}
[[package]]
name = "exceptiongroup"
@@ -471,13 +472,13 @@ files = [
[[package]]
name = "platformdirs"
-version = "3.8.0"
+version = "3.8.1"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
optional = true
python-versions = ">=3.7"
files = [
- {file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"},
- {file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"},
+ {file = "platformdirs-3.8.1-py3-none-any.whl", hash = "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c"},
+ {file = "platformdirs-3.8.1.tar.gz", hash = "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528"},
]
[package.dependencies]
@@ -1137,4 +1138,4 @@ test = ["coverage", "pytest"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.7.2,<4.0.0"
-content-hash = "4848e0572b46e35592999b9d96fb0169fe6a9c49bcc0140225a7bc3d135bbefa"
+content-hash = "99229cd66d1bb086ad644c8942d36fdd86c9e9dac01da456c8f2f5ed135409d1"
diff --git a/pyproject.toml b/pyproject.toml
index a6c1b615..3c289122 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -31,7 +31,7 @@ pytest = {version = "^7", optional = true }
coverage = { version ="^7", optional = true }
flake8 = { version = "^3", optional = true }
tox = { version ="^3", optional = true }
-erdantic= { version ="^0.5", optional = true }
+erdantic = { version ="^0.6", optional = true }
[tool.pytest.ini_options]
minversion = "6.0"
diff --git a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
index 04809f30..bca9ba92 100644
--- a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
+++ b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
@@ -7,7 +7,8 @@
import sphinx
from docutils.statemachine import StringList
-from pydantic import BaseSettings, BaseModel
+from pydantic import BaseModel
+from pydantic_settings import BaseSettings
from sphinx.ext.autodoc import (
MethodDocumenter,
ClassDocumenter,
@@ -724,7 +725,7 @@ def add_alias(self):
if alias_given and alias_required:
sourcename = self.get_sourcename()
- self.add_line(' :alias: ' + field.alias, sourcename)
+ self.add_line(f' :alias: {field.alias}', sourcename)
def add_content(self,
more_content: Optional[StringList],
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index cf4cf56e..d7e2ab9a 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -12,11 +12,11 @@
Optional
import pydantic
-from pydantic import BaseModel, create_model
-from pydantic.class_validators import Validator
+from pydantic import BaseModel, create_model, ConfigDict
from pydantic.fields import FieldInfo
-from pydantic.schema import get_field_schema_validations
+from pydantic.type_adapter import TypeAdapter
from pydantic_settings import SettingsConfigDict
+from pydantic_core import SchemaValidator
from sphinx.addnodes import desc_signature
ASTERISK_FIELD_NAME = "all fields"
@@ -29,6 +29,8 @@ class ValidatorAdapter(BaseModel):
"""
+ model_config = ConfigDict(arbitrary_types_allowed=True)
+
func: Callable
root_pre: bool = False
root_post: bool = False
@@ -80,9 +82,6 @@ def is_member(self, model: Type) -> bool:
bases = (f"{x.__module__}.{x.__qualname__}" for x in model.__mro__)
return f"{self.module}.{self.class_name}" in bases
- class Config:
- arbitrary_types_allowed = True
-
def __hash__(self):
return id(f"{self}")
@@ -172,7 +171,7 @@ def get_constraints(self, field_name: str) -> Dict[str, Any]:
"""
field = self.get(field_name)
- constraints = get_field_schema_validations(field)
+ constraints = TypeAdapter(field).json_schema()
ignore = {"env_names", "env"}
# ignore additional kwargs from pydantic `Field`, see #110
@@ -263,7 +262,8 @@ class ValidatorInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
- self.attribute: Dict[str, List[Validator]] = self.model.__validators__
+
+ self.attribute: SchemaValidator = self.model.__pydantic_validator__
@property
def values(self) -> Set[ValidatorAdapter]:
@@ -325,7 +325,7 @@ class ConfigInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
- self.attribute: Dict = self.model.Config
+ self.attribute: ConfigDict = self.model.model_config
@property
def is_configured(self) -> bool:
@@ -337,7 +337,7 @@ def is_configured(self) -> bool:
cfg = self.attribute
- is_main_config = cfg is pydantic.main.BaseConfig
+ is_main_config = cfg is pydantic.ConfigDict
is_setting_config = cfg is SettingsConfigDict
is_default_config = is_main_config or is_setting_config
@@ -483,7 +483,7 @@ def is_pydantic_field(cls, parent: Any, field_name: str) -> bool:
if not cls.is_pydantic_model(parent):
return False
- return field_name in parent.__fields__
+ return field_name in parent.model_fields
@classmethod
def is_validator_by_name(cls, name: str, obj: Any) -> bool:
@@ -525,21 +525,19 @@ def get_field_validator_mapping(self) -> Dict[str, List[ValidatorAdapter]]:
"""
mapping = defaultdict(list)
+ model_decorators = self.model.__pydantic_decorators__
# standard validators
- for field, validators in self.model.__validators__.items():
- for validator in validators:
- mapping[field].append(ValidatorAdapter(func=validator.func))
+ for field, validator in model_decorators.validators.items():
+ print('field', field, validator)
+ mapping[field].append(ValidatorAdapter(func=validator.func))
# root pre
- for func in self.model.__pre_root_validators__:
- mapping["*"].append(ValidatorAdapter(func=func,
- root_pre=True))
-
- # root post
- for _, func in self.model.__post_root_validators__:
- mapping["*"].append(ValidatorAdapter(func=func,
- root_post=True))
+ for what, validator in model_decorators.root_validators.items(): # TODO
+ print('root', what, validator)
+ is_pre = validator.info.mode == "before"
+ mapping["*"].append(ValidatorAdapter(func=validator.func,
+ root_pre=is_pre))
return mapping
diff --git a/tests/conftest.py b/tests/conftest.py
index c417fa68..859ace81 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -11,7 +11,7 @@
import pytest
import sphinx
-from pydantic import BaseModel
+from pydantic import BaseModel, ConfigDict
from sphinx import application
from sphinx.application import Sphinx
from sphinx.cmd import build
@@ -284,12 +284,10 @@ class SphinxResult(BaseModel):
"""
- app: Optional[application.Sphinx]
- doctree: Optional[Dict[str, Any]]
- return_code: Optional[int]
-
- class Config:
- arbitrary_types_allowed = True
+ model_config = ConfigDict(arbitrary_types_allowed=True)
+ app: Optional[application.Sphinx] = None
+ doctree: Optional[Dict[str, Any]] = None
+ return_code: Optional[int] = None
def combine_sphinx_init_arguments(args: List, kwargs: Dict) -> Dict:
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index f9b35add..64c71f94 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -1,7 +1,7 @@
from typing import Optional
-from pydantic import BaseModel, validator, Field, root_validator
-from pydantic_settings import BaseSettings
+from pydantic import BaseModel, field_validator, Field, root_validator, ConfigDict
+from pydantic_settings import BaseSettings, SettingsConfigDict
class ModelShowJson(BaseModel):
@@ -11,9 +11,7 @@ class ModelShowJson(BaseModel):
class ModelShowConfigSummary(BaseModel):
"""ModelShowConfigSummary."""
- class Config:
- title: str = "FooBar"
- allow_mutation: bool = True
+ model_config = ConfigDict(title="FooBar", frozen=False)
class ModelShowValidatorsSummary(BaseModel):
@@ -21,7 +19,7 @@ class ModelShowValidatorsSummary(BaseModel):
field: int = 1
- @validator("field")
+ @field_validator("field")
def check(cls, v) -> str:
return v
@@ -29,7 +27,7 @@ def check(cls, v) -> str:
class ModelShowValidatorsSummaryInherited(ModelShowValidatorsSummary):
"""ModelShowValidatorsSummaryInherited."""
- @validator("field")
+ @field_validator("field")
def check_inherited(cls, v) -> str:
return v
@@ -41,7 +39,7 @@ class ModelShowValidatorsSummaryMultipleFields(BaseModel):
field2: int = 2
- @validator("field1", "field2")
+ @field_validator("field1", "field2")
def check(cls, v) -> str:
return v
@@ -66,11 +64,11 @@ class ModelSummaryListOrder(BaseModel):
field_b: int = 1
field_a: int = 1
- @validator("field_b")
+ @field_validator("field_b")
def validate_b(cls, v):
return v
- @validator("field_a")
+ @field_validator("field_a")
def validate_a(cls, v):
return v
@@ -102,14 +100,12 @@ class ModelMembers(BaseModel):
class ModelMemberOrder(BaseModel):
"""ModelMemberOrder."""
- @validator("field")
+ @field_validator("field")
def dummy(cls, v) -> str:
"""Check."""
return v
- class Config:
- """Config."""
- allow_mutation = True
+ model_config = ConfigDict(frozen=False)
field: int = 1
"""Field."""
@@ -121,7 +117,7 @@ class ModelShowValidatorMembers(BaseModel):
field: int = 1
"""Field."""
- @validator("field")
+ @field_validator("field")
def dummy(cls, v) -> str:
"""Check."""
return v
@@ -133,9 +129,7 @@ class ModelShowConfigMember(BaseModel):
field: int = 1
"""Field."""
- class Config:
- """Config."""
- allow_mutation = True
+ model_config = ConfigDict(frozen=False)
class ModelSignaturePrefix(BaseModel):
@@ -150,7 +144,7 @@ class ModelWithFieldSwapNameAndAlias(BaseModel):
field2: str = Field(default="FooBar", alias="field2 alias")
"""Field2"""
- @validator("field1")
+ @field_validator("field1")
def check(cls, v) -> str:
"""Check."""
return v
@@ -163,9 +157,7 @@ class SettingsShowJson(BaseSettings):
class SettingsShowConfigSummary(BaseSettings):
"""SettingsShowConfigSummary."""
- class Config:
- title: str = "FooBar"
- allow_mutation: bool = True
+ model_config = SettingsConfigDict(title="FooBar", frozen=False)
class SettingsShowValidatorsSummary(BaseSettings):
@@ -173,7 +165,7 @@ class SettingsShowValidatorsSummary(BaseSettings):
field: int = 1
- @validator("field")
+ @field_validator("field")
def check(cls, v) -> str:
return v
@@ -193,11 +185,11 @@ class SettingsSummaryListOrder(BaseSettings):
field_b: int = 1
field_a: int = 1
- @validator("field_b")
+ @field_validator("field_b")
def validate_b(cls, v):
return v
- @validator("field_a")
+ @field_validator("field_a")
def validate_a(cls, v):
return v
@@ -229,14 +221,12 @@ class SettingsMembers(BaseSettings):
class SettingsMemberOrder(BaseSettings):
"""SettingsMemberOrder."""
- @validator("field")
+ @field_validator("field")
def dummy(cls, v) -> str:
"""Check."""
return v
- class Config:
- """Config."""
- allow_mutation = True
+ model_config = SettingsConfigDict(frozen=False)
field: int = 1
"""Field."""
@@ -248,7 +238,7 @@ class SettingsShowValidatorMembers(BaseSettings):
field: int = 1
"""Field."""
- @validator("field")
+ @field_validator("field")
def dummy(cls, v) -> str:
"""Check."""
return v
@@ -260,9 +250,7 @@ class SettingsShowConfigMember(BaseSettings):
field: int = 1
"""Field."""
- class Config:
- """Config."""
- allow_mutation = True
+ model_config = SettingsConfigDict(frozen=False)
class SettingsSignaturePrefix(BaseSettings):
@@ -272,17 +260,13 @@ class SettingsSignaturePrefix(BaseSettings):
class ConfigMembers(BaseModel):
"""ConfigUndocMembers."""
- class Config:
- allow_mutation = True
- """Allow Mutation."""
- title = "foobar"
+ model_config = ConfigDict(frozen=False, title="FooBar")
class ConfigSignaturePrefix(BaseModel):
"""ConfigSignaturePrefix."""
- class Config:
- """Config."""
+ model_config = ConfigDict()
class ValidatorReplaceSignature(BaseModel):
@@ -290,7 +274,7 @@ class ValidatorReplaceSignature(BaseModel):
field: int = 1
- @validator("field")
+ @field_validator("field")
def check(cls, v) -> str:
"""Check."""
return v
@@ -302,7 +286,7 @@ class ValidatorReplaceSignatureWithSwapNameAndAlias(BaseModel):
field1: int = Field(default=5, alias="field1 alias")
"""Field1"""
- @validator("field1")
+ @field_validator("field1")
def check(cls, v) -> str:
"""Check."""
return v
@@ -313,7 +297,7 @@ class ValidatorListFields(BaseModel):
field: int = 1
- @validator("field")
+ @field_validator("field")
def check(cls, v) -> str:
"""Check."""
return v
@@ -324,7 +308,7 @@ class ValidatorListFieldsWithFieldSwapNameAndAlias(BaseModel):
field: int = Field(1, alias="field_alias")
- @validator("field")
+ @field_validator("field")
def check(cls, v) -> str:
"""Check."""
return v
@@ -335,7 +319,7 @@ class ValidatorSignaturePrefix(BaseModel):
field: int = 1
- @validator("field")
+ @field_validator("field")
def check(cls, v) -> str:
"""Check."""
return v
@@ -346,7 +330,7 @@ class ValidatorAsteriskRootValidator(BaseModel):
field: int = 1
- @validator("*")
+ @field_validator("*")
def check(cls, v):
"""Check."""
return v
@@ -368,7 +352,7 @@ class FieldListValidators(BaseModel):
field: int = 1
"""Field."""
- @validator("field")
+ @field_validator("field")
def check(cls, v) -> str:
"""Check."""
return v
@@ -377,7 +361,7 @@ def check(cls, v) -> str:
class FieldListValidatorsInherited(FieldListValidators):
"""FieldListValidatorsInherited."""
- @validator("field")
+ @field_validator("field")
def check_inherited(cls, v) -> str:
"""Check inherited."""
return v
diff --git a/tests/roots/test-base/target/edgecase_json_compliant.py b/tests/roots/test-base/target/edgecase_json_compliant.py
index dd7928c5..36c0c09f 100644
--- a/tests/roots/test-base/target/edgecase_json_compliant.py
+++ b/tests/roots/test-base/target/edgecase_json_compliant.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel
+from pydantic import BaseModel, ConfigDict
class NoJsonSerializer:
@@ -8,5 +8,4 @@ class NoJsonSerializer:
class NotJsonCompliant(BaseModel):
field: NoJsonSerializer = NoJsonSerializer()
- class Config:
- arbitrary_types_allowed = True
+ model_config = ConfigDict(arbitrary_types_allowed=True)
diff --git a/tests/roots/test-base/target/edgecase_model_as_attr.py b/tests/roots/test-base/target/edgecase_model_as_attr.py
index 285c5692..7eeca862 100644
--- a/tests/roots/test-base/target/edgecase_model_as_attr.py
+++ b/tests/roots/test-base/target/edgecase_model_as_attr.py
@@ -14,7 +14,7 @@ class Model(BaseModel):
field2: str
"""Field2 Doc String"""
- @validator("field")
+ @field_validator("field")
def validate(cls, v):
"""Dummy validator"""
return v
diff --git a/tests/roots/test-base/target/example_generics.py b/tests/roots/test-base/target/example_generics.py
index ed02fb93..a554b1db 100644
--- a/tests/roots/test-base/target/example_generics.py
+++ b/tests/roots/test-base/target/example_generics.py
@@ -24,7 +24,7 @@ class Response(GenericModel, Generic[DataT]):
data: Optional[DataT]
error: Optional[Error]
- @validator('error', always=True)
+ @field_validator('error', always=True)
def check_consistency(cls, v, values):
if v is not None and values['data'] is not None:
raise ValueError('must not provide both data and error')
diff --git a/tests/roots/test-base/target/example_model.py b/tests/roots/test-base/target/example_model.py
index 22e38325..44006379 100644
--- a/tests/roots/test-base/target/example_model.py
+++ b/tests/roots/test-base/target/example_model.py
@@ -1,7 +1,8 @@
-from pydantic import BaseModel, validator, Field
+from pydantic import field_validator, Field
+from pydantic.env_settings import BaseSettings, SettingsConfigDict
-class ExampleModel(BaseModel):
+class ExampleSettings(BaseSettings):
"""Document your project settings very conveniently. Applies like wise
to pydantic models.
@@ -20,7 +21,7 @@ class ExampleModel(BaseModel):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
@@ -31,6 +32,4 @@ def check_max_length_ten(cls, v):
return v
- class Config:
- env_prefix = "foo_"
- allow_mutation = True
+ model_config = SettingsConfigDict(frozen=False, env_prefix="foo_")
diff --git a/tests/roots/test-base/target/example_setting.py b/tests/roots/test-base/target/example_setting.py
index b870ed98..f59f189a 100644
--- a/tests/roots/test-base/target/example_setting.py
+++ b/tests/roots/test-base/target/example_setting.py
@@ -26,7 +26,7 @@ class ExampleSettings(BaseSettings):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
diff --git a/tests/roots/test-base/target/example_swap_name_with_alias.py b/tests/roots/test-base/target/example_swap_name_with_alias.py
index 5f4d6df0..c05266b1 100644
--- a/tests/roots/test-base/target/example_swap_name_with_alias.py
+++ b/tests/roots/test-base/target/example_swap_name_with_alias.py
@@ -10,7 +10,7 @@ class SwapFieldWithAlias(BaseModel):
field_without_alias: int = 5
"""Field without alias."""
- @validator("field_with_alias", "field_without_alias")
+ @field_validator("field_with_alias", "field_without_alias")
def check(cls, v) -> str:
"""Check."""
return v
diff --git a/tests/roots/test-base/target/example_validators.py b/tests/roots/test-base/target/example_validators.py
index 8b7d6828..795b8927 100644
--- a/tests/roots/test-base/target/example_validators.py
+++ b/tests/roots/test-base/target/example_validators.py
@@ -9,7 +9,7 @@ class ExampleValidators(BaseModel):
name: str
email: str
- @validator("*")
+ @field_validator("*")
def check_non_whitespaces(cls, v):
"""Confirm that string contains non whitespace characters.
diff --git a/tests/roots/test-base/target/examples.py b/tests/roots/test-base/target/examples.py
index f9476750..ff843656 100644
--- a/tests/roots/test-base/target/examples.py
+++ b/tests/roots/test-base/target/examples.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator, Field
+from pydantic import BaseModel, field_validator, Field, ConfigDict
class PlainModel(BaseModel):
@@ -18,7 +18,7 @@ class ModelWithFieldValidator(BaseModel):
field: int = 1
"""Doc field"""
- @validator("field")
+ @field_validator("field")
def is_integer(cls, v) -> str:
"""Doc validator."""
return v
@@ -27,14 +27,12 @@ def is_integer(cls, v) -> str:
class ModelWithConfig(BaseModel):
"""Model with Config."""
- class Config:
- """With Doc String."""
- allow_mutation = True
- """FooBar."""
+ """With Doc String."""
+ model_config = ConfigDict(frozen=False)
class ModelWithAlias(BaseModel):
"""Model with Alias."""
field: int = Field(5, alias="aliased")
- """FooBar."""
\ No newline at end of file
+ """FooBar."""
diff --git a/tests/roots/test-base/target/faq/model_as_attr.py b/tests/roots/test-base/target/faq/model_as_attr.py
index df6aa2c5..c0f70849 100644
--- a/tests/roots/test-base/target/faq/model_as_attr.py
+++ b/tests/roots/test-base/target/faq/model_as_attr.py
@@ -10,7 +10,7 @@ class Model(BaseModel):
field2: str
"""Field2 Doc String"""
- @validator("field")
+ @field_validator("field")
def validate(cls, v):
"""Dummy validator"""
return v
diff --git a/tests/roots/test-base/target/usage_automodule.py b/tests/roots/test-base/target/usage_automodule.py
index 752bd548..a75a4243 100644
--- a/tests/roots/test-base/target/usage_automodule.py
+++ b/tests/roots/test-base/target/usage_automodule.py
@@ -26,7 +26,7 @@ class AutoModuleSettings(BaseSettings):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
diff --git a/tests/roots/test-base/target/usage_autosummary.py b/tests/roots/test-base/target/usage_autosummary.py
index 0a18feae..9100a715 100644
--- a/tests/roots/test-base/target/usage_autosummary.py
+++ b/tests/roots/test-base/target/usage_autosummary.py
@@ -21,7 +21,7 @@ class AutoSummaryModel(BaseModel):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
diff --git a/tests/roots/test-base/target/usage_model.py b/tests/roots/test-base/target/usage_model.py
index 22e38325..bc485b8b 100644
--- a/tests/roots/test-base/target/usage_model.py
+++ b/tests/roots/test-base/target/usage_model.py
@@ -1,7 +1,8 @@
-from pydantic import BaseModel, validator, Field
+from pydantic import field_validator, Field
+from pydantic_settings import BaseSettings, SettingsConfigDict
-class ExampleModel(BaseModel):
+class ExampleSettings(BaseSettings):
"""Document your project settings very conveniently. Applies like wise
to pydantic models.
@@ -20,7 +21,7 @@ class ExampleModel(BaseModel):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
@@ -31,6 +32,4 @@ def check_max_length_ten(cls, v):
return v
- class Config:
- env_prefix = "foo_"
- allow_mutation = True
+ model_config = SettingsConfigDict(frozen=False, env_prefix="foo_")
diff --git a/tests/roots/test-base/target/usage_setting.py b/tests/roots/test-base/target/usage_setting.py
index b870ed98..f59f189a 100644
--- a/tests/roots/test-base/target/usage_setting.py
+++ b/tests/roots/test-base/target/usage_setting.py
@@ -26,7 +26,7 @@ class ExampleSettings(BaseSettings):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
diff --git a/tests/roots/test-edgecase-any-reference/target/example_setting.py b/tests/roots/test-edgecase-any-reference/target/example_setting.py
index 88b75b22..f2489df8 100644
--- a/tests/roots/test-edgecase-any-reference/target/example_setting.py
+++ b/tests/roots/test-edgecase-any-reference/target/example_setting.py
@@ -21,7 +21,7 @@ class ExampleSettings(BaseSettings):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
diff --git a/tests/roots/test-events-add-css-fallback/add_css_fallback.py b/tests/roots/test-events-add-css-fallback/add_css_fallback.py
index 42fb566f..8229c12d 100644
--- a/tests/roots/test-events-add-css-fallback/add_css_fallback.py
+++ b/tests/roots/test-events-add-css-fallback/add_css_fallback.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, Field, validator
+from pydantic import BaseModel, Field, field_validator, ConfigDict
from pydantic_settings import BaseSettings
@@ -21,7 +21,7 @@ class AutoSummaryModel(BaseModel):
description="Shows constraints within doc string."
)
- @validator("field_with_validator_and_alias", "field_plain_with_validator")
+ @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
def check_max_length_ten(cls, v):
"""Show corresponding field with link/anchor.
@@ -30,10 +30,7 @@ def check_max_length_ten(cls, v):
if not len(v) < 10:
raise ValueError("No more than 10 characters allowed")
- class Config:
- """Dummy DocString"""
- env_prefix = "foo_"
- allow_mutation = True
+ model_config = ConfigDict(frozen=False)
class AutoSummarySettings(BaseSettings):
diff --git a/tests/test_edgecases.py b/tests/test_edgecases.py
index 42f0e838..227b5308 100644
--- a/tests/test_edgecases.py
+++ b/tests/test_edgecases.py
@@ -59,7 +59,7 @@ def test_current_module_model(parse_rst):
input_rst = ['.. py:currentmodule:: target.example_model',
'',
- '.. autopydantic_model:: ExampleModel',
+ '.. autopydantic_model:: ExampleSettings',
' :model-show-json: True',
' :model-show-config-member: False',
' :model-show-config-summary: True',
diff --git a/tests/test_inspection.py b/tests/test_inspection.py
index be7650e6..69364d52 100644
--- a/tests/test_inspection.py
+++ b/tests/test_inspection.py
@@ -8,9 +8,8 @@
except ImportError:
from typing import _ForwardRef as ForwardRef
-import pydantic
import pytest
-from pydantic import BaseModel
+from pydantic import BaseModel, ConfigDict
from sphinxcontrib.autodoc_pydantic.inspection import ModelInspector, \
StaticInspector
@@ -35,6 +34,7 @@ def __init__(self):
new_type = TypeVar("Dummy")
class NonSerializable(BaseModel):
+ model_config = ConfigDict(arbitrary_types_allowed=True)
field_1: str = "foo"
field_2: object
field_3: str = object()
@@ -42,9 +42,6 @@ class NonSerializable(BaseModel):
field_5: new_type
field_6: int = 10
- class Config:
- arbitrary_types_allowed = True
-
return ModelInspector(NonSerializable)
From 786b84be90820d5204bc6f3e500a373d9d809f2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?=
Date: Tue, 18 Jul 2023 13:44:22 +0200
Subject: [PATCH 09/42] more tests passing
---
changelog.rst | 4 +-
docs/source/developers/design.rst | 4 +-
pyproject.toml | 2 +-
sphinxcontrib/autodoc_pydantic/__init__.py | 7 +-
.../directives/autodocumenters.py | 90 ++-------
.../autodoc_pydantic/directives/directives.py | 13 --
.../directives/options/definition.py | 8 +-
sphinxcontrib/autodoc_pydantic/inspection.py | 59 +++---
tests/roots/test-base/target/configuration.py | 10 +-
.../target/edgecase_model_as_attr.py | 2 +-
.../test-base/target/example_generics.py | 2 +-
.../roots/test-base/target/example_setting.py | 8 +-
.../target/example_swap_name_with_alias.py | 2 +-
.../test-base/target/example_validators.py | 2 +-
tests/roots/test-base/target/examples.py | 3 +-
.../test-base/target/faq/model_as_attr.py | 2 +-
.../test-base/target/usage_automodule.py | 8 +-
.../test-base/target/usage_autosummary.py | 7 +-
tests/roots/test-base/target/usage_setting.py | 8 +-
.../target/example_setting.py | 8 +-
tests/test_autodoc_examples.py | 17 +-
tests/test_autosummary.py | 4 +-
tests/test_configuration_config.py | 172 ------------------
tests/test_configuration_model.py | 4 +-
tests/test_configuration_settings.py | 4 +-
tests/test_directives.py | 36 ++--
26 files changed, 101 insertions(+), 385 deletions(-)
delete mode 100644 tests/test_configuration_config.py
diff --git a/changelog.rst b/changelog.rst
index 06e391eb..7df4e43b 100644
--- a/changelog.rst
+++ b/changelog.rst
@@ -429,7 +429,7 @@ Additionally, it adds support for sphinx 4.3.
Bugfix
~~~~~~
-- Fix a corner-case where a module that imported
+- Fix a corner-case where a module that imported
``numpy.typing.NDArray`` caused autodoc_pydantic to experience
an uncaught exception
`#57 `__.
@@ -975,7 +975,7 @@ Added
- ``config_members``
- Directives ``PydanticModel``, ``PydanticSettings``,
- ``PydanticField``, ``PydanticValidator``, ``PydanticConfigClass``
+ ``PydanticField``, ``PydanticValidator``
Internal
~~~~~~~~
diff --git a/docs/source/developers/design.rst b/docs/source/developers/design.rst
index fda2b964..92c70bcc 100644
--- a/docs/source/developers/design.rst
+++ b/docs/source/developers/design.rst
@@ -85,7 +85,7 @@ programmatically to inspect pydantic models:
.. code-block:: python
from sphinxcontrib.autodoc_pydantic.inspection import ModelInspector
- from pydantic import BaseModel, validator, Field
+ from pydantic import BaseModel, field_validator, Field
class TestModel(BaseModel):
@@ -139,7 +139,6 @@ The following auto-documenters exist in the :ref:`autodocumenters `
- :class:`PydanticFieldDocumenter `
- :class:`PydanticValidatorDocumenter `
-- :class:`PydanticConfigClassDocumenter `
All auto-documenters are not written from scratch but inherit from
the default auto-documenters to borrow most of the main functionality provided
@@ -300,4 +299,3 @@ customization:
- :class:`PydanticSettings `
- :class:`PydanticField `
- :class:`PydanticValidator `
-- :class:`PydanticConfigClass `
diff --git a/pyproject.toml b/pyproject.toml
index 3c289122..3e9b6629 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -18,7 +18,7 @@ classifiers = [
include = ["sphinxcontrib/autodoc_pydantic/css/autodoc_pydantic.css"]
[tool.poetry.dependencies]
-python = ">=3.7.2,<4.0.0"
+python = ">=3.8.0,<4.0.0"
Sphinx = ">=4.0"
pydantic = ">=2.0,<3.0.0"
pydantic-settings = ">=2.0,<3.0.0"
diff --git a/sphinxcontrib/autodoc_pydantic/__init__.py b/sphinxcontrib/autodoc_pydantic/__init__.py
index fafc262e..915ecff8 100644
--- a/sphinxcontrib/autodoc_pydantic/__init__.py
+++ b/sphinxcontrib/autodoc_pydantic/__init__.py
@@ -4,6 +4,7 @@
from pathlib import Path
from typing import Dict, Any
+from importlib.metadata import version
from sphinx.domains import ObjType
from sphinx.application import Sphinx
@@ -11,7 +12,6 @@
from sphinxcontrib.autodoc_pydantic.directives.autodocumenters import (
PydanticValidatorDocumenter,
PydanticModelDocumenter,
- PydanticConfigClassDocumenter,
PydanticFieldDocumenter,
PydanticSettingsDocumenter
)
@@ -20,13 +20,12 @@
from sphinxcontrib.autodoc_pydantic.directives.directives import (
PydanticField,
- PydanticConfigClass,
PydanticValidator,
PydanticModel,
PydanticSettings
)
-__version__ = "1.8.0"
+__version__ = version("autodoc_pydantic")
from sphinxcontrib.autodoc_pydantic.events import add_fallback_css_class
@@ -135,7 +134,6 @@ def add_directives_and_autodocumenters(app: Sphinx):
app.add_directive_to_domain("py", "pydantic_field", PydanticField)
app.add_directive_to_domain("py", "pydantic_model", PydanticModel)
app.add_directive_to_domain("py", "pydantic_settings", PydanticSettings)
- app.add_directive_to_domain("py", "pydantic_config", PydanticConfigClass)
app.add_directive_to_domain("py", "pydantic_validator", PydanticValidator)
app.setup_extension('sphinx.ext.autodoc')
@@ -143,7 +141,6 @@ def add_directives_and_autodocumenters(app: Sphinx):
app.add_autodocumenter(PydanticModelDocumenter)
app.add_autodocumenter(PydanticSettingsDocumenter)
app.add_autodocumenter(PydanticValidatorDocumenter)
- app.add_autodocumenter(PydanticConfigClassDocumenter)
app.connect('object-description-transform', add_fallback_css_class)
diff --git a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
index bca9ba92..50a3045f 100644
--- a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
+++ b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
@@ -30,7 +30,6 @@
OPTIONS_SETTINGS,
OPTIONS_FIELD,
OPTIONS_VALIDATOR,
- OPTIONS_CONFIG,
OPTIONS_MERGED
)
from sphinxcontrib.autodoc_pydantic.directives.templates import to_collapsable
@@ -207,6 +206,9 @@ def can_document_member(cls,
def __init__(self, *args: Any) -> None:
super().__init__(*args)
+ exclude_members = self.options.setdefault("exclude-members", set())
+ exclude_members.add("model_fields")
+ exclude_members.add("model_config")
self.pydantic = PydanticAutoDoc(self, is_child=False)
def document_members(self, *args, **kwargs):
@@ -234,21 +236,17 @@ def hide_config_member(self):
"""
- if "exclude-members" not in self.options:
- self.options["exclude-members"] = {"Config"}
- else:
- self.options["exclude-members"].add("Config")
+ exclude_members = self.options["exclude-members"]
+ exclude_members.add("Config") # deprecated since pydantic v2
+ exclude_members.add("model_config")
def hide_validator_members(self):
"""Add validator names to `exclude_members`.
"""
-
validators = self.pydantic.inspect.validators.names
- if "exclude-members" not in self.options:
- self.options["exclude-members"] = validators
- else:
- self.options["exclude-members"].update(validators)
+ exclude_members = self.options["exclude-members"]
+ exclude_members.update(validators)
def hide_reused_validators(self):
"""Add reused validators to `exclude_members` option.
@@ -257,11 +255,8 @@ def hide_reused_validators(self):
validators = self.pydantic.inspect.validators
reused_validators = validators.get_reused_validator_method_names()
-
- if "exclude-members" not in self.options:
- self.options["exclude-members"] = set(reused_validators)
- else:
- self.options["exclude-members"].update(reused_validators)
+ exclude_members = self.options["exclude-members"]
+ exclude_members.update(reused_validators)
def format_signature(self, **kwargs) -> str:
"""If parameter list is to be hidden, return only empty signature.
@@ -449,7 +444,6 @@ def add_validators_summary(self):
if not self.pydantic.inspect.validators:
return
-
sorted_references = self._get_validator_summary_references()
source_name = self.get_sourcename()
@@ -539,7 +533,6 @@ def _convert_json_schema_to_rest(schema: Dict) -> List[str]:
"""Convert model's schema dict into reST.
"""
-
schema = json.dumps(schema, default=str, indent=3)
lines = [f" {line}" for line in schema.split("\n")]
lines = ['.. code-block:: json', ''] + lines
@@ -651,7 +644,6 @@ def add_directive_header(self, sig: str) -> None:
"""Delegate header options.
"""
-
super().add_directive_header(sig)
self.add_default_value_or_marker()
@@ -717,7 +709,7 @@ def add_alias(self):
field_name = self.pydantic_field_name
field = self.pydantic.inspect.fields.get(field_name)
- alias_given = field.alias != field_name
+ alias_given = field.alias and field.alias != field_name
show_alias = self.pydantic.options.is_true("field-show-alias")
swap = self.pydantic.options.is_true("field-swap-name-and-alias")
@@ -905,63 +897,3 @@ def add_field_list(self):
self.add_line("", source_name)
-
-class PydanticConfigClassDocumenter(ClassDocumenter):
- """Represents specialized Documenter subclass for pydantic model
- configuration.
-
- """
-
- objtype = 'pydantic_config'
- directivetype = 'pydantic_config'
- option_spec = ClassDocumenter.option_spec.copy()
- option_spec.update(OPTIONS_CONFIG)
- member_order = 100
- priority = 10 + ClassDocumenter.priority
-
- pyautodoc_pass_to_directive = (
- "config-signature-prefix",
- )
-
- def __init__(self, *args: Any) -> None:
- super().__init__(*args)
- self.pydantic = PydanticAutoDoc(self, is_child=True)
-
- @classmethod
- def can_document_member(cls,
- member: Any,
- membername: str,
- isattr: bool,
- parent: Any) -> bool:
- """Filter only pydantic model configurations.
-
- """
-
- is_val = super().can_document_member(member, membername, isattr,
- parent)
- is_parent_model = ModelInspector.static.is_pydantic_model(
- parent.object)
- is_config = membername == "Config"
- is_class = isinstance(member, type)
- return is_val and is_parent_model and is_config and is_class
-
- def document_members(self, *args, **kwargs):
- """Modify member options before starting to document members.
-
- """
-
- self.pydantic.options.set_members_all()
- if self.options.get("members"):
- self.options["undoc-members"] = True
-
- # handle special case when Config is documented as an attribute
- # in which case `all_members` defaults to True which has to be
- # overruled by `autodoc_pydantic_config_members` app cfg
- app_cfg = self.pydantic.options.get_app_cfg_by_name("members")
- hide_members = app_cfg is False
- no_members = bool(self.options.get("members")) is False
-
- if hide_members and no_members:
- super().document_members(all_members=False, **kwargs)
- else:
- super().document_members(*args, **kwargs)
diff --git a/sphinxcontrib/autodoc_pydantic/directives/directives.py b/sphinxcontrib/autodoc_pydantic/directives/directives.py
index 1c1c7f11..ad0f8414 100644
--- a/sphinxcontrib/autodoc_pydantic/directives/directives.py
+++ b/sphinxcontrib/autodoc_pydantic/directives/directives.py
@@ -266,16 +266,3 @@ def handle_signature(self, sig: str, signode: desc_signature) -> TUPLE_STR:
self.replace_return_node(signode)
return fullname, prefix
-
-
-class PydanticConfigClass(PydanticDirectiveBase, PyClasslike):
- """Specialized directive for pydantic config class.
-
- """
-
- option_spec = PyClasslike.option_spec.copy()
- option_spec.update({"__doc_disable_except__": option_list_like,
- "config-signature-prefix": unchanged})
-
- config_name = "config"
- default_prefix = "class"
diff --git a/sphinxcontrib/autodoc_pydantic/directives/options/definition.py b/sphinxcontrib/autodoc_pydantic/directives/options/definition.py
index 2da930ad..3c5f5bf5 100644
--- a/sphinxcontrib/autodoc_pydantic/directives/options/definition.py
+++ b/sphinxcontrib/autodoc_pydantic/directives/options/definition.py
@@ -31,14 +31,8 @@
"""Represents added directive options for :class:`PydanticValidatorDocumenter`.
"""
-OPTIONS_CONFIG = {"members": option_members,
- "config-signature-prefix": unchanged,
- "__doc_disable_except__": option_list_like}
-"""Represents added directive options for :class:`PydanticConfigDocumenter`."""
-
OPTIONS_MERGED = {**OPTIONS_FIELD,
- **OPTIONS_VALIDATOR,
- **OPTIONS_CONFIG}
+ **OPTIONS_VALIDATOR}
OPTIONS_MODEL = {
"model-show-json": option_default_true,
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index d7e2ab9a..d1b4b5b7 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -9,12 +9,12 @@
import warnings
from collections import defaultdict
from typing import NamedTuple, List, Dict, Any, Set, TypeVar, Type, Callable, \
- Optional
+ Optional, Union
-import pydantic
from pydantic import BaseModel, create_model, ConfigDict
from pydantic.fields import FieldInfo
from pydantic.type_adapter import TypeAdapter
+from pydantic._internal._decorators import Decorator, ValidatorDecoratorInfo
from pydantic_settings import SettingsConfigDict
from pydantic_core import SchemaValidator
from sphinx.addnodes import desc_signature
@@ -123,6 +123,8 @@ class FieldInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
+ # json schema can reliably be created only at model level
+ self.model_json_schema = self.model.model_json_schema()
self.attribute = self.model.model_fields
@property
@@ -170,9 +172,8 @@ def get_constraints(self, field_name: str) -> Dict[str, Any]:
"""
- field = self.get(field_name)
- constraints = TypeAdapter(field).json_schema()
- ignore = {"env_names", "env"}
+ constraints = self.model_json_schema["properties"].get(field_name, {})
+ ignore = {"env_names", "env", "default", "title", "type"}
# ignore additional kwargs from pydantic `Field`, see #110
extra_kwargs = self.get_property_from_field_info(field_name=field_name,
@@ -262,8 +263,11 @@ class ValidatorInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
-
- self.attribute: SchemaValidator = self.model.__pydantic_validator__
+ self.attribute: Dict[str, Decorator[ValidatorDecoratorInfo]] = dict(
+ **self.model.__pydantic_decorators__.validators,
+ **self.model.__pydantic_decorators__.field_validators,
+ **self.model.__pydantic_decorators__.root_validators
+ )
@property
def values(self) -> Set[ValidatorAdapter]:
@@ -317,6 +321,7 @@ def __bool__(self):
return bool(self.attribute)
+# TODO: remove (made useless by model.model_config in pydantic v2).
class ConfigInspector(BaseInspectionComposite):
"""Provide namespace for inspection methods for config class of pydantic
models.
@@ -335,24 +340,16 @@ def is_configured(self) -> bool:
"""
- cfg = self.attribute
-
- is_main_config = cfg is pydantic.ConfigDict
- is_setting_config = cfg is SettingsConfigDict
- is_default_config = is_main_config or is_setting_config
-
- return not is_default_config
+ return bool(self.attribute)
@property
- def items(self) -> Dict:
+ def items(self) -> Union[ConfigDict, SettingsConfigDict]:
"""Return all non private (without leading underscore `_`) items of
pydantic configuration class.
"""
- return {key: getattr(self.attribute, key)
- for key in dir(self.attribute)
- if not key.startswith("_")}
+ return self.attribute
class ReferenceInspector(BaseInspectionComposite):
@@ -441,11 +438,17 @@ def sanitized(self) -> Dict:
try:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
- return self.model.schema()
+ schema = self.model.model_json_schema()
except (TypeError, ValueError):
new_model = self.create_sanitized_model()
- return new_model.model_json_schema()
+ schema = new_model.model_json_schema()
+
+ keys_order = ["title", "description", "type", "properties"]
+ reordered_schema = {k: schema[k] for k in keys_order if k in schema}
+ reordered_schema.update(schema)
+ return reordered_schema
+
def create_sanitized_model(self) -> BaseModel:
"""Generates a new pydantic model from the original one while
@@ -528,13 +531,15 @@ def get_field_validator_mapping(self) -> Dict[str, List[ValidatorAdapter]]:
model_decorators = self.model.__pydantic_decorators__
# standard validators
- for field, validator in model_decorators.validators.items():
- print('field', field, validator)
- mapping[field].append(ValidatorAdapter(func=validator.func))
-
- # root pre
- for what, validator in model_decorators.root_validators.items(): # TODO
- print('root', what, validator)
+ for validator in model_decorators.validators.values():
+ for field in validator.info.fields:
+ mapping[field].append(ValidatorAdapter(func=validator.func))
+ for validator in model_decorators.field_validators.values():
+ for field in validator.info.fields:
+ mapping[field].append(ValidatorAdapter(func=validator.func))
+
+ # root validators
+ for validator in model_decorators.root_validators.values():
is_pre = validator.info.mode == "before"
mapping["*"].append(ValidatorAdapter(func=validator.func,
root_pre=is_pre))
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index 64c71f94..1a0fcb3f 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -1,6 +1,6 @@
from typing import Optional
-from pydantic import BaseModel, field_validator, Field, root_validator, ConfigDict
+from pydantic import BaseModel, field_validator, Field, model_validator, ConfigDict, root_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -260,7 +260,9 @@ class SettingsSignaturePrefix(BaseSettings):
class ConfigMembers(BaseModel):
"""ConfigUndocMembers."""
- model_config = ConfigDict(frozen=False, title="FooBar")
+ class Config:
+ frozen = False
+ title = "FooBar"
class ConfigSignaturePrefix(BaseModel):
@@ -335,12 +337,12 @@ def check(cls, v):
"""Check."""
return v
- @root_validator
+ @root_validator(skip_on_failure=True)
def check_root(cls, values):
"""Check root."""
return values
- @root_validator(pre=True)
+ @model_validator(mode="before")
def check_root_pre(cls, values):
"""Check root pre."""
return values
diff --git a/tests/roots/test-base/target/edgecase_model_as_attr.py b/tests/roots/test-base/target/edgecase_model_as_attr.py
index 7eeca862..78c6735a 100644
--- a/tests/roots/test-base/target/edgecase_model_as_attr.py
+++ b/tests/roots/test-base/target/edgecase_model_as_attr.py
@@ -2,7 +2,7 @@
models/settings when used as class attributes.
"""
-from pydantic import BaseModel, validator
+from pydantic import BaseModel, field_validator
class Model(BaseModel):
diff --git a/tests/roots/test-base/target/example_generics.py b/tests/roots/test-base/target/example_generics.py
index a554b1db..28072d8c 100644
--- a/tests/roots/test-base/target/example_generics.py
+++ b/tests/roots/test-base/target/example_generics.py
@@ -1,6 +1,6 @@
from typing import Generic, TypeVar, Optional, List
-from pydantic import BaseModel, validator
+from pydantic import BaseModel, field_validator
from pydantic.generics import GenericModel
DataT = TypeVar('DataT')
diff --git a/tests/roots/test-base/target/example_setting.py b/tests/roots/test-base/target/example_setting.py
index f59f189a..51caad02 100644
--- a/tests/roots/test-base/target/example_setting.py
+++ b/tests/roots/test-base/target/example_setting.py
@@ -1,5 +1,5 @@
-from pydantic import validator, Field
-from pydantic_settings import BaseSettings
+from pydantic import field_validator, Field
+from pydantic_settings import BaseSettings, SettingsConfigDict
class ExampleSettings(BaseSettings):
@@ -37,6 +37,4 @@ def check_max_length_ten(cls, v):
return v
- class Config:
- env_prefix = "foo_"
- allow_mutation = True
+ model_config = SettingsConfigDict(env_prefix="foo_", frozen=False)
diff --git a/tests/roots/test-base/target/example_swap_name_with_alias.py b/tests/roots/test-base/target/example_swap_name_with_alias.py
index c05266b1..417f4eca 100644
--- a/tests/roots/test-base/target/example_swap_name_with_alias.py
+++ b/tests/roots/test-base/target/example_swap_name_with_alias.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator, Field
+from pydantic import BaseModel, field_validator, Field
class SwapFieldWithAlias(BaseModel):
diff --git a/tests/roots/test-base/target/example_validators.py b/tests/roots/test-base/target/example_validators.py
index 795b8927..d9851ed2 100644
--- a/tests/roots/test-base/target/example_validators.py
+++ b/tests/roots/test-base/target/example_validators.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator, root_validator
+from pydantic import BaseModel, field_validator, root_validator
class ExampleValidators(BaseModel):
diff --git a/tests/roots/test-base/target/examples.py b/tests/roots/test-base/target/examples.py
index ff843656..bf44def2 100644
--- a/tests/roots/test-base/target/examples.py
+++ b/tests/roots/test-base/target/examples.py
@@ -4,7 +4,6 @@
class PlainModel(BaseModel):
"""Model Plain."""
-
class ModelWithField(BaseModel):
"""Model With Field."""
@@ -19,7 +18,7 @@ class ModelWithFieldValidator(BaseModel):
"""Doc field"""
@field_validator("field")
- def is_integer(cls, v) -> str:
+ def is_integer(cls, v):
"""Doc validator."""
return v
diff --git a/tests/roots/test-base/target/faq/model_as_attr.py b/tests/roots/test-base/target/faq/model_as_attr.py
index c0f70849..519dfc54 100644
--- a/tests/roots/test-base/target/faq/model_as_attr.py
+++ b/tests/roots/test-base/target/faq/model_as_attr.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator
+from pydantic import BaseModel, field_validator
class Model(BaseModel):
diff --git a/tests/roots/test-base/target/usage_automodule.py b/tests/roots/test-base/target/usage_automodule.py
index a75a4243..1aea1fb5 100644
--- a/tests/roots/test-base/target/usage_automodule.py
+++ b/tests/roots/test-base/target/usage_automodule.py
@@ -1,5 +1,5 @@
-from pydantic import validator, Field
-from pydantic_settings import BaseSettings
+from pydantic import field_validator, Field
+from pydantic_settings import BaseSettings, SettingsConfigDict
class AutoModuleSettings(BaseSettings):
@@ -37,6 +37,4 @@ def check_max_length_ten(cls, v):
return v
- class Config:
- env_prefix = "foo_"
- allow_mutation = True
+ model_config = SettingsConfigDict(env_prefix="foo_", frozen=False)
diff --git a/tests/roots/test-base/target/usage_autosummary.py b/tests/roots/test-base/target/usage_autosummary.py
index 9100a715..e882305b 100644
--- a/tests/roots/test-base/target/usage_autosummary.py
+++ b/tests/roots/test-base/target/usage_autosummary.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, Field, validator
+from pydantic import BaseModel, Field, field_validator, ConfigDict
from pydantic_settings import BaseSettings
@@ -30,10 +30,7 @@ def check_max_length_ten(cls, v):
if not len(v) < 10:
raise ValueError("No more than 10 characters allowed")
- class Config:
- env_prefix = "foo_"
- allow_mutation = True
-
+ model_config = ConfigDict(frozen=False)
class AutoSummarySettings(BaseSettings):
"""Some settings with pydantic."""
diff --git a/tests/roots/test-base/target/usage_setting.py b/tests/roots/test-base/target/usage_setting.py
index f59f189a..51caad02 100644
--- a/tests/roots/test-base/target/usage_setting.py
+++ b/tests/roots/test-base/target/usage_setting.py
@@ -1,5 +1,5 @@
-from pydantic import validator, Field
-from pydantic_settings import BaseSettings
+from pydantic import field_validator, Field
+from pydantic_settings import BaseSettings, SettingsConfigDict
class ExampleSettings(BaseSettings):
@@ -37,6 +37,4 @@ def check_max_length_ten(cls, v):
return v
- class Config:
- env_prefix = "foo_"
- allow_mutation = True
+ model_config = SettingsConfigDict(env_prefix="foo_", frozen=False)
diff --git a/tests/roots/test-edgecase-any-reference/target/example_setting.py b/tests/roots/test-edgecase-any-reference/target/example_setting.py
index f2489df8..31b03aab 100644
--- a/tests/roots/test-edgecase-any-reference/target/example_setting.py
+++ b/tests/roots/test-edgecase-any-reference/target/example_setting.py
@@ -1,5 +1,5 @@
-from pydantic import validator, Field
-from pydantic_settings import BaseSettings
+from pydantic import field_validator, Field
+from pydantic_settings import BaseSettings, SettingsConfigDict
class ExampleSettings(BaseSettings):
@@ -30,6 +30,4 @@ def check_max_length_ten(cls, v):
if not len(v) < 10:
raise ValueError("No more than 10 characters allowed")
- class Config:
- env_prefix = "foo_"
- allow_mutation = True
+ model_config = SettingsConfigDict(env_prefix="foo_", frozen=False)
diff --git a/tests/test_autodoc_examples.py b/tests/test_autodoc_examples.py
index 118b50ef..740e418a 100644
--- a/tests/test_autodoc_examples.py
+++ b/tests/test_autodoc_examples.py
@@ -109,20 +109,7 @@ def test_model_with_config(autodocument):
' Model with Config.',
'',
' :Config:',
- ' - **allow_mutation**: *bool = True*',
- '',
- '',
- ' .. py:pydantic_config:: ModelWithConfig.Config()',
- ' :module: target.examples',
- '',
- ' With Doc String.',
- '',
- '',
- ' .. py:attribute:: ModelWithConfig.Config.allow_mutation',
- ' :module: target.examples',
- ' :value: True',
- '',
- ' FooBar.',
+ ' - **frozen**: *bool = False*',
'']
@@ -156,4 +143,4 @@ def test_model_plain_show_json(autodocument):
'',
'
',
'',
- '']
\ No newline at end of file
+ '']
diff --git a/tests/test_autosummary.py b/tests/test_autosummary.py
index 4dce782d..a16ec28f 100644
--- a/tests/test_autosummary.py
+++ b/tests/test_autosummary.py
@@ -7,15 +7,13 @@
PydanticSettingsDocumenter,
PydanticFieldDocumenter,
PydanticValidatorDocumenter,
- PydanticConfigClassDocumenter
)
@pytest.mark.parametrize("klass", [PydanticModelDocumenter,
PydanticSettingsDocumenter,
PydanticFieldDocumenter,
- PydanticValidatorDocumenter,
- PydanticConfigClassDocumenter])
+ PydanticValidatorDocumenter])
def test_autosummary_fake_directive(klass):
"""Ensure that using autosummary's `FakeDirective` works with
pydantic autodocumenters.
diff --git a/tests/test_configuration_config.py b/tests/test_configuration_config.py
deleted file mode 100644
index 588abfa7..00000000
--- a/tests/test_configuration_config.py
+++ /dev/null
@@ -1,172 +0,0 @@
-"""This module contains tests for pydantic config class configurations.
-
-"""
-
-from sphinx.addnodes import desc_annotation
-from sphinx.testing.util import assert_node
-import sphinx
-
-from sphinxcontrib.autodoc_pydantic import PydanticConfigClassDocumenter
-from tests.compatibility import desc_annotation_directive_prefix
-
-KWARGS = dict(documenter=PydanticConfigClassDocumenter.directivetype,
- deactivate_all=True)
-
-
-def test_autodoc_pydantic_config_members_true(autodocument):
- kwargs = dict(object_path='target.configuration.ConfigMembers.Config',
- **KWARGS)
-
- result = [
- '',
- ".. py:pydantic_config:: Config()",
- ' :module: target.configuration.ConfigMembers',
- '',
- '',
- ' .. py:attribute:: Config.allow_mutation',
- ' :module: target.configuration.ConfigMembers',
- ' :value: True',
- '',
- ' Allow Mutation.',
- '',
- '',
- ' .. py:attribute:: Config.title',
- ' :module: target.configuration.ConfigMembers',
- " :value: 'foobar'",
- ''
- ]
-
- if sphinx.version_info[:2] <= (3, 4):
- result.pop(9)
- result.pop(10)
-
- # explict global
- actual = autodocument(
- options_app={"autodoc_pydantic_config_members": True}, **kwargs)
- assert result == actual
-
- # explict local
- actual = autodocument(options_doc={"members": None}, **kwargs)
- assert result == actual
-
- # explicit local overwrite global
- actual = autodocument(
- options_app={"autodoc_pydantic_config_members": False},
- options_doc={"members": None},
- **kwargs)
- assert result == actual
-
-
-def test_autodoc_pydantic_config_members_false(autodocument):
- kwargs = dict(object_path='target.configuration.ConfigMembers.Config',
- **KWARGS)
-
- result = [
- '',
- ".. py:pydantic_config:: Config()",
- ' :module: target.configuration.ConfigMembers',
- '',
- ]
-
- # explict global
- actual = autodocument(
- options_app={"autodoc_pydantic_config_members": False},
- **kwargs)
- assert result == actual
-
- # explict local
- actual = autodocument(options_doc={"members": "False"}, **kwargs)
- assert result == actual
-
- # explicit local overwrite global
- actual = autodocument(
- options_app={"autodoc_pydantic_config_members": True},
- options_doc={"members": "False"},
- **kwargs)
- assert result == actual
-
-
-def test_autodoc_pydantic_config_signature_prefix(autodocument):
- kwargs = dict(
- object_path='target.configuration.ConfigSignaturePrefix.Config',
- **KWARGS)
-
- # default
- result = [
- '',
- ".. py:pydantic_config:: Config()",
- ' :module: target.configuration.ConfigSignaturePrefix',
- '',
- ' Config.',
- ''
- ]
-
- actual = autodocument(**kwargs)
- assert result == actual
-
- # explicit value
- result = [
- '',
- ".. py:pydantic_config:: Config()",
- ' :module: target.configuration.ConfigSignaturePrefix',
- ' :config-signature-prefix: foobar',
- '',
- ' Config.',
- ''
- ]
-
- actual = autodocument(options_doc={"config-signature-prefix": "foobar"},
- **kwargs)
- assert result == actual
-
- # explict empty
- result = [
- '',
- ".. py:pydantic_config:: Config()",
- ' :module: target.configuration.ConfigSignaturePrefix',
- ' :config-signature-prefix: ',
- '',
- ' Config.',
- ''
- ]
-
- actual = autodocument(options_doc={"config-signature-prefix": ""},
- **kwargs)
- assert result == actual
-
-
-def test_autodoc_pydantic_config_signature_prefix_directive(parse_rst):
- # default
- input_rst = [
- '',
- ".. py:pydantic_config:: Config()",
- ' :module: target.configuration.ConfigSignaturePrefix',
- '',
- ' Config.',
- ''
- ]
-
- doctree = parse_rst(input_rst)
- prefix = desc_annotation_directive_prefix("model")
- assert_node(doctree[1][0][0], [desc_annotation, prefix])
-
- # empty
- doctree = parse_rst(input_rst,
- conf={"autodoc_pydantic_config_signature_prefix": ""})
- prefix = desc_annotation_directive_prefix("class")
- assert_node(doctree[1][0][0], [desc_annotation, prefix])
-
- # custom
- input_rst = [
- '',
- ".. py:pydantic_config:: Config()",
- ' :module: target.configuration.ConfigSignaturePrefix',
- ' :config-signature-prefix: foobar',
- '',
- ' Config.',
- ''
- ]
-
- doctree = parse_rst(input_rst)
- prefix = desc_annotation_directive_prefix("foobar")
- assert_node(doctree[1][0][0], [desc_annotation, prefix])
diff --git a/tests/test_configuration_model.py b/tests/test_configuration_model.py
index ae9d45da..627e9f8e 100644
--- a/tests/test_configuration_model.py
+++ b/tests/test_configuration_model.py
@@ -276,7 +276,7 @@ def test_autodoc_pydantic_model_show_config_summary_summary_true(autodocument):
' ModelShowConfigSummary.',
'',
' :Config:',
- ' - **allow_mutation**: *bool = True*',
+ ' - **frozen**: *bool = True*',
' - **title**: *str = FooBar*',
'']
@@ -1109,7 +1109,7 @@ def test_autodoc_pydantic_model_show_config_members_true(autodocument):
' Config.',
'',
'',
- ' .. py:attribute:: ModelShowConfigMember.Config.allow_mutation',
+ ' .. py:attribute:: ModelShowConfigMember.Config.frozen',
' :module: target.configuration',
' :value: True',
'']
diff --git a/tests/test_configuration_settings.py b/tests/test_configuration_settings.py
index ec23aa51..03b41e6d 100644
--- a/tests/test_configuration_settings.py
+++ b/tests/test_configuration_settings.py
@@ -116,7 +116,7 @@ def test_autodoc_pydantic_settings_show_config_summary_summary_true(autodocument
' SettingsShowConfigSummary.',
'',
' :Config:',
- ' - **allow_mutation**: *bool = True*',
+ ' - **frozen**: *bool = True*',
' - **title**: *str = FooBar*',
'']
@@ -928,7 +928,7 @@ def test_autodoc_pydantic_settings_show_config_members_true(autodocument):
' Config.',
'',
'',
- ' .. py:attribute:: SettingsShowConfigMember.Config.allow_mutation',
+ ' .. py:attribute:: SettingsShowConfigMember.Config.frozen',
' :module: target.configuration',
' :value: True',
'']
diff --git a/tests/test_directives.py b/tests/test_directives.py
index b1d7c67d..3253a0e1 100644
--- a/tests/test_directives.py
+++ b/tests/test_directives.py
@@ -3,25 +3,25 @@
"""
from docutils.nodes import (
- paragraph,
- field_list,
+ paragraph,
+ field_list,
field,
- field_name,
- field_body,
- bullet_list,
- list_item,
- literal,
- emphasis,
+ field_name,
+ field_body,
+ bullet_list,
+ list_item,
+ literal,
+ emphasis,
strong
)
from sphinx.addnodes import (
- desc,
- desc_signature,
- desc_name,
+ desc,
+ desc_signature,
+ desc_name,
desc_content,
- desc_annotation,
- desc_addname,
- pending_xref,
+ desc_annotation,
+ desc_addname,
+ pending_xref,
index
)
from sphinx.testing.util import assert_node
@@ -221,7 +221,7 @@ def test_example_model_with_config(parse_rst):
' Model with Config.',
'',
' :Config:',
- ' - **allow_mutation**: *bool = True*',
+ ' - **frozen**: *bool = True*',
'',
' .. py:pydantic_config:: ModelWithConfig.Config()',
' :module: target.examples',
@@ -229,7 +229,7 @@ def test_example_model_with_config(parse_rst):
' With Doc String.',
'',
'',
- ' .. py:attribute:: ModelWithConfig.Config.allow_mutation',
+ ' .. py:attribute:: ModelWithConfig.Config.frozen',
' :module: target.examples',
' :value: True',
'',
@@ -245,7 +245,7 @@ def test_example_model_with_config(parse_rst):
[desc_content, ([paragraph, "With Doc String."],
index,
[desc, (
- [desc_signature, ([desc_name, "allow_mutation"],
+ [desc_signature, ([desc_name, "frozen"],
default_value)],
[desc_content, ([paragraph, "FooBar."])])
]
@@ -258,7 +258,7 @@ def test_example_model_with_config(parse_rst):
[field_body, ([
bullet_list, ([
list_item, ([
- paragraph, ([strong, "allow_mutation"],
+ paragraph, ([strong, "frozen"],
": ",
[emphasis, "bool = True"])
])
From c22c76deb9bc023658f5f66e1da7264f8a2256ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Thu, 20 Jul 2023 17:12:23 +0200
Subject: [PATCH 10/42] Remove poetry.lock
---
poetry.lock | 1141 ---------------------------------------------------
1 file changed, 1141 deletions(-)
delete mode 100644 poetry.lock
diff --git a/poetry.lock b/poetry.lock
deleted file mode 100644
index c1581667..00000000
--- a/poetry.lock
+++ /dev/null
@@ -1,1141 +0,0 @@
-# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
-
-[[package]]
-name = "alabaster"
-version = "0.7.13"
-description = "A configurable sidebar-enabled Sphinx theme"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
- {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
-]
-
-[[package]]
-name = "annotated-types"
-version = "0.5.0"
-description = "Reusable constraint types to use with typing.Annotated"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"},
- {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"},
-]
-
-[package.dependencies]
-typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""}
-
-[[package]]
-name = "babel"
-version = "2.12.1"
-description = "Internationalization utilities"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
- {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
-]
-
-[package.dependencies]
-pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
-
-[[package]]
-name = "certifi"
-version = "2023.5.7"
-description = "Python package for providing Mozilla's CA Bundle."
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"},
- {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"},
-]
-
-[[package]]
-name = "charset-normalizer"
-version = "3.2.0"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-optional = false
-python-versions = ">=3.7.0"
-files = [
- {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"},
- {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"},
- {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"},
- {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"},
- {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"},
- {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"},
- {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"},
-]
-
-[[package]]
-name = "click"
-version = "8.1.4"
-description = "Composable command line interface toolkit"
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "click-8.1.4-py3-none-any.whl", hash = "sha256:2739815aaa5d2c986a88f1e9230c55e17f0caad3d958a5e13ad0797c166db9e3"},
- {file = "click-8.1.4.tar.gz", hash = "sha256:b97d0c74955da062a7d4ef92fadb583806a585b2ea81958a81bd72726cbb8e37"},
-]
-
-[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."
-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.2.7"
-description = "Code coverage measurement for Python"
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"},
- {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"},
- {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"},
- {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"},
- {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"},
- {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"},
- {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"},
- {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"},
- {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"},
- {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"},
- {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"},
- {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"},
- {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"},
- {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"},
- {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"},
- {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"},
- {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"},
- {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"},
- {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"},
- {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"},
- {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"},
- {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"},
- {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"},
- {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"},
- {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"},
- {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"},
- {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"},
- {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"},
- {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"},
- {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"},
- {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"},
- {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"},
- {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"},
- {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"},
- {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"},
- {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"},
- {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"},
- {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"},
- {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"},
- {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"},
- {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"},
- {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"},
- {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"},
- {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"},
- {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"},
- {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"},
- {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"},
- {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"},
- {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"},
- {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"},
- {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"},
- {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"},
- {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"},
- {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"},
- {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"},
- {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"},
- {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"},
- {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"},
- {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"},
- {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"},
-]
-
-[package.extras]
-toml = ["tomli"]
-
-[[package]]
-name = "distlib"
-version = "0.3.6"
-description = "Distribution utilities"
-optional = true
-python-versions = "*"
-files = [
- {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
- {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
-]
-
-[[package]]
-name = "docutils"
-version = "0.18.1"
-description = "Docutils -- Python Documentation Utilities"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-files = [
- {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
- {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
-]
-
-[[package]]
-name = "erdantic"
-version = "0.6.0"
-description = "Entity relationship diagrams for Python data model classes like Pydantic."
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "erdantic-0.6.0-py3-none-any.whl", hash = "sha256:50ae472a04fc7a68a16698f1fb81c6f448fe4b9086717f95a4cebd5c8591a2bf"},
- {file = "erdantic-0.6.0.tar.gz", hash = "sha256:b9d38852ae5ed76adc50589e9924bdba4fdd2bd315fa047fd675a43fc5d9957f"},
-]
-
-[package.dependencies]
-importlib_metadata = {version = "*", markers = "python_version < \"3.8\""}
-pydantic = ">=2"
-pydantic-core = "*"
-pygraphviz = "*"
-typer = "*"
-typing_extensions = {version = ">4", markers = "python_version < \"3.8\""}
-
-[[package]]
-name = "exceptiongroup"
-version = "1.1.2"
-description = "Backport of PEP 654 (exception groups)"
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"},
- {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"},
-]
-
-[package.extras]
-test = ["pytest (>=6)"]
-
-[[package]]
-name = "filelock"
-version = "3.12.2"
-description = "A platform independent file lock."
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"},
- {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"},
-]
-
-[package.extras]
-docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
-testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
-
-[[package]]
-name = "flake8"
-version = "3.9.2"
-description = "the modular source code checker: pep8 pyflakes and co"
-optional = true
-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 = "idna"
-version = "3.4"
-description = "Internationalized Domain Names in Applications (IDNA)"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
- {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
-]
-
-[[package]]
-name = "imagesize"
-version = "1.4.1"
-description = "Getting image size from png/jpeg/jpeg2000/gif file"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-files = [
- {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
- {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
-]
-
-[[package]]
-name = "importlib-metadata"
-version = "6.7.0"
-description = "Read metadata from Python packages"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"},
- {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"},
-]
-
-[package.dependencies]
-typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
-zipp = ">=0.5"
-
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-perf = ["ipython"]
-testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"]
-
-[[package]]
-name = "iniconfig"
-version = "2.0.0"
-description = "brain-dead simple config-ini parsing"
-optional = true
-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 = "jinja2"
-version = "3.1.2"
-description = "A very fast and expressive template engine."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
- {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
-]
-
-[package.dependencies]
-MarkupSafe = ">=2.0"
-
-[package.extras]
-i18n = ["Babel (>=2.7)"]
-
-[[package]]
-name = "markupsafe"
-version = "2.1.3"
-description = "Safely add untrusted strings to HTML/XML markup."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
- {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
-]
-
-[[package]]
-name = "mccabe"
-version = "0.6.1"
-description = "McCabe checker, plugin for flake8"
-optional = true
-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 = "packaging"
-version = "23.1"
-description = "Core utilities for Python packages"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
- {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
-]
-
-[[package]]
-name = "platformdirs"
-version = "3.8.1"
-description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "platformdirs-3.8.1-py3-none-any.whl", hash = "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c"},
- {file = "platformdirs-3.8.1.tar.gz", hash = "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528"},
-]
-
-[package.dependencies]
-typing-extensions = {version = ">=4.6.3", markers = "python_version < \"3.8\""}
-
-[package.extras]
-docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
-
-[[package]]
-name = "pluggy"
-version = "1.2.0"
-description = "plugin and hook calling mechanisms for python"
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"},
- {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"},
-]
-
-[package.dependencies]
-importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
-
-[[package]]
-name = "py"
-version = "1.11.0"
-description = "library with cross-python path, ini-parsing, io, code, log facilities"
-optional = true
-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"
-optional = true
-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 = "pydantic"
-version = "2.0.2"
-description = "Data validation using Python type hints"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "pydantic-2.0.2-py3-none-any.whl", hash = "sha256:f5581e0c79b2ec2fa25a9d30d766629811cdda022107fa73d022ab5578873ae3"},
- {file = "pydantic-2.0.2.tar.gz", hash = "sha256:b802f5245b8576315fe619e5989fd083448fa1258638ef9dac301ca60878396d"},
-]
-
-[package.dependencies]
-annotated-types = ">=0.4.0"
-pydantic-core = "2.1.2"
-typing-extensions = ">=4.6.1"
-
-[package.extras]
-email = ["email-validator (>=2.0.0)"]
-
-[[package]]
-name = "pydantic-core"
-version = "2.1.2"
-description = ""
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "pydantic_core-2.1.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:b4815720c266e832b20e27a7a5f3772bb09fdedb31a9a34bab7b49d98967ef5a"},
- {file = "pydantic_core-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8884a1dbfc5cb8c54b48446ca916d4577c1f4d901126091e4ab25d00194e065f"},
- {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74a33aa69d476773230396396afb8e11908f8dafdcfd422e746770599a3f889d"},
- {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af832edd384755826e494ffdcf1fdda86e4babc42a0b18d342943fb18181040e"},
- {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_armv7l.whl", hash = "sha256:017700236ea2e7afbef5d3803559c80bd8720306778ebd49268de7ce9972e83e"},
- {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:c2d00a96fdf26295c6f25eaf9e4a233f353146a73713cd97a5f5dc6090c3aef2"},
- {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_s390x.whl", hash = "sha256:2575664f0a559a7b951a518f6f34c23cab7190f34f8220b8c8218c4f403147ee"},
- {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24c3c9180a2d19d640bacc2d00f497a9a1f2abadb2a9ee201b56bb03bc5343bd"},
- {file = "pydantic_core-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:88a56f0f6d020b4d17641f4b4d1f9540a536d4146768d059c430e97bdb485fc1"},
- {file = "pydantic_core-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fa38a76e832743866aed6b715869757074b06357d1a260163ec26d84974245fe"},
- {file = "pydantic_core-2.1.2-cp310-none-win32.whl", hash = "sha256:a772c652603855d7180015849d483a1f539351a263bb9b81bfe85193a33ce124"},
- {file = "pydantic_core-2.1.2-cp310-none-win_amd64.whl", hash = "sha256:b4673d1f29487608d613ebcc5caa99ba15eb58450a7449fb6d800f29d90bebc1"},
- {file = "pydantic_core-2.1.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:76c9c55462740d728b344e3a087775846516c3fee31ec56e2075faa7cfcafcbf"},
- {file = "pydantic_core-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb854ec52e6e2e05b83d647695f4d913452fdd45a3dfa8233d7dab5967b3908f"},
- {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ac140d54da366672f6b91f9a1e8e2d4e7e72720143353501ae886d3fca03272"},
- {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:818f5cb1b209ab1295087c45717178f4bbbd2bd7eda421f7a119e7b9b736a3cb"},
- {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_armv7l.whl", hash = "sha256:db4564aea8b3cb6cf1e5f3fd80f1ced73a255d492396d1bd8abd688795b34d63"},
- {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:2ca2d2d5ab65fb40dd05259965006edcc62a9d9b30102737c0a6f45bcbd254e8"},
- {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_s390x.whl", hash = "sha256:7c7ad8958aadfbcd664078002246796ecd5566b64b22f6af4fd1bbcec6bf8f60"},
- {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:080a7af828388284a68ad7d3d3eac3bcfff6a580292849aff087e7d556ec42d4"},
- {file = "pydantic_core-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bad7029fb2251c1ac7d3acdd607e540d40d137a7d43a5e5acdcfdbd38db3fc0a"},
- {file = "pydantic_core-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1635a37137fafbc6ee0a8c879857e05b30b1aabaa927e653872b71f1501b1502"},
- {file = "pydantic_core-2.1.2-cp311-none-win32.whl", hash = "sha256:eb4301f009a44bb5db5edfe4e51a8175a4112b566baec07f4af8b1f8cb4649a2"},
- {file = "pydantic_core-2.1.2-cp311-none-win_amd64.whl", hash = "sha256:ebf583f4d9b52abd15cc59e5f6eeca7e3e9741c6ea62d8711c00ac3acb067875"},
- {file = "pydantic_core-2.1.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:90b06bb47e60173d24c7cb79670aa8dd6081797290353b9d3c66d3a23e88eb34"},
- {file = "pydantic_core-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e5761ce986ec709897b1b965fad9743f301500434bea3cbab2b6e662571580f"},
- {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b9f8bf1d7008a58fbb6eb334dc6e2f2905400cced8dadb46c4ca28f005a8562"},
- {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a014ee88980013d192a718cbb88e8cea20acd3afad69bc6d15672d05a49cdb6"},
- {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_armv7l.whl", hash = "sha256:8125152b03dd91deca5afe5b933a1994b39405adf6be2fe8dce3632319283f85"},
- {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_ppc64le.whl", hash = "sha256:dc737506b4a0ba2922a2626fc6d620ce50a46aebd0fe2fbcad1b93bbdd8c7e78"},
- {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_s390x.whl", hash = "sha256:bb471ea8650796060afc99909d9b75da583d317e52f660faf64c45f70b3bf1e2"},
- {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1fad38db1744d27061df516e59c5025b09b0a50a337c04e6eebdbddc18951bc"},
- {file = "pydantic_core-2.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:94d368af9e6563de6e7170a74710a2cbace7a1e9c8e507d9e3ac34c7065d7ae3"},
- {file = "pydantic_core-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bd95d223de5162811a7b36c73d48eac4fee03b075132f3a1b73c132ce157a60c"},
- {file = "pydantic_core-2.1.2-cp312-none-win32.whl", hash = "sha256:cd62f73830d4715bc643ae39de0bd4fb9c81d6d743530074da91e77a2cccfe67"},
- {file = "pydantic_core-2.1.2-cp312-none-win_amd64.whl", hash = "sha256:51968887d6bd1eaa7fc7759701ea8ccb470c04654beaa8ede6835b0533f206a9"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:7ff6bfe63f447a509ed4d368a7f4ba6a7abc03bc4744fc3fb30f2ffab73f3821"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:4e67f9b9dfda2e42b39459cbf99d319ccb90da151e35cead3521975b2afbf673"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b815a769b019dd96be6571096f246b74f63330547e9b30244c51b4a2eb0277fc"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aff436c23c68449601b3fba7075b4f37ef8fbb893c8c1ed3ef898f090332b1e"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_armv7l.whl", hash = "sha256:2ee3ae58f271851362f6c9b33e4c9f9e866557ec7d8c03dc091e9b5aa5566cec"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:cf92dccca8f66e987f6c4378700447f82b79e86407912ab1ee06b16b82f05120"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_s390x.whl", hash = "sha256:4663293a36a851a860b1299c50837914269fca127434911297dd39fea9667a01"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c917f7a41d9d09b8b024a5d65cf37e5588ccdb6e610d2df565fb7186b1f3b1c"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:06ae67547251135a1b3f8dd465797b13146295a3866bc12ddd73f7512787bb7c"},
- {file = "pydantic_core-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4938b32c09dbcecbeb652327cb4a449b1ef1a1bf6c8fc2c8241aa6b8f6d63b54"},
- {file = "pydantic_core-2.1.2-cp37-none-win32.whl", hash = "sha256:682ff9228c838018c47dfa89b3d84cca45f88cacde28807ab8296ec221862af4"},
- {file = "pydantic_core-2.1.2-cp37-none-win_amd64.whl", hash = "sha256:6e3bcb4a9bc209a61ea2aceb7433ce2ece32c7e670b0c06848bf870c9b3e7d87"},
- {file = "pydantic_core-2.1.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:2278ca0b0dfbcfb1e12fa58570916dc260dc72bee5e6e342debf5329d8204688"},
- {file = "pydantic_core-2.1.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87cff210af3258ca0c829e3ebc849d7981bfde23a99d6cb7a3c17a163b3dbad2"},
- {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7684b5fb906b37e940c5df3f57118f32e033af5e4770e5ae2ae56fbd2fe1a30a"},
- {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3747a4178139ebf3f19541285b2eb7c886890ca4eb7eec851578c02a13cc1385"},
- {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_armv7l.whl", hash = "sha256:e17056390068afd4583d88dcf4d4495764e4e2c7d756464468e0d21abcb8931e"},
- {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:c720e55cef609d50418bdfdfb5c44a76efc020ae7455505788d0113c54c7df55"},
- {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_s390x.whl", hash = "sha256:b59a64c367f350873c40a126ffe9184d903d2126c701380b4b55753484df5948"},
- {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68a2a767953c707d9575dcf14d8edee7930527ee0141a8bb612c22d1f1059f9a"},
- {file = "pydantic_core-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae46769d9a7138d58cd190441cac14ce954010a0081f28462ed916c8e55a4f"},
- {file = "pydantic_core-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fc909f62325a631e1401dd07dfc386986dbcac15f98c9ff2145d930678a9d25a"},
- {file = "pydantic_core-2.1.2-cp38-none-win32.whl", hash = "sha256:b4038869ba1d8fa33863b4b1286ab07e6075a641ae269b865f94d7e10b3e800e"},
- {file = "pydantic_core-2.1.2-cp38-none-win_amd64.whl", hash = "sha256:5948af62f323252d56acaec8ebfca5f15933f6b72f8dbe3bf21ee97b2d10e3f0"},
- {file = "pydantic_core-2.1.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:8e6ce261ccb9a986953c4dce070327e4954f9dd4cd214746dfc70efbc713b6a1"},
- {file = "pydantic_core-2.1.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d35d634d9d1ed280c87bc2a7a6217b8787eedc86f368fc2fa1c0c8c78f7d3c93"},
- {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be2e2812a43205728a06c9d0fd090432cd76a9bb5bff2bfcfdf8b0e27d51851"},
- {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0eb54b11cd4fe0c6404611eef77086ade03eb1457e92910bbb4f3479efa3f79"},
- {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_armv7l.whl", hash = "sha256:087ddbb754575618a8832ee4ab52fe7eb332f502e2a56088b53dbeb5c4efdf9f"},
- {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:b74906e01c7fc938ac889588ef438de812989817095c3c4904721f647d64a4d1"},
- {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_s390x.whl", hash = "sha256:60b7239206a2f61ad89c7518adfacb3ccd6662eaa07c5e437317aea2615a1f18"},
- {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:be3419204952bbe9b72b90008977379c52f99ae1c6e640488de4be783c345d71"},
- {file = "pydantic_core-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:804cf8f6a859620f8eb754c02f7770f61c3e9c519f8338c331d555b3d6976e3c"},
- {file = "pydantic_core-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cbba32fb14e199d0493c6b9c44870dab0a9c37af9f0f729068459d1849279ffd"},
- {file = "pydantic_core-2.1.2-cp39-none-win32.whl", hash = "sha256:6bf00f56a4468f5b03dadb672a5f1d24aea303d4ccffe8a0f548c9e36017edd3"},
- {file = "pydantic_core-2.1.2-cp39-none-win_amd64.whl", hash = "sha256:ac462a28218ea7d592c7ad51b517558f4ac6565a4e53db7a4811eeaf9c9660b0"},
- {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:047e782b9918f35ef534ced36f1fd2064f5581229b7a15e4d3177387a6b53134"},
- {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c0213891898fa5b404cf3edf4797e3ac7819a0708ea5473fc6432a2aa27c189"},
- {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0f481aaf0119f77b200e5a5e2799b3e14c015a317eaa948f42263908735cc9f"},
- {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15eb4cb543ed36f6a4f16e3bee7aa7ed1c3757be95a3f3bbb2b82b9887131e0f"},
- {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ef71e73a81a4cd7e87c93e8ff0170140fd93ba33b0f61e83da3f55f6e0a84fb4"},
- {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:840238c845b0f80777151fef0003088ab91c6f7b3467edaff4932b425c4e3c3f"},
- {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7648e48ba263ca0a8a2dc55a60a219c9133fb101ba52c89a14a29fb3d4322ca3"},
- {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:8eb4e2b71562375609c66a79f89acd4fe95c5cba23473d04952c8b14b6f908f5"},
- {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056afea59651c4e47ec6dadbb77ccae4742c059a3d12bc1c0e393d189d2970d"},
- {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46cd323371aa7e4053010ccdb94063a4273aa9e5dbe97f8a1147faa769de8d8d"},
- {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa39499625239da4ec960cf4fc66b023929b24cc77fb8520289cfdb3c1986428"},
- {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f5de2d4167fd4bc5ad205fb7297e25867b8e335ca08d64ed7a561d2955a2c32d"},
- {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:9a5fba9168fc27805553760fa8198db46eef83bf52b4e87ebbe1333b823d0e70"},
- {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e68a404fad8493989d6f07b7b9e066f1d2524d7cb64db2d4e9a84c920032c67f"},
- {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:1a5c4475510d1a9cc1458a26cfc21442223e52ce9adb640775c38739315d03c7"},
- {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0681472245ef182554208a25d16884c84f1c5a69f14e6169b88932e5da739a1c"},
- {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7fd334b40c5e13a97becfcaba314de0dcc6f7fe21ec8f992139bcc64700e9dc"},
- {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7345b1741bf66a9d8ed0ec291c3eabd534444e139e1ea6db5742ac9fd3be2530"},
- {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0855cf8b760fb40f97f0226cb527c8a94a2ab9d8179628beae20d6939aaeacb0"},
- {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d281a10837d98db997c0247f45d138522c91ce30cf3ae7a6afdb5e709707d360"},
- {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:82e09f27edab289187dd924d4d93f2a35f21aa969699b2504aa643da7fbfeff9"},
- {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:aa54902fa51f7d921ba80923cf1c7ff3dce796a7903300bd8824deb90e357744"},
- {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b9a5fc4058d64c9c826684dcdb43891c1b474a4a88dcf8dfc3e1fb5889496f8"},
- {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:817681d111cb65f07d46496eafec815f48e1aff37713b73135a0a9eb4d3610ab"},
- {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b5d37aedea5963f2097bddbcdb255483191646a52d40d8bb66d61c190fcac91"},
- {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f2de65752fff248319bcd3b29da24e205fa505607539fcd4acc4037355175b63"},
- {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a8b9c2cc4c5f8169b943d24be4bd1548fe81c016d704126e3a3124a2fc164885"},
- {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f7bcdf70c8b6e70be11c78d3c00b80a24cccfb408128f23e91ec3019bed1ecc1"},
- {file = "pydantic_core-2.1.2.tar.gz", hash = "sha256:d2c790f0d928b672484eac4f5696dd0b78f3d6d148a641ea196eb49c0875e30a"},
-]
-
-[package.dependencies]
-typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
-
-[[package]]
-name = "pydantic-settings"
-version = "2.0.1"
-description = "Settings management using Pydantic"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "pydantic_settings-2.0.1-py3-none-any.whl", hash = "sha256:579bbcbec3501e62bab73867b097ae10218201950e897463c98a182ffe7ed104"},
- {file = "pydantic_settings-2.0.1.tar.gz", hash = "sha256:f440ec7cfb6dc63f03226c47b0e7803750d1b66a49ed944ac23eb4f0c84f8722"},
-]
-
-[package.dependencies]
-pydantic = ">=2.0.1"
-python-dotenv = ">=0.21.0"
-
-[[package]]
-name = "pyflakes"
-version = "2.3.1"
-description = "passive checker of Python programs"
-optional = true
-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.15.1"
-description = "Pygments is a syntax highlighting package written in Python."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
- {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
-]
-
-[package.extras]
-plugins = ["importlib-metadata"]
-
-[[package]]
-name = "pygraphviz"
-version = "1.7"
-description = "Python interface to Graphviz"
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "pygraphviz-1.7.zip", hash = "sha256:a7bec6609f37cf1e64898c59f075afd659106cf9356c5f387cecaa2e0cdb2304"},
-]
-
-[[package]]
-name = "pytest"
-version = "7.4.0"
-description = "pytest: simple powerful testing with Python"
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"},
- {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
-importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
-iniconfig = "*"
-packaging = "*"
-pluggy = ">=0.12,<2.0"
-tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
-
-[package.extras]
-testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
-
-[[package]]
-name = "python-dotenv"
-version = "0.21.1"
-description = "Read key-value pairs from a .env file and set them as environment variables"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"},
- {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"},
-]
-
-[package.extras]
-cli = ["click (>=5.0)"]
-
-[[package]]
-name = "pytz"
-version = "2023.3"
-description = "World timezone definitions, modern and historical"
-optional = false
-python-versions = "*"
-files = [
- {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
- {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
-]
-
-[[package]]
-name = "requests"
-version = "2.31.0"
-description = "Python HTTP for Humans."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
- {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
-]
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = ">=2,<4"
-idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
-
-[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
-
-[[package]]
-name = "six"
-version = "1.16.0"
-description = "Python 2 and 3 compatibility utilities"
-optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
-files = [
- {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
- {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
-]
-
-[[package]]
-name = "snowballstemmer"
-version = "2.2.0"
-description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
-optional = false
-python-versions = "*"
-files = [
- {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
- {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
-]
-
-[[package]]
-name = "sphinx"
-version = "5.3.0"
-description = "Python documentation generator"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"},
- {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"},
-]
-
-[package.dependencies]
-alabaster = ">=0.7,<0.8"
-babel = ">=2.9"
-colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
-docutils = ">=0.14,<0.20"
-imagesize = ">=1.3"
-importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""}
-Jinja2 = ">=3.0"
-packaging = ">=21.0"
-Pygments = ">=2.12"
-requests = ">=2.5.0"
-snowballstemmer = ">=2.0"
-sphinxcontrib-applehelp = "*"
-sphinxcontrib-devhelp = "*"
-sphinxcontrib-htmlhelp = ">=2.0.0"
-sphinxcontrib-jsmath = "*"
-sphinxcontrib-qthelp = "*"
-sphinxcontrib-serializinghtml = ">=1.1.5"
-
-[package.extras]
-docs = ["sphinxcontrib-websupport"]
-lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"]
-test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
-
-[[package]]
-name = "sphinx-copybutton"
-version = "0.4.0"
-description = "Add a copy button to each of your code cells."
-optional = true
-python-versions = ">=3.6"
-files = [
- {file = "sphinx-copybutton-0.4.0.tar.gz", hash = "sha256:8daed13a87afd5013c3a9af3575cc4d5bec052075ccd3db243f895c07a689386"},
- {file = "sphinx_copybutton-0.4.0-py3-none-any.whl", hash = "sha256:4340d33c169dac6dd82dce2c83333412aa786a42dd01a81a8decac3b130dc8b0"},
-]
-
-[package.dependencies]
-sphinx = ">=1.8"
-
-[package.extras]
-code-style = ["pre-commit (==2.12.1)"]
-rtd = ["ipython", "sphinx", "sphinx-book-theme"]
-
-[[package]]
-name = "sphinx-rtd-theme"
-version = "1.2.2"
-description = "Read the Docs theme for Sphinx"
-optional = true
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
-files = [
- {file = "sphinx_rtd_theme-1.2.2-py2.py3-none-any.whl", hash = "sha256:6a7e7d8af34eb8fc57d52a09c6b6b9c46ff44aea5951bc831eeb9245378f3689"},
- {file = "sphinx_rtd_theme-1.2.2.tar.gz", hash = "sha256:01c5c5a72e2d025bd23d1f06c59a4831b06e6ce6c01fdd5ebfe9986c0a880fc7"},
-]
-
-[package.dependencies]
-docutils = "<0.19"
-sphinx = ">=1.6,<7"
-sphinxcontrib-jquery = ">=4,<5"
-
-[package.extras]
-dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"]
-
-[[package]]
-name = "sphinx-tabs"
-version = "3.4.1"
-description = "Tabbed views for Sphinx"
-optional = true
-python-versions = "~=3.7"
-files = [
- {file = "sphinx-tabs-3.4.1.tar.gz", hash = "sha256:d2a09f9e8316e400d57503f6df1c78005fdde220e5af589cc79d493159e1b832"},
- {file = "sphinx_tabs-3.4.1-py3-none-any.whl", hash = "sha256:7cea8942aeccc5d01a995789c01804b787334b55927f29b36ba16ed1e7cb27c6"},
-]
-
-[package.dependencies]
-docutils = ">=0.18.0,<0.19.0"
-pygments = "*"
-sphinx = "*"
-
-[package.extras]
-code-style = ["pre-commit (==2.13.0)"]
-testing = ["bs4", "coverage", "pygments", "pytest (>=7.1,<8)", "pytest-cov", "pytest-regressions", "rinohtype", "sphinx-testing"]
-
-[[package]]
-name = "sphinxcontrib-applehelp"
-version = "1.0.2"
-description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"},
- {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"},
-]
-
-[package.extras]
-lint = ["docutils-stubs", "flake8", "mypy"]
-test = ["pytest"]
-
-[[package]]
-name = "sphinxcontrib-devhelp"
-version = "1.0.2"
-description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
- {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
-]
-
-[package.extras]
-lint = ["docutils-stubs", "flake8", "mypy"]
-test = ["pytest"]
-
-[[package]]
-name = "sphinxcontrib-htmlhelp"
-version = "2.0.0"
-description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"},
- {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"},
-]
-
-[package.extras]
-lint = ["docutils-stubs", "flake8", "mypy"]
-test = ["html5lib", "pytest"]
-
-[[package]]
-name = "sphinxcontrib-jquery"
-version = "4.1"
-description = "Extension to include jQuery on newer Sphinx releases"
-optional = true
-python-versions = ">=2.7"
-files = [
- {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
- {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
-]
-
-[package.dependencies]
-Sphinx = ">=1.8"
-
-[[package]]
-name = "sphinxcontrib-jsmath"
-version = "1.0.1"
-description = "A sphinx extension which renders display math in HTML via JavaScript"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
- {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
-]
-
-[package.extras]
-test = ["flake8", "mypy", "pytest"]
-
-[[package]]
-name = "sphinxcontrib-mermaid"
-version = "0.7.1"
-description = "Mermaid diagrams in yours Sphinx powered docs"
-optional = true
-python-versions = "*"
-files = [
- {file = "sphinxcontrib-mermaid-0.7.1.tar.gz", hash = "sha256:aa8a40b50ec86ad12824b62180240ca52a9bda8424455d7eb252eae9aa5d293c"},
- {file = "sphinxcontrib_mermaid-0.7.1-py2.py3-none-any.whl", hash = "sha256:3e20de1937c30dfa807e446bf99983d73d0dd3dc5c6524addda59800fe928762"},
-]
-
-[[package]]
-name = "sphinxcontrib-qthelp"
-version = "1.0.3"
-description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
- {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
-]
-
-[package.extras]
-lint = ["docutils-stubs", "flake8", "mypy"]
-test = ["pytest"]
-
-[[package]]
-name = "sphinxcontrib-serializinghtml"
-version = "1.1.5"
-description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
- {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
-]
-
-[package.extras]
-lint = ["docutils-stubs", "flake8", "mypy"]
-test = ["pytest"]
-
-[[package]]
-name = "tomli"
-version = "2.0.1"
-description = "A lil' TOML parser"
-optional = true
-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"
-optional = true
-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"
-six = ">=1.14.0"
-tomli = {version = ">=2.0.1", markers = "python_version >= \"3.7\" and python_version < \"3.11\""}
-virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7"
-
-[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)", "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 = "typer"
-version = "0.9.0"
-description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
-optional = true
-python-versions = ">=3.6"
-files = [
- {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"},
- {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"},
-]
-
-[package.dependencies]
-click = ">=7.1.1,<9.0.0"
-typing-extensions = ">=3.7.4.3"
-
-[package.extras]
-all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
-dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
-doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"]
-test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
-
-[[package]]
-name = "typing-extensions"
-version = "4.7.1"
-description = "Backported and Experimental Type Hints for Python 3.7+"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
- {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
-]
-
-[[package]]
-name = "urllib3"
-version = "2.0.3"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"},
- {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"},
-]
-
-[package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
-socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
-zstd = ["zstandard (>=0.18.0)"]
-
-[[package]]
-name = "virtualenv"
-version = "20.23.1"
-description = "Virtual Python Environment builder"
-optional = true
-python-versions = ">=3.7"
-files = [
- {file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"},
- {file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"},
-]
-
-[package.dependencies]
-distlib = ">=0.3.6,<1"
-filelock = ">=3.12,<4"
-importlib-metadata = {version = ">=6.6", markers = "python_version < \"3.8\""}
-platformdirs = ">=3.5.1,<4"
-
-[package.extras]
-docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "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.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"]
-
-[[package]]
-name = "zipp"
-version = "3.15.0"
-description = "Backport of pathlib-compatible object wrapper for zip files"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"},
- {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"},
-]
-
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
-
-[extras]
-dev = ["coverage", "flake8", "pytest", "sphinx-copybutton", "sphinx-rtd-theme", "sphinx-tabs", "sphinxcontrib-mermaid", "tox"]
-docs = ["sphinx-copybutton", "sphinx-rtd-theme", "sphinx-tabs", "sphinxcontrib-mermaid"]
-erdantic = ["erdantic"]
-test = ["coverage", "pytest"]
-
-[metadata]
-lock-version = "2.0"
-python-versions = ">=3.7.2,<4.0.0"
-content-hash = "99229cd66d1bb086ad644c8942d36fdd86c9e9dac01da456c8f2f5ed135409d1"
From 0582abea682415c4128e8cd36cbd8404d5cc2ba0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Thu, 20 Jul 2023 17:33:01 +0200
Subject: [PATCH 11/42] Order of constraints is now alphabetical in v2.
---
tests/test_configuration_fields.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_configuration_fields.py b/tests/test_configuration_fields.py
index d3c53a54..276e80f4 100644
--- a/tests/test_configuration_fields.py
+++ b/tests/test_configuration_fields.py
@@ -214,8 +214,8 @@ def test_autodoc_pydantic_field_show_constraints_true(autodocument):
' Field.',
'',
' :Constraints:',
- ' - **minimum** = 0',
' - **maximum** = 100',
+ ' - **minimum** = 0',
''
]
From b7e02fd62a6c5f770c1c394f79cfb5cdbb97ba82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Thu, 20 Jul 2023 17:42:53 +0200
Subject: [PATCH 12/42] Fix ignore additional kwargs in Field for v2.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 7 +++++--
tests/test_configuration_fields.py | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index d1b4b5b7..1a68d24d 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -176,8 +176,11 @@ def get_constraints(self, field_name: str) -> Dict[str, Any]:
ignore = {"env_names", "env", "default", "title", "type"}
# ignore additional kwargs from pydantic `Field`, see #110
- extra_kwargs = self.get_property_from_field_info(field_name=field_name,
- property_name="extra")
+ extra_kwargs = self.get_property_from_field_info(
+ field_name=field_name,
+ property_name="json_schema_extra"
+ )
+
if extra_kwargs:
ignore = ignore.union(extra_kwargs.keys())
diff --git a/tests/test_configuration_fields.py b/tests/test_configuration_fields.py
index 276e80f4..ec288f48 100644
--- a/tests/test_configuration_fields.py
+++ b/tests/test_configuration_fields.py
@@ -261,8 +261,8 @@ def test_autodoc_pydantic_field_show_constraints_ignore_extra_kwargs(
' Field.',
'',
' :Constraints:',
- ' - **minimum** = 0',
' - **maximum** = 100',
+ ' - **minimum** = 0',
''
]
From c905902d225449a04d402cdb1cbba8c1f628f251 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Thu, 20 Jul 2023 17:56:11 +0200
Subject: [PATCH 13/42] Adapt to changed behavior of optional/required field
values.
`field1 : Optional[int]` is no longer optional but required in v2.
---
tests/roots/test-base/target/configuration.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index 1a0fcb3f..4b6bc801 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -425,7 +425,7 @@ class FieldShowRequired(BaseModel):
class FieldShowRequiredNot(BaseModel):
"""FieldShowRequiredNot"""
- field1: Optional[int]
+ field1: Optional[int] = None
"""field1"""
field2: Optional[int] = 0
From 2233774315e66f61ff961de67a4ae3588ad8613d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 14:53:01 +0200
Subject: [PATCH 14/42] Add `Optional[int]` as required field in v2.
---
tests/roots/test-base/target/configuration.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index 4b6bc801..84ba5ac5 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -420,6 +420,8 @@ class FieldShowRequired(BaseModel):
"""field2"""
field3: int = Field(default=...)
"""field3"""
+ field4: Optional[int]
+ """field4"""
class FieldShowRequiredNot(BaseModel):
From 9a90075f3cab7c7e70c7c3d76169e4f266ec88de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 14:53:44 +0200
Subject: [PATCH 15/42] Change `None` to `PydanticUndefined` to due changed
semantics in v2.
---
tests/test_configuration_fields.py | 44 +++++++++++++++++++++---------
1 file changed, 31 insertions(+), 13 deletions(-)
diff --git a/tests/test_configuration_fields.py b/tests/test_configuration_fields.py
index ec288f48..3626bda7 100644
--- a/tests/test_configuration_fields.py
+++ b/tests/test_configuration_fields.py
@@ -741,20 +741,28 @@ def test_autodoc_pydantic_field_show_required_true_not(expected, autodocument):
assert result == actual
-@pytest.mark.parametrize("field", ["field1", "field2", "field3"])
-def test_autodoc_pydantic_field_show_required_false(field, autodocument):
+@pytest.mark.parametrize("field_values", (("field1", "int"),
+ ("field2", "int"),
+ ("field3", "int"),
+ ("field4", "~typing.Optional[int]")))
+def test_autodoc_pydantic_field_show_required_false(field_values,
+ autodocument):
+ """Ensure that the required marker is not shown if deactivated.
+
+ """
+ field_name, type_value = field_values
result = [
'',
- f'.. py:pydantic_field:: FieldShowRequired.{field}',
+ f'.. py:pydantic_field:: FieldShowRequired.{field_name}',
' :module: target.configuration',
- ' :type: int',
+ f' :type: {type_value}',
'',
- f' {field}',
+ f' {field_name}',
'',
]
kwargs = dict(
- object_path=f'target.configuration.FieldShowRequired.{field}',
+ object_path=f'target.configuration.FieldShowRequired.{field_name}',
**KWARGS
)
@@ -776,22 +784,32 @@ def test_autodoc_pydantic_field_show_required_false(field, autodocument):
assert result == actual
-@pytest.mark.parametrize("field", ["field1", "field2", "field3"])
+@pytest.mark.parametrize("field_values", (("field1", "int"),
+ ("field2", "int"),
+ ("field3", "int"),
+ ("field4", "~typing.Optional[int]")))
def test_autodoc_pydantic_field_show_required_false_show_default_true(
- field, autodocument):
+ field_values, autodocument):
+ """Ensure that the required marker is not shown while the default value
+ is present.
+
+ """
+
+ field_name, type_value = field_values
+
result = [
'',
- f'.. py:pydantic_field:: FieldShowRequired.{field}',
+ f'.. py:pydantic_field:: FieldShowRequired.{field_name}',
' :module: target.configuration',
- ' :type: int',
- f' :value: None',
+ f' :type: {type_value}',
+ f' :value: PydanticUndefined',
'',
- f' {field}',
+ f' {field_name}',
'',
]
kwargs = dict(
- object_path=f'target.configuration.FieldShowRequired.{field}',
+ object_path=f'target.configuration.FieldShowRequired.{field_name}',
**KWARGS
)
From 869c382b4ab31674d0b7f92292e72b015d27e848 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 14:59:35 +0200
Subject: [PATCH 16/42] Respect order of parameters in `ConfigDict`.
---
tests/roots/test-base/target/configuration.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index 84ba5ac5..c0df99bc 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -11,7 +11,7 @@ class ModelShowJson(BaseModel):
class ModelShowConfigSummary(BaseModel):
"""ModelShowConfigSummary."""
- model_config = ConfigDict(title="FooBar", frozen=False)
+ model_config = ConfigDict(frozen=True, title="FooBar")
class ModelShowValidatorsSummary(BaseModel):
From 0e744dc284dfa49b8146c7b5250f3aa3c8ce0529 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 15:22:22 +0200
Subject: [PATCH 17/42] Adjust tests to account for removed config member.
---
tests/test_configuration_model.py | 124 +-----------------------------
1 file changed, 2 insertions(+), 122 deletions(-)
diff --git a/tests/test_configuration_model.py b/tests/test_configuration_model.py
index 627e9f8e..646bc5bb 100644
--- a/tests/test_configuration_model.py
+++ b/tests/test_configuration_model.py
@@ -13,8 +13,7 @@
SETTING_MEMBER_ORDER = {
"autodoc_pydantic_model_members": True,
- "autodoc_pydantic_model_show_validator_members": True,
- "autodoc_pydantic_model_show_config_member": True}
+ "autodoc_pydantic_model_show_validator_members": True}
def test_autodoc_pydantic_model_show_json_true(autodocument):
@@ -845,14 +844,7 @@ def test_autodoc_pydantic_model_member_order_groupwise(autodocument):
' :classmethod:',
'',
' Check.',
- '',
- '',
- ' .. py:pydantic_config:: ModelMemberOrder.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
- ''
- ]
+ '']
# explict global
actual = autodocument(
@@ -896,12 +888,6 @@ def test_autodoc_pydantic_model_member_order_bysource(autodocument):
' Check.',
'',
'',
- ' .. py:pydantic_config:: ModelMemberOrder.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
- '',
- '',
' .. py:pydantic_field:: ModelMemberOrder.field',
' :module: target.configuration',
' :type: int',
@@ -945,12 +931,6 @@ def test_autodoc_pydantic_model_member_order_alphabetical(autodocument):
' ModelMemberOrder.',
'',
'',
- ' .. py:pydantic_config:: ModelMemberOrder.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
- '',
- '',
' .. py:pydantic_validator:: ModelMemberOrder.dummy',
' :module: target.configuration',
' :classmethod:',
@@ -1082,106 +1062,6 @@ def test_autodoc_pydantic_model_show_validator_members_false(autodocument):
assert result == actual
-def test_autodoc_pydantic_model_show_config_members_true(autodocument):
- kwargs = dict(object_path='target.configuration.ModelShowConfigMember',
- **KWARGS)
- enable = {"autodoc_pydantic_model_members": True,
- "autodoc_pydantic_config_members": True}
-
- result = [
- '',
- ".. py:pydantic_model:: ModelShowConfigMember",
- ' :module: target.configuration',
- '',
- ' ModelShowConfigMember.',
- '',
- '',
- ' .. py:pydantic_field:: ModelShowConfigMember.field',
- ' :module: target.configuration',
- ' :type: int',
- '',
- ' Field.',
- '',
- '',
- ' .. py:pydantic_config:: ModelShowConfigMember.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
- '',
- '',
- ' .. py:attribute:: ModelShowConfigMember.Config.frozen',
- ' :module: target.configuration',
- ' :value: True',
- '']
-
- # explict global
- actual = autodocument(
- options_app={"autodoc_pydantic_model_show_config_member": True,
- **enable},
- **kwargs)
- assert result == actual
-
- # explict local
- actual = autodocument(
- options_app=enable,
- options_doc={"model-show-config-member": True},
- **kwargs)
- assert result == actual
-
- # explicit local overwrite global
- actual = autodocument(
- options_app={"autodoc_pydantic_model_show_config_member": False,
- **enable},
- options_doc={"model-show-config-member": True},
- **kwargs)
- assert result == actual
-
-
-def test_autodoc_pydantic_model_show_config_members_false(autodocument):
- kwargs = dict(object_path='target.configuration.ModelShowConfigMember',
- **KWARGS)
- enable = {"autodoc_pydantic_model_members": True,
- "autodoc_pydantic_config_members": True}
-
- result = [
- '',
- ".. py:pydantic_model:: ModelShowConfigMember",
- ' :module: target.configuration',
- '',
- ' ModelShowConfigMember.',
- '',
- '',
- ' .. py:pydantic_field:: ModelShowConfigMember.field',
- ' :module: target.configuration',
- ' :type: int',
- '',
- ' Field.',
- '',
- ]
-
- # explict global
- actual = autodocument(
- options_app={"autodoc_pydantic_model_show_config_member": False,
- **enable},
- **kwargs)
- assert result == actual
-
- # explict local
- actual = autodocument(
- options_app=enable,
- options_doc={"model-show-config-member": False},
- **kwargs)
- assert result == actual
-
- # explicit local overwrite global
- actual = autodocument(
- options_app={"autodoc_pydantic_model_show_config_member": True,
- **enable},
- options_doc={"model-show-config-member": False},
- **kwargs)
- assert result == actual
-
-
def test_autodoc_pydantic_model_signature_prefix(autodocument, parse_rst):
"""Tests pydantic_model directive.
From a860b596cfbfe9292efc9e7e1f0977febc3b6228 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 15:24:43 +0200
Subject: [PATCH 18/42] Adjust docs to account for removed config documenter.
---
docs/source/users/configuration.rst | 30 -----------------------------
docs/source/users/usage.rst | 30 -----------------------------
2 files changed, 60 deletions(-)
diff --git a/docs/source/users/configuration.rst b/docs/source/users/configuration.rst
index ab8ae050..e0fc10f7 100644
--- a/docs/source/users/configuration.rst
+++ b/docs/source/users/configuration.rst
@@ -638,36 +638,6 @@ Validators
Define the signature prefix for pydantic validator.
-------------
-Config Class
-------------
-
-.. config_description:: autopydantic_model
- :title: Show Members
- :path: target.configuration.ConfigMembers
- :confpy: autodoc_pydantic_config_members
- :directive_option: members
- :enable: model-show-config-member, undoc-members
- :values: True, False
-
- Show members. By default, members are hidden for standard :code:`auto`
- directives. For pydantic class config, this is overwritten if enabled.
-
-.. note::
-
- By default, all undocumented members are shown for the `Config` class.
- The directive option :code:`:undoc-members:` is added automatically.
-
-
-.. config_description:: autopydantic_config
- :title: Signature Prefix
- :path: target.configuration.ConfigSignaturePrefix.Config
- :confpy: autodoc_pydantic_config_signature_prefix
- :directive_option: config-signature-prefix
- :values: model, class, foobar
-
- Define the signature prefix for config class.
-
-------
General
diff --git a/docs/source/users/usage.rst b/docs/source/users/usage.rst
index 2f9b6a52..3303c3ee 100644
--- a/docs/source/users/usage.rst
+++ b/docs/source/users/usage.rst
@@ -227,33 +227,3 @@ from its corresponding pydantic model/settings but it is still possible.
To overwrite global defaults, the following directive options can be supplied:
.. documenter_config_toc:: validator
-
-.. _autopydantic_config:
-
-autopydantic_config
--------------------
-
-Very rarely, you may want to document a pydantic config class without the corresponding
-pydantic model/setting. However, technically it's possible since the :code:`autopydantic_config`
-directive is used by the :code:`autopydantic_model` and :code:`autopydantic_settings`.
-
-.. tabs::
-
- .. tab:: reST
-
- .. code-block:: rest
-
- .. autopydantic_config:: target.usage_setting.ExampleSettings.Config
-
- .. tab:: *rendered output*
-
- .. autopydantic_config:: target.usage_setting.ExampleSettings.Config
- :noindex:
-
- .. tab:: python
-
- .. autocodeblock:: target.usage_setting
-
-To overwrite global defaults, the following directive options can be supplied:
-
-.. documenter_config_toc:: config
From 2fb22f9343bc42ec84be44a1d167dc543315055d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 18:04:35 +0200
Subject: [PATCH 19/42] Adjust to modified bound->unbound reused validators in
v2.
---
.../target/configuration_model_hide_reused_validator.py | 5 ++---
tests/test_configuration_model.py | 1 -
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/tests/roots/test-base/target/configuration_model_hide_reused_validator.py b/tests/roots/test-base/target/configuration_model_hide_reused_validator.py
index e217024b..120d0470 100644
--- a/tests/roots/test-base/target/configuration_model_hide_reused_validator.py
+++ b/tests/roots/test-base/target/configuration_model_hide_reused_validator.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator
+from pydantic import BaseModel, field_validator
def validation(name):
@@ -10,6 +10,5 @@ class ModelOne(BaseModel):
name: str
"""Name"""
- normalize_name = validator('name', allow_reuse=True)(validation)
+ normalize_name = field_validator('name')(validation)
"""Reused validator class method."""
-
diff --git a/tests/test_configuration_model.py b/tests/test_configuration_model.py
index 646bc5bb..3213e991 100644
--- a/tests/test_configuration_model.py
+++ b/tests/test_configuration_model.py
@@ -1405,7 +1405,6 @@ def test_autodoc_pydantic_model_hide_reused_validator_false(autodocument):
'',
' .. py:method:: ModelOne.normalize_name()',
' :module: target.configuration_model_hide_reused_validator',
- ' :classmethod:',
'',
' Reused validator class method.',
''
From a458bdef0999cc8515530dd1af53424c0540b73b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 18:06:06 +0200
Subject: [PATCH 20/42] Simplify `ValidatorAdapter` & `ValidatorInspector`.
Simplify reused validators retrieval.
---
.../directives/autodocumenters.py | 2 +-
sphinxcontrib/autodoc_pydantic/inspection.py | 55 ++++---------------
2 files changed, 12 insertions(+), 45 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
index 50a3045f..bf6fd0fd 100644
--- a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
+++ b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
@@ -254,7 +254,7 @@ def hide_reused_validators(self):
"""
validators = self.pydantic.inspect.validators
- reused_validators = validators.get_reused_validator_method_names()
+ reused_validators = validators.get_reused_validators_names()
exclude_members = self.options["exclude-members"]
exclude_members.update(reused_validators)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index 1a68d24d..1d1107b2 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -69,18 +69,6 @@ def object_path(self) -> str:
return f"{self.func.__module__}.{self.func.__qualname__}"
- def is_member(self, model: Type) -> bool:
- """Check if `self.func` is a member of provided `model` class or its
- base classes. This can be used to identify functions that are reused
- as validators.
-
- """
-
- if self.class_name is None:
- return False
-
- bases = (f"{x.__module__}.{x.__qualname__}" for x in model.__mro__)
- return f"{self.module}.{self.class_name}" in bases
def __hash__(self):
return id(f"{self}")
@@ -266,11 +254,6 @@ class ValidatorInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
- self.attribute: Dict[str, Decorator[ValidatorDecoratorInfo]] = dict(
- **self.model.__pydantic_decorators__.validators,
- **self.model.__pydantic_decorators__.field_validators,
- **self.model.__pydantic_decorators__.root_validators
- )
@property
def values(self) -> Set[ValidatorAdapter]:
@@ -282,31 +265,15 @@ def values(self) -> Set[ValidatorAdapter]:
flattened = itertools.chain.from_iterable(all_validators)
return set(flattened)
- def get_reused_validator_method_names(self) -> List[str]:
- """Identify all bound methods names that are used to generate reused
- validators as placeholders.
-
- """
-
- reused_validators = self.get_reused_validators()
- if not reused_validators:
- return []
-
- validator_set = set([x.func for x in reused_validators])
- bound_methods = {key: value
- for key, value in vars(self.model).items()
- if inspect.ismethod(getattr(self.model, key))}
-
- return [key for key, value in bound_methods.items()
- if value.__func__ in validator_set]
-
- def get_reused_validators(self) -> List[ValidatorAdapter]:
+ def get_reused_validators_names(self) -> List[str]:
"""Identify all reused validators.
"""
- return [validator for validator in self.values
- if not validator.is_member(self.model)]
+ validators = self.model.__pydantic_decorators__.field_validators
+ return [x.cls_var_name
+ for x in validators.values()
+ if inspect.isfunction(x.func)]
@property
def names(self) -> Set[str]:
@@ -321,8 +288,7 @@ def __bool__(self):
"""
- return bool(self.attribute)
-
+ return bool(self.values)
# TODO: remove (made useless by model.model_config in pydantic v2).
class ConfigInspector(BaseInspectionComposite):
@@ -531,18 +497,19 @@ def get_field_validator_mapping(self) -> Dict[str, List[ValidatorAdapter]]:
"""
mapping = defaultdict(list)
- model_decorators = self.model.__pydantic_decorators__
+ decorators = self.model.__pydantic_decorators__
# standard validators
- for validator in model_decorators.validators.values():
+ for validator in decorators.validators.values():
for field in validator.info.fields:
mapping[field].append(ValidatorAdapter(func=validator.func))
- for validator in model_decorators.field_validators.values():
+
+ for validator in decorators.field_validators.values():
for field in validator.info.fields:
mapping[field].append(ValidatorAdapter(func=validator.func))
# root validators
- for validator in model_decorators.root_validators.values():
+ for validator in decorators.root_validators.values():
is_pre = validator.info.mode == "before"
mapping["*"].append(ValidatorAdapter(func=validator.func,
root_pre=is_pre))
From 3584ae07d935e04f4191f234c4cb48fd49ed8584 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 18:08:33 +0200
Subject: [PATCH 21/42] `ConfigInspector` remains mandatory for
`ModelDocumenter`.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index 1d1107b2..3f82519b 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -69,7 +69,6 @@ def object_path(self) -> str:
return f"{self.func.__module__}.{self.func.__qualname__}"
-
def __hash__(self):
return id(f"{self}")
@@ -290,7 +289,7 @@ def __bool__(self):
return bool(self.values)
-# TODO: remove (made useless by model.model_config in pydantic v2).
+
class ConfigInspector(BaseInspectionComposite):
"""Provide namespace for inspection methods for config class of pydantic
models.
@@ -418,7 +417,6 @@ def sanitized(self) -> Dict:
reordered_schema.update(schema)
return reordered_schema
-
def create_sanitized_model(self) -> BaseModel:
"""Generates a new pydantic model from the original one while
substituting invalid fields with typevars.
From 998d9d7581339f89148d6911b81b69c1af38c360 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 21:53:11 +0200
Subject: [PATCH 22/42] Adjust for removed config documenter.
---
...guration_settings_hide_reused_validator.py | 4 +-
tests/test_configuration_settings.py | 119 ------------------
2 files changed, 2 insertions(+), 121 deletions(-)
diff --git a/tests/roots/test-base/target/configuration_settings_hide_reused_validator.py b/tests/roots/test-base/target/configuration_settings_hide_reused_validator.py
index 3556f6db..67e49354 100644
--- a/tests/roots/test-base/target/configuration_settings_hide_reused_validator.py
+++ b/tests/roots/test-base/target/configuration_settings_hide_reused_validator.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator
+from pydantic import BaseModel, field_validator
def validation(name):
@@ -10,6 +10,6 @@ class SettingOne(BaseModel):
name: str
"""Name"""
- normalize_name = validator('name', allow_reuse=True)(validation)
+ normalize_name = field_validator('name')(validation)
"""Reused validator class method."""
diff --git a/tests/test_configuration_settings.py b/tests/test_configuration_settings.py
index 03b41e6d..5a900cb6 100644
--- a/tests/test_configuration_settings.py
+++ b/tests/test_configuration_settings.py
@@ -664,12 +664,6 @@ def test_autodoc_pydantic_settings_member_order_groupwise(autodocument):
' :classmethod:',
'',
' Check.',
- '',
- '',
- ' .. py:pydantic_config:: SettingsMemberOrder.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
''
]
@@ -715,12 +709,6 @@ def test_autodoc_pydantic_settings_member_order_bysource(autodocument):
' Check.',
'',
'',
- ' .. py:pydantic_config:: SettingsMemberOrder.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
- '',
- '',
' .. py:pydantic_field:: SettingsMemberOrder.field',
' :module: target.configuration',
' :type: int',
@@ -764,12 +752,6 @@ def test_autodoc_pydantic_settings_member_order_alphabetical(autodocument):
' SettingsMemberOrder.',
'',
'',
- ' .. py:pydantic_config:: SettingsMemberOrder.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
- '',
- '',
' .. py:pydantic_validator:: SettingsMemberOrder.dummy',
' :module: target.configuration',
' :classmethod:',
@@ -901,106 +883,6 @@ def test_autodoc_pydantic_settings_show_validator_members_false(autodocument):
assert result == actual
-def test_autodoc_pydantic_settings_show_config_members_true(autodocument):
- kwargs = dict(object_path='target.configuration.SettingsShowConfigMember',
- **KWARGS)
- enable = {"autodoc_pydantic_settings_members": True,
- "autodoc_pydantic_config_members": True}
-
- result = [
- '',
- ".. py:pydantic_settings:: SettingsShowConfigMember",
- ' :module: target.configuration',
- '',
- ' SettingsShowConfigMember.',
- '',
- '',
- ' .. py:pydantic_field:: SettingsShowConfigMember.field',
- ' :module: target.configuration',
- ' :type: int',
- '',
- ' Field.',
- '',
- '',
- ' .. py:pydantic_config:: SettingsShowConfigMember.Config()',
- ' :module: target.configuration',
- '',
- ' Config.',
- '',
- '',
- ' .. py:attribute:: SettingsShowConfigMember.Config.frozen',
- ' :module: target.configuration',
- ' :value: True',
- '']
-
- # explict global
- actual = autodocument(
- options_app={"autodoc_pydantic_settings_show_config_member": True,
- **enable},
- **kwargs)
- assert result == actual
-
- # explict local
- actual = autodocument(
- options_app=enable,
- options_doc={"settings-show-config-member": True},
- **kwargs)
- assert result == actual
-
- # explicit local overwrite global
- actual = autodocument(
- options_app={"autodoc_pydantic_settings_show_config_member": False,
- **enable},
- options_doc={"settings-show-config-member": True},
- **kwargs)
- assert result == actual
-
-
-def test_autodoc_pydantic_settings_show_config_members_false(autodocument):
- kwargs = dict(object_path='target.configuration.SettingsShowConfigMember',
- **KWARGS)
- enable = {"autodoc_pydantic_settings_members": True,
- "autodoc_pydantic_config_members": True}
-
- result = [
- '',
- ".. py:pydantic_settings:: SettingsShowConfigMember",
- ' :module: target.configuration',
- '',
- ' SettingsShowConfigMember.',
- '',
- '',
- ' .. py:pydantic_field:: SettingsShowConfigMember.field',
- ' :module: target.configuration',
- ' :type: int',
- '',
- ' Field.',
- '',
- ]
-
- # explict global
- actual = autodocument(
- options_app={"autodoc_pydantic_settings_show_config_member": False,
- **enable},
- **kwargs)
- assert result == actual
-
- # explict local
- actual = autodocument(
- options_app=enable,
- options_doc={"settings-show-config-member": False},
- **kwargs)
- assert result == actual
-
- # explicit local overwrite global
- actual = autodocument(
- options_app={"autodoc_pydantic_settings_show_config_member": True,
- **enable},
- options_doc={"settings-show-config-member": False},
- **kwargs)
- assert result == actual
-
-
def test_autodoc_pydantic_settings_signature_prefix(autodocument, parse_rst):
"""Tests pydantic_settings directive.
@@ -1192,7 +1074,6 @@ def test_autodoc_pydantic_settings_hide_reused_validator_false(autodocument):
'',
' .. py:method:: SettingOne.normalize_name()',
' :module: target.configuration_settings_hide_reused_validator',
- ' :classmethod:',
'',
' Reused validator class method.',
''
From e5774ce881f4c85c780be54c9083a8687a065bf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 22:13:33 +0200
Subject: [PATCH 23/42] Replace `root_validators` with `model_validators` in
v2.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 2 +-
tests/roots/test-base/target/configuration.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index 3f82519b..af3964d7 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -507,7 +507,7 @@ def get_field_validator_mapping(self) -> Dict[str, List[ValidatorAdapter]]:
mapping[field].append(ValidatorAdapter(func=validator.func))
# root validators
- for validator in decorators.root_validators.values():
+ for validator in decorators.model_validators.values():
is_pre = validator.info.mode == "before"
mapping["*"].append(ValidatorAdapter(func=validator.func,
root_pre=is_pre))
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index c0df99bc..7d14a45f 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -337,7 +337,7 @@ def check(cls, v):
"""Check."""
return v
- @root_validator(skip_on_failure=True)
+ @model_validator(mode="after")
def check_root(cls, values):
"""Check root."""
return values
From 62ba8a0968696aae2a74d41d8faffe54b492eeca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Fri, 21 Jul 2023 22:16:58 +0200
Subject: [PATCH 24/42] Remove config directive tests in v2.
---
tests/test_directives.py | 102 ---------------------------------------
1 file changed, 102 deletions(-)
diff --git a/tests/test_directives.py b/tests/test_directives.py
index 3253a0e1..ffd46297 100644
--- a/tests/test_directives.py
+++ b/tests/test_directives.py
@@ -208,83 +208,6 @@ def test_example_model_with_field_and_validator(parse_rst):
assert_node(doctree, output_nodes)
-def test_example_model_with_config(parse_rst):
- """Tests plain pydantic model config class.
-
- """
-
- input_rst = [
- '',
- '.. py:pydantic_model:: ModelWithConfig',
- ' :module: target.examples',
- '',
- ' Model with Config.',
- '',
- ' :Config:',
- ' - **frozen**: *bool = True*',
- '',
- ' .. py:pydantic_config:: ModelWithConfig.Config()',
- ' :module: target.examples',
- '',
- ' With Doc String.',
- '',
- '',
- ' .. py:attribute:: ModelWithConfig.Config.frozen',
- ' :module: target.examples',
- ' :value: True',
- '',
- ' FooBar.',
- '']
-
- default_value = desc_annotation_default_value("True")
- prefix_model = desc_annotation_directive_prefix("model")
- config_class_node = [
- desc, (
- [desc_signature, ([desc_annotation, prefix_model],
- [desc_name, "Config"])],
- [desc_content, ([paragraph, "With Doc String."],
- index,
- [desc, (
- [desc_signature, ([desc_name, "frozen"],
- default_value)],
- [desc_content, ([paragraph, "FooBar."])])
- ]
- )])
- ]
-
- config_node = [
- field_list, ([
- field, ([field_name, "Config"],
- [field_body, ([
- bullet_list, ([
- list_item, ([
- paragraph, ([strong, "frozen"],
- ": ",
- [emphasis, "bool = True"])
- ])
- ])
- ])])
- ])
- ]
-
- prefix_model = desc_annotation_directive_prefix("pydantic model")
- output_nodes = (
- index,
- [desc, ([desc_signature, ([desc_annotation, prefix_model],
- [desc_addname, "target.examples."],
- [desc_name, "ModelWithConfig"])],
- [desc_content, ([paragraph, "Model with Config."],
- config_node,
- index,
- config_class_node)
- ])
- ]
- )
-
- doctree = parse_rst(input_rst)
- assert_node(doctree, output_nodes)
-
-
def test_pydantic_model(parse_rst):
"""Tests pydantic_model directive.
@@ -335,31 +258,6 @@ def test_pydantic_settings(parse_rst):
assert_node(doctree, output_nodes)
-def test_pydantic_config(parse_rst):
- """Tests pydantic_config_class directive.
-
- """
-
- input_rst = ['.. py:pydantic_config:: Model.Config',
- ' :module: target.examples',
- '',
- ' Config Plain.',
- '']
-
- prefix_model = desc_annotation_directive_prefix("model")
- output_nodes = (
- index,
- [desc, ([desc_signature, ([desc_annotation, prefix_model],
- [desc_addname, "Model."],
- [desc_name, "Config"])],
- [desc_content, ([paragraph, "Config Plain."])])
- ]
- )
-
- doctree = parse_rst(input_rst)
- assert_node(doctree, output_nodes)
-
-
def test_pydantic_validator(parse_rst):
"""Tests pydantic_validator directive.
From aede5716170992471e6052f5c4a177e090efee8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 11:42:48 +0200
Subject: [PATCH 25/42] Support fetching constraints in v2.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 72 ++++++---
tests/roots/test-base/target/configuration.py | 19 ++-
tests/test_configuration_fields.py | 147 +++++++++++++++++-
3 files changed, 213 insertions(+), 25 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index af3964d7..76a27d5a 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -11,12 +11,9 @@
from typing import NamedTuple, List, Dict, Any, Set, TypeVar, Type, Callable, \
Optional, Union
-from pydantic import BaseModel, create_model, ConfigDict
+from pydantic import BaseModel, create_model, ConfigDict, Strict
from pydantic.fields import FieldInfo
-from pydantic.type_adapter import TypeAdapter
-from pydantic._internal._decorators import Decorator, ValidatorDecoratorInfo
from pydantic_settings import SettingsConfigDict
-from pydantic_core import SchemaValidator
from sphinx.addnodes import desc_signature
ASTERISK_FIELD_NAME = "all fields"
@@ -111,7 +108,6 @@ class FieldInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
# json schema can reliably be created only at model level
- self.model_json_schema = self.model.model_json_schema()
self.attribute = self.model.model_fields
@property
@@ -154,25 +150,65 @@ def get_property_from_field_info(self,
field = self.get(field_name)
return getattr(field, property_name, None)
- def get_constraints(self, field_name: str) -> Dict[str, Any]:
- """Get constraints for given `field_name`.
+ def get_constraint_items(self, field_name: str) -> Dict[str, str]:
+ """Extract all possible constraints along with their default values
+ from a fields meta attribute.
+
+ """
+
+ metadata = self.model.model_fields[field_name].metadata
+ available = [meta for meta in metadata if meta is not None]
+
+ return {key: getattr(meta, key)
+ for meta in available
+ for key, value in self._get_meta_items(meta).items()}
+
+ @staticmethod
+ def _get_meta_items(meta_class: Any) -> Dict[str, str]:
+ """Helper method to extract constraint names and values from different
+ pydantic Metadata objects such as `pydantic.types.Strict`.
+
+ """
+
+ try:
+ return meta_class.__dataclass_fields__
+ except AttributeError:
+ return meta_class.__dict__
+
+ def get_given_constraint_keys(self, field_name: str) -> Set[str]:
+ """Retrieves all schema attribute keys that have been set.
+ This information is relevant to distinguish given values that are
+ equivalent to their default values. Otherwise, there is no chance
+ to determine if a constraint was actually given by the user or set as
+ a default value.
+
+ Note: Accessing private attributes with many levels of nesting is far
+ from being desired but currently there is no proper solution around
+ this. Accessing the `properties` via the `model_schema_json` may fail
+ in cases where fields are not serializable.
"""
- constraints = self.model_json_schema["properties"].get(field_name, {})
- ignore = {"env_names", "env", "default", "title", "type"}
+ definition = self.model.__pydantic_core_schema__["definitions"][0]
+ schema = definition["schema"]["fields"][field_name]["schema"]
+
+ # account for yet another level on model-field
+ if "schema" in schema:
+ schema = schema["schema"]
- # ignore additional kwargs from pydantic `Field`, see #110
- extra_kwargs = self.get_property_from_field_info(
- field_name=field_name,
- property_name="json_schema_extra"
- )
+ return set(schema.keys())
+
+ def get_constraints(self, field_name: str) -> Dict[str, Any]:
+ """Get constraints for given `field_name`.
+
+ """
- if extra_kwargs:
- ignore = ignore.union(extra_kwargs.keys())
+ constraint_items = self.get_constraint_items(field_name).items()
+ given_constraint_keys = self.get_given_constraint_keys(field_name)
- return {key: value for key, value in constraints.items()
- if key not in ignore}
+ return {key: value
+ for key, value in constraint_items
+ if key in given_constraint_keys}
def is_required(self, field_name: str) -> bool:
"""Check if a given pydantic field is required/mandatory. Returns True,
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index 7d14a45f..9f5047ef 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -1,6 +1,7 @@
-from typing import Optional
+from typing import Optional, Annotated
-from pydantic import BaseModel, field_validator, Field, model_validator, ConfigDict, root_validator
+from pydantic import BaseModel, field_validator, Field, model_validator, \
+ ConfigDict, root_validator, conint, constr, Strict
from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -44,7 +45,6 @@ def check(cls, v) -> str:
return v
-
class ModelShowFieldSummary(BaseModel):
"""ModelShowFieldSummary."""
@@ -383,6 +383,19 @@ class FieldShowConstraints(BaseModel):
"""Field."""
+class FieldShowConstraintsNativeConstraintTypes(BaseModel):
+ """FieldShowConstraints."""
+
+ field_int: conint(ge=0, le=100, strict=True)
+ """field_int"""
+
+ field_str: constr(min_length=5, strict=True, pattern="[a-z]+")
+ """field_str"""
+
+ field_annotated: Annotated[float, Strict()]
+ """field_annotated"""
+
+
class FieldShowConstraintsIgnoreExtraKwargs(BaseModel):
"""FieldShowConstraints."""
diff --git a/tests/test_configuration_fields.py b/tests/test_configuration_fields.py
index 3626bda7..a02a27d9 100644
--- a/tests/test_configuration_fields.py
+++ b/tests/test_configuration_fields.py
@@ -201,6 +201,11 @@ def test_autodoc_pydantic_field_doc_policy_both(autodocument):
def test_autodoc_pydantic_field_show_constraints_true(autodocument):
+ """Ensure that constraints are properly show via the `Field` type
+ annotation.
+
+ """
+
kwargs = dict(
object_path='target.configuration.FieldShowConstraints.field',
**KWARGS)
@@ -214,8 +219,98 @@ def test_autodoc_pydantic_field_show_constraints_true(autodocument):
' Field.',
'',
' :Constraints:',
- ' - **maximum** = 100',
- ' - **minimum** = 0',
+ ' - **ge** = 0',
+ ' - **le** = 100',
+ ''
+ ]
+
+ # explict global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_field_show_constraints": True},
+ **kwargs)
+ assert result == actual
+
+ # explicit local
+ actual = autodocument(
+ options_doc={"field-show-constraints": True},
+ **kwargs)
+ assert result == actual
+
+ # explicit local overwrite global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_field_show_constraints": False},
+ options_doc={"field-show-constraints": True},
+ **kwargs)
+ assert result == actual
+
+
+def test_autodoc_pydantic_field_show_constraints_native_int_type(autodocument):
+ """Ensure that constraints are properly show via specialized constraint
+ types.
+
+ """
+
+ kwargs = dict(
+ object_path='target.configuration.FieldShowConstraintsNativeConstraintTypes.field_int',
+ **KWARGS)
+
+ result = [
+ '',
+ '.. py:pydantic_field:: FieldShowConstraintsNativeConstraintTypes.field_int',
+ ' :module: target.configuration',
+ ' :type: int',
+ '',
+ ' field_int',
+ '',
+ ' :Constraints:',
+ ' - **strict** = True',
+ ' - **ge** = 0',
+ ' - **le** = 100',
+ ''
+ ]
+
+ # explict global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_field_show_constraints": True},
+ **kwargs)
+ assert result == actual
+
+ # explicit local
+ actual = autodocument(
+ options_doc={"field-show-constraints": True},
+ **kwargs)
+ assert result == actual
+
+ # explicit local overwrite global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_field_show_constraints": False},
+ options_doc={"field-show-constraints": True},
+ **kwargs)
+ assert result == actual
+
+
+def test_autodoc_pydantic_field_show_constraints_native_str_type(autodocument):
+ """Ensure that constraints are properly show via specialized constraint
+ types.
+
+ """
+
+ kwargs = dict(
+ object_path='target.configuration.FieldShowConstraintsNativeConstraintTypes.field_str',
+ **KWARGS)
+
+ result = [
+ '',
+ '.. py:pydantic_field:: FieldShowConstraintsNativeConstraintTypes.field_str',
+ ' :module: target.configuration',
+ ' :type: str',
+ '',
+ ' field_str',
+ '',
+ ' :Constraints:',
+ ' - **strict** = True',
+ ' - **min_length** = 5',
+ ' - **pattern** = [a-z]+',
''
]
@@ -239,6 +334,50 @@ def test_autodoc_pydantic_field_show_constraints_true(autodocument):
assert result == actual
+def test_autodoc_pydantic_field_show_constraints_native_annotated_type(autodocument):
+ """Ensure that constraints are properly show via specialized constraint
+ types.
+
+ """
+
+ kwargs = dict(
+ object_path='target.configuration.FieldShowConstraintsNativeConstraintTypes.field_annotated',
+ **KWARGS)
+
+ result = [
+ '',
+ '.. py:pydantic_field:: FieldShowConstraintsNativeConstraintTypes.field_annotated',
+ ' :module: target.configuration',
+ ' :type: float',
+ '',
+ ' field_annotated',
+ '',
+ ' :Constraints:',
+ ' - **strict** = True',
+ ''
+ ]
+
+ # explict global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_field_show_constraints": True},
+ **kwargs)
+ assert result == actual
+
+ # explicit local
+ actual = autodocument(
+ options_doc={"field-show-constraints": True},
+ **kwargs)
+ assert result == actual
+
+ # explicit local overwrite global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_field_show_constraints": False},
+ options_doc={"field-show-constraints": True},
+ **kwargs)
+ assert result == actual
+
+
+
def test_autodoc_pydantic_field_show_constraints_ignore_extra_kwargs(
autodocument):
"""Ensure that additional keyword arguments passed to pydantic `Field` are
@@ -261,8 +400,8 @@ def test_autodoc_pydantic_field_show_constraints_ignore_extra_kwargs(
' Field.',
'',
' :Constraints:',
- ' - **maximum** = 100',
- ' - **minimum** = 0',
+ ' - **ge** = 0',
+ ' - **le** = 100',
''
]
From 12c1cac4d4c1d99d651e030e96ba69c2f9fb328c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 11:43:51 +0200
Subject: [PATCH 26/42] Adjust serializability checks for v2.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 9 +++++----
tests/test_inspection.py | 5 +----
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index 76a27d5a..4cc7b8e9 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -11,7 +11,7 @@
from typing import NamedTuple, List, Dict, Any, Set, TypeVar, Type, Callable, \
Optional, Union
-from pydantic import BaseModel, create_model, ConfigDict, Strict
+from pydantic import BaseModel, create_model, ConfigDict
from pydantic.fields import FieldInfo
from pydantic_settings import SettingsConfigDict
from sphinx.addnodes import desc_signature
@@ -252,12 +252,13 @@ def _test_field_serializabiltiy(field: FieldInfo) -> bool:
"""
- class Cfg:
- arbitrary_types_allowed = True
+ model_config = ConfigDict(arbitrary_types_allowed=True)
try:
field_args = (field.annotation, field.default)
- model = create_model("_", test_field=field_args, Config=Cfg)
+ model = create_model("_",
+ __config__=model_config,
+ test_field=field_args)
model.model_json_schema()
return True
diff --git a/tests/test_inspection.py b/tests/test_inspection.py
index 69364d52..5868806b 100644
--- a/tests/test_inspection.py
+++ b/tests/test_inspection.py
@@ -139,10 +139,7 @@ def test_is_serializable_self_reference(serializable_self_reference):
def test_find_non_json_serializable_fields(serializable, serializable_mix):
assert serializable.fields.non_json_serializable == []
- non_serial_fields = ["field_2", "field_3", "field_4"]
- if get_pydantic_version() >= (1, 9):
- non_serial_fields.remove("field_2")
-
+ non_serial_fields = ["field_4"]
assert serializable_mix.fields.non_json_serializable == non_serial_fields
From 48744cd5706d9468f159f3cb88325ecd7686094d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 11:44:26 +0200
Subject: [PATCH 27/42] Adjust tests for v2 and account for removed config
documenter.
---
sphinxcontrib/autodoc_pydantic/events.py | 3 +--
tests/roots/test-base/target/edgecase_model_as_attribute.py | 6 +++---
.../target/edgecase_reused_validator_identical_names.py | 4 ++--
tests/test_edgecases.py | 1 +
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/events.py b/sphinxcontrib/autodoc_pydantic/events.py
index f616104c..e68619d1 100644
--- a/sphinxcontrib/autodoc_pydantic/events.py
+++ b/sphinxcontrib/autodoc_pydantic/events.py
@@ -4,8 +4,7 @@
OBJTYPES_CSS_FALLBACKS = {"pydantic_model": "class",
"pydantic_settings": "class",
"pydantic_validator": "method",
- "pydantic_field": "attribute",
- "pydantic_config": "class"}
+ "pydantic_field": "attribute"}
def add_fallback_css_class(app: Sphinx,
diff --git a/tests/roots/test-base/target/edgecase_model_as_attribute.py b/tests/roots/test-base/target/edgecase_model_as_attribute.py
index 817331c0..b42f636e 100644
--- a/tests/roots/test-base/target/edgecase_model_as_attribute.py
+++ b/tests/roots/test-base/target/edgecase_model_as_attribute.py
@@ -1,15 +1,15 @@
-import pydantic
+from pydantic import field_validator, BaseModel
class Foo:
"""Foo class"""
- class Bar(pydantic.BaseModel):
+ class Bar(BaseModel):
"""Bar class"""
x: str
- @pydantic.validator('x')
+ @field_validator('x')
def do_nothing(cls, value):
"""Foo"""
return value
diff --git a/tests/roots/test-base/target/edgecase_reused_validator_identical_names.py b/tests/roots/test-base/target/edgecase_reused_validator_identical_names.py
index ee0de487..336c9c7c 100644
--- a/tests/roots/test-base/target/edgecase_reused_validator_identical_names.py
+++ b/tests/roots/test-base/target/edgecase_reused_validator_identical_names.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator
+from pydantic import BaseModel, field_validator
def validation(name):
@@ -10,6 +10,6 @@ class ModelOne(BaseModel):
name: str
"""Name"""
- validation = validator('name', allow_reuse=True)(validation)
+ validation = field_validator('name')(validation)
"""Reused validator class method."""
diff --git a/tests/test_edgecases.py b/tests/test_edgecases.py
index 227b5308..71e295b4 100644
--- a/tests/test_edgecases.py
+++ b/tests/test_edgecases.py
@@ -37,6 +37,7 @@ def test_not_json_compliant(autodocument):
' "type": "object",',
' "properties": {',
' "field": {',
+ ' "default": null,',
' "title": "Field"',
' }',
' }',
From 7f17e406dbd1a07b07c1b7566b3c4571673679f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 12:13:18 +0200
Subject: [PATCH 28/42] Further test adjustments to account for better field
serializability in pydantic v2.
---
tests/roots/test-json-error-strategy/example.py | 6 +++++-
tests/test_inspection.py | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/tests/roots/test-json-error-strategy/example.py b/tests/roots/test-json-error-strategy/example.py
index 80ab58b0..a3033576 100644
--- a/tests/roots/test-json-error-strategy/example.py
+++ b/tests/roots/test-json-error-strategy/example.py
@@ -1,12 +1,16 @@
from pydantic import BaseModel
+class Custom:
+ def __init__(self):
+ self.field = "foobar"
+
class NonSerializable(BaseModel):
"""NonSerializable
"""
- field: object = object()
+ field: Custom = Custom()
"""Field"""
class Config:
diff --git a/tests/test_inspection.py b/tests/test_inspection.py
index 5868806b..a57c07ea 100644
--- a/tests/test_inspection.py
+++ b/tests/test_inspection.py
@@ -92,7 +92,7 @@ class Foo(BaseModel):
[
("field_1", True),
("field_2", object_is_serializable()),
- ("field_3", False),
+ ("field_3", True),
("field_4", False),
("field_5", True),
("field_6", True),
From e341207157a9fd47e4091dec6adbd36dcf5ab706 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 12:13:57 +0200
Subject: [PATCH 29/42] Adjust model config retrieval to work with modified
`BaseSettings` in v2.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 37 +++++++++++-------
tests/roots/test-base/target/configuration.py | 4 ++
tests/test_configuration_settings.py | 39 ++++++++++++++++++-
3 files changed, 65 insertions(+), 15 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index 4cc7b8e9..b98d9774 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -13,7 +13,7 @@
from pydantic import BaseModel, create_model, ConfigDict
from pydantic.fields import FieldInfo
-from pydantic_settings import SettingsConfigDict
+from pydantic_settings import SettingsConfigDict, BaseSettings
from sphinx.addnodes import desc_signature
ASTERISK_FIELD_NAME = "all fields"
@@ -335,27 +335,36 @@ class ConfigInspector(BaseInspectionComposite):
def __init__(self, parent: 'ModelInspector'):
super().__init__(parent)
- self.attribute: ConfigDict = self.model.model_config
+ self.items = self._get_values_per_type()
- @property
- def is_configured(self) -> bool:
- """Check if pydantic model config was explicitly configured. If not,
- it defaults to the standard configuration provided by pydantic and
- typically does not required documentation.
+ def _get_values_per_type(self) -> Dict[str, str]:
+ """Get the configuration values from any pydantic model.
+
+ Behavior of configuration values varies between `BaseModel` and
+ BaseSettings`. For `BaseModel`, if no configs are provided, then
+ model_config` is empty. However, for `BaseSettings`, `model_config`
+ contains a predefined set of values. This needs to be handled properly
+ otherwise the `BaseSettings` always show up a lot of irrelevant default
+ values. Hence, the default values are removed.
"""
- return bool(self.attribute)
+ values = self.model.model_config
- @property
- def items(self) -> Union[ConfigDict, SettingsConfigDict]:
- """Return all non private (without leading underscore `_`) items of
- pydantic configuration class.
+ if issubclass(self.model, BaseSettings):
+ default = tuple(BaseSettings.model_config.items())
+ available = tuple(values.items())
- """
+ result = [given for given in available if given not in default]
+ values = dict(result)
+
+ return values
- return self.attribute
+ @property
+ def is_configured(self) -> bool:
+ """Check if pydantic model config was explicitly configured."""
+ return bool(self.items)
class ReferenceInspector(BaseInspectionComposite):
"""Provide namespace for inspection methods for creating references
diff --git a/tests/roots/test-base/target/configuration.py b/tests/roots/test-base/target/configuration.py
index 9f5047ef..d02daf5c 100644
--- a/tests/roots/test-base/target/configuration.py
+++ b/tests/roots/test-base/target/configuration.py
@@ -160,6 +160,10 @@ class SettingsShowConfigSummary(BaseSettings):
model_config = SettingsConfigDict(title="FooBar", frozen=False)
+class SettingsShowConfigSummaryEmpty(BaseSettings):
+ """SettingsShowConfigSummaryEmpty."""
+
+
class SettingsShowValidatorsSummary(BaseSettings):
"""SettingsShowValidatorsSummary."""
diff --git a/tests/test_configuration_settings.py b/tests/test_configuration_settings.py
index 5a900cb6..cf270f52 100644
--- a/tests/test_configuration_settings.py
+++ b/tests/test_configuration_settings.py
@@ -116,8 +116,8 @@ def test_autodoc_pydantic_settings_show_config_summary_summary_true(autodocument
' SettingsShowConfigSummary.',
'',
' :Config:',
- ' - **frozen**: *bool = True*',
' - **title**: *str = FooBar*',
+ ' - **frozen**: *bool = False*',
'']
# explict global
@@ -173,6 +173,43 @@ def test_autodoc_pydantic_settings_show_config_summary_false(autodocument):
assert actual == result
+def test_autodoc_pydantic_settings_show_config_summary_summary_true_but_empty(autodocument):
+ """In case there are not configuration settings provided, then ensure that
+ the config summary section is not shown at all.
+
+ """
+
+ kwargs = dict(object_path='target.configuration.SettingsShowConfigSummaryEmpty',
+ **KWARGS)
+
+ result = [
+ '',
+ '.. py:pydantic_settings:: SettingsShowConfigSummaryEmpty',
+ ' :module: target.configuration',
+ '',
+ ' SettingsShowConfigSummaryEmpty.',
+ '']
+
+ # explict global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_settings_show_config_summary": True},
+ **kwargs)
+ assert actual == result
+
+ # explict local
+ actual = autodocument(
+ options_doc={"settings-show-config-summary": True},
+ **kwargs)
+ assert actual == result
+
+ # explicit local overwrite global
+ actual = autodocument(
+ options_app={"autodoc_pydantic_settings_show_config_summary": False},
+ options_doc={"settings-show-config-summary": True},
+ **kwargs)
+ assert actual == result
+
+
def test_autodoc_pydantic_settings_show_validator_summary_true(autodocument):
kwargs = dict(
object_path='target.configuration.SettingsShowValidatorsSummary',
From 476f84236d31006580a05e2da754913f9a105582 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 12:25:11 +0200
Subject: [PATCH 30/42] Fix generics example for v2.
---
tests/roots/test-base/target/example_generics.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tests/roots/test-base/target/example_generics.py b/tests/roots/test-base/target/example_generics.py
index 28072d8c..cc9a31b1 100644
--- a/tests/roots/test-base/target/example_generics.py
+++ b/tests/roots/test-base/target/example_generics.py
@@ -1,7 +1,6 @@
from typing import Generic, TypeVar, Optional, List
from pydantic import BaseModel, field_validator
-from pydantic.generics import GenericModel
DataT = TypeVar('DataT')
@@ -18,13 +17,13 @@ class DataModel(BaseModel):
people: List[str]
-class Response(GenericModel, Generic[DataT]):
+class Response(BaseModel, Generic[DataT]):
"""HTTP Response representation."""
data: Optional[DataT]
error: Optional[Error]
- @field_validator('error', always=True)
+ @field_validator('error')
def check_consistency(cls, v, values):
if v is not None and values['data'] is not None:
raise ValueError('must not provide both data and error')
From b07222ef92ffc87a9a890a6360b62433bbb691bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 14:07:15 +0200
Subject: [PATCH 31/42] Remove obsolete test cases.
---
tests/roots/test-base/target/example_model.py | 35 -------------------
1 file changed, 35 deletions(-)
delete mode 100644 tests/roots/test-base/target/example_model.py
diff --git a/tests/roots/test-base/target/example_model.py b/tests/roots/test-base/target/example_model.py
deleted file mode 100644
index 44006379..00000000
--- a/tests/roots/test-base/target/example_model.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from pydantic import field_validator, Field
-from pydantic.env_settings import BaseSettings, SettingsConfigDict
-
-
-class ExampleSettings(BaseSettings):
- """Document your project settings very conveniently. Applies like wise
- to pydantic models.
-
- """
-
- field_plain_with_validator: int = 100
- """Show standard field with type annotation."""
-
- field_with_validator_and_alias: str = Field("FooBar", alias="BarFoo")
- """Shows corresponding validator with link/anchor."""
-
- field_with_constraints_and_description: int = Field(
- default=5,
- ge=0,
- le=100,
- description="Shows constraints within doc string."
- )
-
- @field_validator("field_with_validator_and_alias", "field_plain_with_validator")
- def check_max_length_ten(cls, v):
- """Show corresponding field with link/anchor.
-
- """
-
- if len(v) >= 10:
- raise ValueError("No more than 10 characters allowed")
-
- return v
-
- model_config = SettingsConfigDict(frozen=False, env_prefix="foo_")
From 7178e9f78056787ea9984a323badd91332a5ba52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 14:07:54 +0200
Subject: [PATCH 32/42] Adjust constraint keys to varying levels of nesting.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index b98d9774..b03ffc69 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -190,9 +190,20 @@ def get_given_constraint_keys(self, field_name: str) -> Set[str]:
"""
definition = self.model.__pydantic_core_schema__["definitions"][0]
- schema = definition["schema"]["fields"][field_name]["schema"]
- # account for yet another level on model-field
+ # account for varying levels of nesting :-(
+ try:
+ field_schemas = definition["schema"]["fields"]
+ except KeyError:
+ field_schemas = definition["schema"]["schema"]["fields"]
+
+ # account for generics and other non-native fields without schema info
+ try:
+ schema = field_schemas[field_name]["schema"]
+ except KeyError:
+ return set()
+
+ # account for yet another level on model-field :-(
if "schema" in schema:
schema = schema["schema"]
From 0f81c1a8c325e69d8e1c5b7270bc599afee66e63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 14:08:25 +0200
Subject: [PATCH 33/42] Fix imports for v2 compatibility.
---
tests/roots/test-base/target/example_reused_validators.py | 6 +++---
tests/roots/test-base/target/example_validators.py | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/roots/test-base/target/example_reused_validators.py b/tests/roots/test-base/target/example_reused_validators.py
index d663da27..17e54251 100644
--- a/tests/roots/test-base/target/example_reused_validators.py
+++ b/tests/roots/test-base/target/example_reused_validators.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, validator
+from pydantic import BaseModel, field_validator
def normalize(name: str) -> str:
@@ -10,11 +10,11 @@ class Producer(BaseModel):
name: str
# validators
- normalize_name = validator('name', allow_reuse=True)(normalize)
+ normalize_name = field_validator('name')(normalize)
class Consumer(BaseModel):
name: str
# validators
- normalize_name = validator('name', allow_reuse=True)(normalize)
\ No newline at end of file
+ normalize_name = field_validator('name')(normalize)
\ No newline at end of file
diff --git a/tests/roots/test-base/target/example_validators.py b/tests/roots/test-base/target/example_validators.py
index d9851ed2..2de4875d 100644
--- a/tests/roots/test-base/target/example_validators.py
+++ b/tests/roots/test-base/target/example_validators.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, field_validator, root_validator
+from pydantic import BaseModel, field_validator, model_validator
class ExampleValidators(BaseModel):
@@ -21,7 +21,7 @@ def check_non_whitespaces(cls, v):
else:
raise ValueError("String contains only whitespace characters.")
- @root_validator
+ @model_validator(mode="after")
def check_contains_letters(cls, values):
"""Confirm that string contains at least one letter.
From d57cfd4f181643144ecc92548b7cd53105d52961 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 14:21:46 +0200
Subject: [PATCH 34/42] Update test matrix for latest features versions.
---
.github/workflows/tests.yml | 64 ++++++++++---------------------------
tox.ini | 14 ++------
2 files changed, 19 insertions(+), 59 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index bcc8855b..52f2d278 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -12,60 +12,28 @@ jobs:
fail-fast: false
matrix:
include:
- - python_version: 3.7
- pydantic_version: "16"
- sphinx_version: "34"
- - python_version: 3.8
- pydantic_version: "17"
- sphinx_version: "35"
- - python_version: 3.9
- pydantic_version: "18"
- sphinx_version: "35"
- - python_version: 3.9
- pydantic_version: "18"
+ - python_version: "3.7"
+ pydantic_version: "20"
sphinx_version: "40"
- - python_version: 3.9
- pydantic_version: "18"
- sphinx_version: "41"
- - python_version: 3.9
- pydantic_version: "18"
- sphinx_version: "42"
- - python_version: 3.9
- pydantic_version: "18"
- sphinx_version: "43"
- - python_version: "3.10"
- pydantic_version: "18"
- sphinx_version: "43"
- - python_version: "3.10"
- pydantic_version: "19"
- sphinx_version: "43"
- - python_version: "3.10"
- pydantic_version: "19"
- sphinx_version: "44"
- - python_version: "3.10"
- pydantic_version: "19"
+ - python_version: "3.8"
+ pydantic_version: "20"
sphinx_version: "45"
+ - python_version: "3.9"
+ pydantic_version: "20"
+ sphinx_version: "45"
+ - python_version: "3.9"
+ pydantic_version: "20"
+ sphinx_version: "53"
- python_version: "3.10"
- pydantic_version: "19"
- sphinx_version: "50"
- - python_version: "3.10"
- pydantic_version: "110"
- sphinx_version: "51"
- - python_version: "3.10"
- pydantic_version: "110"
- sphinx_version: "52"
- - python_version: "3.10"
- pydantic_version: "110"
- sphinx_version: "60"
- - python_version: "3.10"
- pydantic_version: "110"
- sphinx_version: "61"
- - python_version: "3.10"
- pydantic_version: "110"
+ pydantic_version: "20"
sphinx_version: "62"
- python_version: "3.10"
- pydantic_version: "110"
+ pydantic_version: "20"
+ sphinx_version: "70"
+ - python_version: "3.11"
+ pydantic_version: "20"
sphinx_version: "70"
+
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
diff --git a/tox.ini b/tox.ini
index 38c5af8e..070ec117 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py{37,38,39,310}-pydantic{20,latest}-sphinx{40,41,42,43,44,45,50,51,52,60,61,62,70,latest}, latest, development, no_erdantic, linter
+envlist = py{37,38,39,310,311}-pydantic{20,latest}-sphinx{40,45,53,62,70,latest}, latest, development, no_erdantic, linter
isolated_build = True
[testenv]
@@ -12,22 +12,14 @@ commands =
coverage report -m
coverage xml
-[testenv:pydantic{20,latest}-sphinx{40,41,42,43,44,45,50,51,52,60,61,62,70,latest}]
+[testenv:pydantic{20,latest}-sphinx{40,45,53,62,70,latest}]
description = "Test specific historical stable versions."
deps =
pydantic20: pydantic~=2.0.0
pydanticlatest: pydantic
sphinx40: sphinx~=4.0.0
- sphinx41: sphinx~=4.1.0
- sphinx42: sphinx~=4.2.0
- sphinx43: sphinx~=4.3.0
- sphinx44: sphinx~=4.4.0
sphinx45: sphinx~=4.5.0
- sphinx50: sphinx~=5.0.0
- sphinx51: sphinx~=5.1.0
- sphinx52: sphinx~=5.2.0
- sphinx60: sphinx~=6.0.0
- sphinx61: sphinx~=6.1.0
+ sphinx53: sphinx~=5.3.0
sphinx62: sphinx~=6.2.0
sphinx70: sphinx~=7.0.0
sphinxlatest: sphinx
From 1ab16b32f2f32e3f995af087eda69a4b1d11dc3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 15:55:20 +0200
Subject: [PATCH 35/42] Fix sphinx version dependant type annotation.
---
tests/test_configuration_fields.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/test_configuration_fields.py b/tests/test_configuration_fields.py
index a02a27d9..bcf27e2a 100644
--- a/tests/test_configuration_fields.py
+++ b/tests/test_configuration_fields.py
@@ -883,7 +883,7 @@ def test_autodoc_pydantic_field_show_required_true_not(expected, autodocument):
@pytest.mark.parametrize("field_values", (("field1", "int"),
("field2", "int"),
("field3", "int"),
- ("field4", "~typing.Optional[int]")))
+ ("field4", OPTIONAL_INT)))
def test_autodoc_pydantic_field_show_required_false(field_values,
autodocument):
"""Ensure that the required marker is not shown if deactivated.
@@ -926,7 +926,7 @@ def test_autodoc_pydantic_field_show_required_false(field_values,
@pytest.mark.parametrize("field_values", (("field1", "int"),
("field2", "int"),
("field3", "int"),
- ("field4", "~typing.Optional[int]")))
+ ("field4", OPTIONAL_INT)))
def test_autodoc_pydantic_field_show_required_false_show_default_true(
field_values, autodocument):
"""Ensure that the required marker is not shown while the default value
From 71ccfc784b07133528f262fb9c7b925e86d12eda Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 15:55:34 +0200
Subject: [PATCH 36/42] Remove erdantic version number from test.
---
tests/test_configuration_model.py | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/tests/test_configuration_model.py b/tests/test_configuration_model.py
index 3213e991..0f128667 100644
--- a/tests/test_configuration_model.py
+++ b/tests/test_configuration_model.py
@@ -209,24 +209,23 @@ def test_autodoc_pydantic_model_erdantic_figure_collapsed_false(autodocument):
"autodoc_pydantic_model_erdantic_figure_collapsed": False
},
**kwargs)
- print(actual)
- assert actual[:10] == result[:10]
- assert actual[11:] == result[11:]
+ assert actual[:11] == result[:11]
+ assert actual[12:] == result[12:]
# explicit local
actual = autodocument(
options_doc={"model-erdantic-figure": True, "model-erdantic-figure-collapsed": False},
**kwargs)
- assert actual[:10] == result[:10]
- assert actual[11:] == result[11:]
+ assert actual[:11] == result[:11]
+ assert actual[12:] == result[12:]
# explicit local overwrite global
actual = autodocument(
options_app={"autodoc_pydantic_model_erdantic_figure_collapsed": True},
options_doc={"model-erdantic-figure": True, "model-erdantic-figure-collapsed": False},
**kwargs)
- assert actual[:10] == result[:10]
- assert actual[11:] == result[11:]
+ assert actual[:11] == result[:11]
+ assert actual[12:] == result[12:]
@pytest.mark.skipif(package_is_missing('erdantic'), reason="erdantic missing")
From 1c0409024651523751b5c328cfa449eb726df1b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 16:05:48 +0200
Subject: [PATCH 37/42] Allow python 3.7.1. Bump version to 2.0.0.
---
pyproject.toml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 3e9b6629..420ca558 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "autodoc_pydantic"
-version = "1.10.0"
+version = "2.0.0"
description = "Seamlessly integrate pydantic models in your Sphinx documentation."
authors = ["mansenfranzen "]
packages = [{ include = "sphinxcontrib" }]
@@ -18,7 +18,7 @@ classifiers = [
include = ["sphinxcontrib/autodoc_pydantic/css/autodoc_pydantic.css"]
[tool.poetry.dependencies]
-python = ">=3.8.0,<4.0.0"
+python = ">=3.7.1,<4.0.0"
Sphinx = ">=4.0"
pydantic = ">=2.0,<3.0.0"
pydantic-settings = ">=2.0,<3.0.0"
From 19ba8443d358c7223c731ddb87cd4c5f7fc1a8bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 16:06:14 +0200
Subject: [PATCH 38/42] Add separate test for JSON warning/coerce.
---
.../test-json-error-strategy-coerce/conf.py | 8 ++++++++
.../example_coerce.py | 16 +++++++++++++++
.../test-json-error-strategy-coerce/index.rst | 2 ++
.../roots/test-json-error-strategy/example.py | 11 +++++-----
tests/test_edgecases.py | 20 +++++++++----------
5 files changed, 41 insertions(+), 16 deletions(-)
create mode 100644 tests/roots/test-json-error-strategy-coerce/conf.py
create mode 100644 tests/roots/test-json-error-strategy-coerce/example_coerce.py
create mode 100644 tests/roots/test-json-error-strategy-coerce/index.rst
diff --git a/tests/roots/test-json-error-strategy-coerce/conf.py b/tests/roots/test-json-error-strategy-coerce/conf.py
new file mode 100644
index 00000000..8a8b1d0f
--- /dev/null
+++ b/tests/roots/test-json-error-strategy-coerce/conf.py
@@ -0,0 +1,8 @@
+import os
+import sys
+
+sys.path.insert(0, os.path.abspath('.'))
+
+extensions = ['sphinx.ext.autodoc',
+ 'sphinx.ext.autosummary',
+ 'sphinxcontrib.autodoc_pydantic']
\ No newline at end of file
diff --git a/tests/roots/test-json-error-strategy-coerce/example_coerce.py b/tests/roots/test-json-error-strategy-coerce/example_coerce.py
new file mode 100644
index 00000000..a006184a
--- /dev/null
+++ b/tests/roots/test-json-error-strategy-coerce/example_coerce.py
@@ -0,0 +1,16 @@
+from pydantic import BaseModel, ConfigDict
+
+
+class CustomCoerce:
+ pass
+
+
+class NonSerializableCoerce(BaseModel):
+ """NonSerializable
+
+ """
+
+ test_me: CustomCoerce
+ """Field"""
+
+ model_config = ConfigDict(arbitrary_types_allowed=True)
diff --git a/tests/roots/test-json-error-strategy-coerce/index.rst b/tests/roots/test-json-error-strategy-coerce/index.rst
new file mode 100644
index 00000000..bb4b3fe4
--- /dev/null
+++ b/tests/roots/test-json-error-strategy-coerce/index.rst
@@ -0,0 +1,2 @@
+.. automodule:: example_coerce
+ :members:
\ No newline at end of file
diff --git a/tests/roots/test-json-error-strategy/example.py b/tests/roots/test-json-error-strategy/example.py
index a3033576..5080a833 100644
--- a/tests/roots/test-json-error-strategy/example.py
+++ b/tests/roots/test-json-error-strategy/example.py
@@ -1,17 +1,16 @@
-from pydantic import BaseModel
+from pydantic import BaseModel, ConfigDict
class Custom:
- def __init__(self):
- self.field = "foobar"
+ pass
+
class NonSerializable(BaseModel):
"""NonSerializable
"""
- field: Custom = Custom()
+ field: Custom
"""Field"""
- class Config:
- arbitrary_types_allowed = True
+ model_config = ConfigDict(arbitrary_types_allowed=True)
diff --git a/tests/test_edgecases.py b/tests/test_edgecases.py
index 71e295b4..37489f05 100644
--- a/tests/test_edgecases.py
+++ b/tests/test_edgecases.py
@@ -228,18 +228,18 @@ def test_json_error_strategy_raise(test_app):
app.build()
-def test_json_error_strategy_warn(test_app, log_capturer):
- """Confirm that a non serializable field triggers a warning during build
- process.
+def test_json_error_strategy_coerce(test_app, log_capturer):
+ """Confirm that a non serializable field triggers no warning during build
+ process but is coerced.
This relates to #28.
"""
- conf = {"autodoc_pydantic_model_show_json_error_strategy": "warn"}
+ conf = {"autodoc_pydantic_model_show_json_error_strategy": "coerce"}
with log_capturer() as logs:
- app = test_app("json-error-strategy", conf=conf)
+ app = test_app("json-error-strategy-coerce", conf=conf)
app.build()
message = (
@@ -248,18 +248,18 @@ def test_json_error_strategy_warn(test_app, log_capturer):
"['field']."
)
- assert [log for log in logs if log.msg == message]
+ assert not [log for log in logs if log.msg == message]
-def test_json_error_strategy_coerce(test_app, log_capturer):
- """Confirm that a non serializable field triggers no warning during build
+def test_json_error_strategy_warn(test_app, log_capturer):
+ """Confirm that a non serializable field triggers a warning during build
process.
This relates to #28.
"""
- conf = {"autodoc_pydantic_model_show_json_error_strategy": "coerce"}
+ conf = {"autodoc_pydantic_model_show_json_error_strategy": "warn"}
with log_capturer() as logs:
app = test_app("json-error-strategy", conf=conf)
@@ -271,7 +271,7 @@ def test_json_error_strategy_coerce(test_app, log_capturer):
"['field']."
)
- assert not [log for log in logs if log.msg == message]
+ assert [log for log in logs if log.msg == message]
def test_autodoc_pydantic_model_show_field_summary_not_inherited(autodocument):
From ff6b73dc755e992d4b1cf249349f18a2a2735aea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 16:07:14 +0200
Subject: [PATCH 39/42] Catch `PydanticInvalidForJsonSchema` in v2.
---
sphinxcontrib/autodoc_pydantic/inspection.py | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/sphinxcontrib/autodoc_pydantic/inspection.py b/sphinxcontrib/autodoc_pydantic/inspection.py
index b03ffc69..e62fa4e7 100644
--- a/sphinxcontrib/autodoc_pydantic/inspection.py
+++ b/sphinxcontrib/autodoc_pydantic/inspection.py
@@ -9,11 +9,12 @@
import warnings
from collections import defaultdict
from typing import NamedTuple, List, Dict, Any, Set, TypeVar, Type, Callable, \
- Optional, Union
+ Optional
-from pydantic import BaseModel, create_model, ConfigDict
+from pydantic import BaseModel, create_model, ConfigDict, \
+ PydanticInvalidForJsonSchema
from pydantic.fields import FieldInfo
-from pydantic_settings import SettingsConfigDict, BaseSettings
+from pydantic_settings import BaseSettings
from sphinx.addnodes import desc_signature
ASTERISK_FIELD_NAME = "all fields"
@@ -465,7 +466,7 @@ def sanitized(self) -> Dict:
warnings.simplefilter("ignore")
schema = self.model.model_json_schema()
- except (TypeError, ValueError):
+ except (TypeError, ValueError, PydanticInvalidForJsonSchema):
new_model = self.create_sanitized_model()
schema = new_model.model_json_schema()
@@ -555,10 +556,6 @@ def get_field_validator_mapping(self) -> Dict[str, List[ValidatorAdapter]]:
decorators = self.model.__pydantic_decorators__
# standard validators
- for validator in decorators.validators.values():
- for field in validator.info.fields:
- mapping[field].append(ValidatorAdapter(func=validator.func))
-
for validator in decorators.field_validators.values():
for field in validator.info.fields:
mapping[field].append(ValidatorAdapter(func=validator.func))
From 881f50f2b359a5cd37b4966327063921b29ce281 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 16:07:38 +0200
Subject: [PATCH 40/42] Move schema generation after error checks.
---
sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
index bf6fd0fd..a5b85cf1 100644
--- a/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
+++ b/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py
@@ -301,7 +301,6 @@ def add_collapsable_schema(self):
"""
- schema = self.pydantic.inspect.schema.sanitized
non_serializable = self.pydantic.inspect.fields.non_json_serializable
# handle non serializable fields
@@ -324,6 +323,7 @@ def add_collapsable_schema(self):
f"Allowed values are f{OptionsJsonErrorStrategy.values()}"
)
+ schema = self.pydantic.inspect.schema.sanitized
schema_rest = self._convert_json_schema_to_rest(schema)
source_name = self.get_sourcename()
for line in schema_rest:
From 17ea80958d100c6bfb81d22f0b9429a859ced4df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 16:07:56 +0200
Subject: [PATCH 41/42] Remove reference to config documenter.
---
docs/source/users/usage.rst | 1 -
1 file changed, 1 deletion(-)
diff --git a/docs/source/users/usage.rst b/docs/source/users/usage.rst
index 3303c3ee..ebd603bf 100644
--- a/docs/source/users/usage.rst
+++ b/docs/source/users/usage.rst
@@ -109,7 +109,6 @@ specialized directives provided by *autodoc_pydantic*:
- :ref:`autopydantic_settings`
- :ref:`autopydantic_field`
- :ref:`autopydantic_validator`
-- :ref:`autopydantic_config`
.. _autopydantic_model:
From d6ef69f5b1c51aa3b21ebc9388a9403cc3f1c7c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20W=C3=B6llert?=
Date: Sat, 22 Jul 2023 16:29:34 +0200
Subject: [PATCH 42/42] Bump version - ci skip.
---
docs/source/conf.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 099b8a7e..c2490b96 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -31,7 +31,7 @@
author = 'Franz Wöllert'
# The full version, including alpha/beta/rc tags
-release = '1.9.0'
+release = '2.0.0'
# -- General configuration ---------------------------------------------------