From f0279c89b7edd10db7af2e254e58b6f589e4162f Mon Sep 17 00:00:00 2001 From: Jacob Hayes Date: Fri, 8 Dec 2023 07:18:10 -0500 Subject: [PATCH] Add support for pydantic v2 (#795) **Pull Request Checklist** - [x] Fixes #713 - [ ] Tests added - [ ] Documentation/examples added - [x] [Good commit messages](https://cbea.ms/git-commit/) and/or PR title **Description of PR** WIP, but wanted to get the bulk of it up for any feedback while I: - add a test run in CI with pydantic v1 installed (to ensure existing users are covered - they passed manually) - add a couple more tests and try to support serializing v1 *and* v2 user-defined models (not just the v1 models from either version - I think this should be possible). - update the model generation to update the Field import --- This PR updates hera to support use with either pydantic v1 or v2 installed. All hera internal code now imports pydantic objects from `hera.shared._pydantic` (extended and renamed from `_base_model`). This module ensures that we're always using v1 compatible objects, which allows us to support codebases installing either pydantic v1 or v2 (although the models passed to Hera must be v1 for pydantic v1 and v2 for pydantic v2). --------- Signed-off-by: Jacob Hayes Signed-off-by: Matt Rose Signed-off-by: Sambhav Kothari Co-authored-by: Matt Rose Co-authored-by: Sambhav Kothari --- .github/workflows/cicd.yaml | 40 +- Makefile | 12 +- .../workflows/scripts/callable_script.md | 4 +- examples/workflows/scripts/callable_script.py | 4 +- poetry.lock | 599 +++++------------- pyproject.toml | 6 +- scripts/models.py | 1 + src/hera/events/models/eventsource.py | 4 +- src/hera/events/models/eventsource.pyi | 5 +- src/hera/events/models/google/protobuf.py | 2 +- src/hera/events/models/google/protobuf.pyi | 2 +- .../events/models/grpc/gateway/runtime.py | 2 +- .../events/models/grpc/gateway/runtime.pyi | 2 +- .../models/io/argoproj/events/v1alpha1.py | 4 +- .../models/io/argoproj/events/v1alpha1.pyi | 5 +- .../models/io/argoproj/workflow/v1alpha1.py | 4 +- .../models/io/argoproj/workflow/v1alpha1.pyi | 5 +- src/hera/events/models/io/k8s/api/core/v1.py | 4 +- src/hera/events/models/io/k8s/api/core/v1.pyi | 5 +- .../models/io/k8s/api/policy/v1beta1.py | 4 +- .../models/io/k8s/api/policy/v1beta1.pyi | 5 +- .../io/k8s/apimachinery/pkg/api/resource.py | 4 +- .../io/k8s/apimachinery/pkg/api/resource.pyi | 5 +- .../io/k8s/apimachinery/pkg/apis/meta/v1.py | 4 +- .../io/k8s/apimachinery/pkg/apis/meta/v1.pyi | 5 +- .../io/k8s/apimachinery/pkg/util/intstr.py | 2 +- .../io/k8s/apimachinery/pkg/util/intstr.pyi | 2 +- src/hera/events/models/sensor.py | 4 +- src/hera/events/models/sensor.pyi | 5 +- src/hera/shared/_base_model.py | 25 - src/hera/shared/_global_config.py | 5 +- src/hera/shared/_pydantic.py | 66 ++ src/hera/shared/serialization.py | 26 +- src/hera/workflows/_mixins.py | 8 +- src/hera/workflows/archive.py | 2 +- src/hera/workflows/artifact.py | 2 +- .../workflows/cluster_workflow_template.py | 3 +- src/hera/workflows/cron_workflow.py | 2 +- src/hera/workflows/env.py | 8 +- src/hera/workflows/env_from.py | 2 +- src/hera/workflows/models/eventsource.py | 4 +- src/hera/workflows/models/eventsource.pyi | 5 +- src/hera/workflows/models/google/protobuf.py | 2 +- src/hera/workflows/models/google/protobuf.pyi | 2 +- .../workflows/models/grpc/gateway/runtime.py | 2 +- .../workflows/models/grpc/gateway/runtime.pyi | 2 +- .../models/io/argoproj/events/v1alpha1.py | 4 +- .../models/io/argoproj/events/v1alpha1.pyi | 5 +- .../models/io/argoproj/workflow/v1alpha1.py | 4 +- .../models/io/argoproj/workflow/v1alpha1.pyi | 5 +- .../workflows/models/io/k8s/api/core/v1.py | 4 +- .../workflows/models/io/k8s/api/core/v1.pyi | 5 +- .../models/io/k8s/api/policy/v1beta1.py | 4 +- .../models/io/k8s/api/policy/v1beta1.pyi | 5 +- .../io/k8s/apimachinery/pkg/api/resource.py | 4 +- .../io/k8s/apimachinery/pkg/api/resource.pyi | 5 +- .../io/k8s/apimachinery/pkg/apis/meta/v1.py | 4 +- .../io/k8s/apimachinery/pkg/apis/meta/v1.pyi | 5 +- .../io/k8s/apimachinery/pkg/util/intstr.py | 2 +- .../io/k8s/apimachinery/pkg/util/intstr.pyi | 2 +- src/hera/workflows/models/sensor.py | 4 +- src/hera/workflows/models/sensor.pyi | 5 +- src/hera/workflows/parameter.py | 3 +- src/hera/workflows/resources.py | 7 +- src/hera/workflows/retry_strategy.py | 7 +- src/hera/workflows/runner.py | 31 +- src/hera/workflows/script.py | 2 +- src/hera/workflows/volume.py | 3 +- src/hera/workflows/workflow.py | 5 +- src/hera/workflows/workflow_template.py | 4 +- tests/script_runner/artifact_loaders.py | 4 +- tests/script_runner/parameter_inputs.py | 14 - tests/test_runner.py | 19 +- 73 files changed, 439 insertions(+), 643 deletions(-) delete mode 100644 src/hera/shared/_base_model.py create mode 100644 src/hera/shared/_pydantic.py diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index afc09dc0e..6363e9fbd 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -34,7 +34,7 @@ jobs: - name: Install dependencies run: poetry install - + - name: run ci checks run: make ci @@ -53,6 +53,44 @@ jobs: with: path: dist/*.whl + # Run tests against pydantic v1 until we drop support. + test-pydantic-v1: + name: test py${{ matrix.python-version }} (pydantic v1) on ${{ matrix.os }} + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + python-version: ["3.8", "3.9", "3.10", "3.11"] + + runs-on: ${{ matrix.os }} + + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: Install poetry + run: pipx install poetry + + - name: setup python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: "poetry" + + - name: Install dependencies + run: | + poetry install + poetry run pip install "pydantic<2" + + - name: run ci checks + run: make ci + + - name: Upload coverage + uses: codecov/codecov-action@v3 + with: + file: ./coverage.xml + concurrency: group: ${{ github.workflow }}-${{ github.ref || github.run_id }} cancel-in-progress: true diff --git a/Makefile b/Makefile index 295d815f7..e13c59060 100644 --- a/Makefile +++ b/Makefile @@ -55,11 +55,15 @@ workflows-models: ## Generate the Workflows models portion of Argo Workflows --snake-case-field \ --target-python-version 3.8 \ --output src/hera/workflows/models \ - --base-class hera.shared._base_model.BaseModel \ + --output-model-type pydantic.BaseModel \ + --base-class hera.shared._pydantic.BaseModel \ + --input-file-type jsonschema \ --wrap-string-literal \ --disable-appending-item-suffix \ --disable-timestamp \ --use-default-kwarg + @find src/hera/workflows/models/ -name '*.py' -exec sed -i.bak 's/from pydantic import Field/from hera.shared._pydantic import Field/' {} + + @find src/hera/workflows/models/ -name '*.bak' -delete @poetry run python scripts/models.py $(OPENAPI_SPEC_URL) workflows @poetry run stubgen -o src -p hera.workflows.models && find src/hera/workflows/models -name '__init__.pyi' -delete @rm $(SPEC_PATH) @@ -74,11 +78,15 @@ events-models: ## Generate the Events models portion of Argo Workflows --snake-case-field \ --target-python-version 3.8 \ --output src/hera/events/models \ - --base-class hera.shared._base_model.BaseModel \ + --output-model-type pydantic.BaseModel \ + --base-class hera.shared._pydantic.BaseModel \ + --input-file-type jsonschema \ --wrap-string-literal \ --disable-appending-item-suffix \ --disable-timestamp \ --use-default-kwarg + @find src/hera/events/models/ -name '*.py' -exec sed -i.bak 's/from pydantic import Field/from hera.shared._pydantic import Field/' {} + + @find src/hera/events/models/ -name '*.bak' -delete @poetry run python scripts/models.py $(OPENAPI_SPEC_URL) events @poetry run stubgen -o src -p hera.events.models && find src/hera/events/models -name '__init__.pyi' -delete @rm $(SPEC_PATH) diff --git a/docs/examples/workflows/scripts/callable_script.md b/docs/examples/workflows/scripts/callable_script.md index 6b5f9a5f8..59a7e8a6a 100644 --- a/docs/examples/workflows/scripts/callable_script.md +++ b/docs/examples/workflows/scripts/callable_script.md @@ -10,6 +10,8 @@ ```python linenums="1" from typing import List, Union + from hera.shared.serialization import serialize + try: from typing import Annotated # type: ignore except ImportError: @@ -99,7 +101,7 @@ with Workflow(name="my-workflow") as w: with Steps(name="my-steps") as s: my_function(arguments={"input": Input(a=2, b="bar", c=42)}) - str_function(arguments={"input": Input(a=2, b="bar", c=42).json()}) + str_function(arguments={"input": serialize(Input(a=2, b="bar", c=42))}) another_function(arguments={"inputs": [Input(a=2, b="bar", c=42), Input(a=2, b="bar", c=42.0)]}) function_kebab(arguments={"a-but-kebab": 3, "b-but-kebab": "bar"}) function_kebab_object(arguments={"input-value": Input(a=3, b="bar", c="42")}) diff --git a/examples/workflows/scripts/callable_script.py b/examples/workflows/scripts/callable_script.py index 846f64bcc..b292de79b 100644 --- a/examples/workflows/scripts/callable_script.py +++ b/examples/workflows/scripts/callable_script.py @@ -1,5 +1,7 @@ from typing import List, Union +from hera.shared.serialization import serialize + try: from typing import Annotated # type: ignore except ImportError: @@ -89,7 +91,7 @@ def function_kebab_object(annotated_input_value: Annotated[Input, Parameter(name with Workflow(name="my-workflow") as w: with Steps(name="my-steps") as s: my_function(arguments={"input": Input(a=2, b="bar", c=42)}) - str_function(arguments={"input": Input(a=2, b="bar", c=42).json()}) + str_function(arguments={"input": serialize(Input(a=2, b="bar", c=42))}) another_function(arguments={"inputs": [Input(a=2, b="bar", c=42), Input(a=2, b="bar", c=42.0)]}) function_kebab(arguments={"a-but-kebab": 3, "b-but-kebab": "bar"}) function_kebab_object(arguments={"input-value": Input(a=3, b="bar", c="42")}) diff --git a/poetry.lock b/poetry.lock index 95ea33f91..cdd37316e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,19 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} + [[package]] name = "anyio" version = "3.6.2" @@ -34,24 +48,6 @@ files = [ [package.extras] test = ["coverage", "flake8", "pexpect", "wheel"] -[[package]] -name = "attrs" -version = "22.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.6" -files = [ - {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, - {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, -] - -[package.extras] -cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] -tests = ["attrs[tests-no-zope]", "zope.interface"] -tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] - [[package]] name = "black" version = "23.10.1" @@ -129,17 +125,6 @@ files = [ {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, ] -[[package]] -name = "chardet" -version = "4.0.0" -description = "Universal encoding detector for Python 2 and 3" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, - {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, -] - [[package]] name = "charset-normalizer" version = "3.0.1" @@ -330,40 +315,38 @@ toml = ["tomli"] [[package]] name = "datamodel-code-generator" -version = "0.17.1" +version = "0.25.1" description = "Datamodel Code Generator" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "datamodel_code_generator-0.17.1-py3-none-any.whl", hash = "sha256:8e3bf374dff69ce65e07feed3322f5b83432cc7d3974169865ede69c4b98bf92"}, - {file = "datamodel_code_generator-0.17.1.tar.gz", hash = "sha256:a22e1f71b76c149a0fbb8214f7b1e4926c01bf5bc94ce5264a932d65599fb4a9"}, + {file = "datamodel_code_generator-0.25.1-py3-none-any.whl", hash = "sha256:87fc3585f497fbe194f3b436376955e68dd2d875b0af517d1efef8f36ab29e9c"}, + {file = "datamodel_code_generator-0.25.1.tar.gz", hash = "sha256:1f991527e6433aa08100be60d876303f71e7c33823fbd6b2e54ad344e8928392"}, ] [package.dependencies] -argcomplete = ">=1.10,<3.0" +argcomplete = ">=1.10,<4.0" black = ">=19.10b0" genson = ">=1.2.1,<2.0" httpx = {version = "*", optional = true, markers = "extra == \"http\""} inflect = ">=4.1.0,<6.0" isort = ">=4.3.21,<6.0" jinja2 = ">=2.10.1,<4.0" -openapi-spec-validator = ">=0.2.8,<=0.5.1" packaging = "*" -prance = ">=0.18.2,<1.0" pydantic = [ - {version = ">=1.10.0,<2.0", extras = ["email"], markers = "python_version >= \"3.11\""}, - {version = ">=1.5.1,<2.0", extras = ["email"], markers = "python_version < \"3.10\""}, - {version = ">=1.9.0,<2.0", extras = ["email"], markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, -] -PySnooper = ">=0.4.1,<2.0.0" -toml = ">=0.10.0,<1.0.0" -typed-ast = [ - {version = ">=1.5.0", markers = "python_full_version >= \"3.9.8\""}, - {version = ">=1.4.2", markers = "python_full_version < \"3.9.8\""}, + {version = ">=1.10.0,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.12\" and python_version < \"4.0\""}, + {version = ">=1.10.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=1.5.1,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version < \"3.10\""}, + {version = ">=1.9.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, ] +pyyaml = ">=6.0.1" +toml = {version = ">=0.10.0,<1.0.0", markers = "python_version < \"3.11\""} [package.extras] +debug = ["PySnooper (>=0.4.1,<2.0.0)"] +graphql = ["graphql-core (>=3.2.3,<4.0.0)"] http = ["httpx"] +validation = ["openapi-spec-validator (>=0.2.8,<0.7.0)", "prance (>=0.18.2)"] [[package]] name = "dnspython" @@ -387,17 +370,17 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"] [[package]] name = "email-validator" -version = "1.3.1" +version = "2.1.0.post1" description = "A robust email address syntax and deliverability validation library." optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "email_validator-1.3.1-py2.py3-none-any.whl", hash = "sha256:49a72f5fa6ed26be1c964f0567d931d10bf3fdeeacdf97bc26ef1cd2a44e0bda"}, - {file = "email_validator-1.3.1.tar.gz", hash = "sha256:d178c5c6fa6c6824e9b04f199cf23e79ac15756786573c190d2ad13089411ad2"}, + {file = "email_validator-2.1.0.post1-py3-none-any.whl", hash = "sha256:c973053efbeddfef924dc0bd93f6e77a1ea7ee0fce935aea7103c7a3d6d2d637"}, + {file = "email_validator-2.1.0.post1.tar.gz", hash = "sha256:a4b0bd1cf55f073b924258d19321b1f3aa74b4b5a71a42c305575dba920e1a44"}, ] [package.dependencies] -dnspython = ">=1.15.0" +dnspython = ">=2.0.0" idna = ">=2.0.0" [[package]] @@ -509,24 +492,6 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] -[[package]] -name = "importlib-resources" -version = "5.12.0" -description = "Read resources from Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [[package]] name = "inflect" version = "5.6.2" @@ -601,89 +566,6 @@ files = [ [package.dependencies] ply = "*" -[[package]] -name = "jsonschema" -version = "4.17.3" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] - -[[package]] -name = "jsonschema-spec" -version = "0.1.3" -description = "JSONSchema Spec with object-oriented paths" -optional = false -python-versions = ">=3.7.0,<4.0.0" -files = [ - {file = "jsonschema_spec-0.1.3-py3-none-any.whl", hash = "sha256:b3cde007ad65c2e631e2f8653cf187124a2c714d02d9fafbab68ad64bf5745d6"}, - {file = "jsonschema_spec-0.1.3.tar.gz", hash = "sha256:8d8db7c255e524fab1016a952a9143e5b6e3c074f4ed25d1878f8e97806caec0"}, -] - -[package.dependencies] -jsonschema = ">=4.0.0,<5.0.0" -pathable = ">=0.4.1,<0.5.0" -PyYAML = ">=5.1" -typing-extensions = ">=4.3.0,<5.0.0" - -[[package]] -name = "lazy-object-proxy" -version = "1.9.0" -description = "A fast and thorough lazy object proxy." -optional = false -python-versions = ">=3.7" -files = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, -] - [[package]] name = "markdown-it-py" version = "2.2.0" @@ -835,48 +717,6 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -[[package]] -name = "openapi-schema-validator" -version = "0.3.4" -description = "OpenAPI schema validation for Python" -optional = false -python-versions = ">=3.7.0,<4.0.0" -files = [ - {file = "openapi-schema-validator-0.3.4.tar.gz", hash = "sha256:7cf27585dd7970b7257cefe48e1a3a10d4e34421831bdb472d96967433bc27bd"}, - {file = "openapi_schema_validator-0.3.4-py3-none-any.whl", hash = "sha256:34fbd14b7501abe25e64d7b4624a9db02cde1a578d285b3da6f34b290cdf0b3a"}, -] - -[package.dependencies] -attrs = ">=19.2.0" -jsonschema = ">=4.0.0,<5.0.0" - -[package.extras] -isodate = ["isodate"] -rfc3339-validator = ["rfc3339-validator"] -strict-rfc3339 = ["strict-rfc3339"] - -[[package]] -name = "openapi-spec-validator" -version = "0.5.1" -description = "OpenAPI 2.0 (aka Swagger) and OpenAPI 3 spec validator" -optional = false -python-versions = ">=3.7.0,<4.0.0" -files = [ - {file = "openapi-spec-validator-0.5.1.tar.gz", hash = "sha256:8248634bad1f23cac5d5a34e193ab36e23914057ca69e91a1ede5af75552c465"}, - {file = "openapi_spec_validator-0.5.1-py3-none-any.whl", hash = "sha256:4a8aee1e45b1ac868e07ab25e18828fe9837baddd29a8e20fdb3d3c61c8eea3d"}, -] - -[package.dependencies] -importlib-resources = ">=5.8.0,<6.0.0" -jsonschema = ">=4.0.0,<5.0.0" -jsonschema-spec = ">=0.1.1,<0.2.0" -lazy-object-proxy = ">=1.7.1,<2.0.0" -openapi-schema-validator = ">=0.3.2,<0.4.0" -PyYAML = ">=5.1" - -[package.extras] -requests = ["requests"] - [[package]] name = "packaging" version = "23.0" @@ -888,17 +728,6 @@ files = [ {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, ] -[[package]] -name = "pathable" -version = "0.4.3" -description = "Object-oriented paths" -optional = false -python-versions = ">=3.7.0,<4.0.0" -files = [ - {file = "pathable-0.4.3-py3-none-any.whl", hash = "sha256:cdd7b1f9d7d5c8b8d3315dbf5a86b2596053ae845f056f57d97c0eefff84da14"}, - {file = "pathable-0.4.3.tar.gz", hash = "sha256:5c869d315be50776cc8a993f3af43e0c60dc01506b399643f919034ebf4cdcab"}, -] - [[package]] name = "pathspec" version = "0.11.0" @@ -910,17 +739,6 @@ files = [ {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, ] -[[package]] -name = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, -] - [[package]] name = "platformdirs" version = "3.0.0" @@ -974,83 +792,141 @@ files = [ ] [[package]] -name = "prance" -version = "0.21.8.0" -description = "Resolving Swagger/OpenAPI 2.0 and 3.0.0 Parser" +name = "pydantic" +version = "2.5.2" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "prance-0.21.8.0-py3-none-any.whl", hash = "sha256:51ec41d10b317bf5d4e74782a7f7f0c0488c6042433b5b4fde2a988cd069d235"}, - {file = "prance-0.21.8.0.tar.gz", hash = "sha256:ce06feef8814c3436645f3b094e91067b1a111bc860a51f239f93437a8d4b00e"}, + {file = "pydantic-2.5.2-py3-none-any.whl", hash = "sha256:80c50fb8e3dcecfddae1adbcc00ec5822918490c99ab31f6cf6140ca1c1429f0"}, + {file = "pydantic-2.5.2.tar.gz", hash = "sha256:ff177ba64c6faf73d7afa2e8cad38fd456c0dbe01c9954e71038001cd15a6edd"}, ] [package.dependencies] -chardet = ">=3.0,<5.0" -requests = ">=2.25,<3.0" -"ruamel.yaml" = ">=0.17.10,<0.18.0" -semver = ">=2.13,<3.0" -six = ">=1.15,<2.0" +annotated-types = ">=0.4.0" +email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""} +pydantic-core = "2.14.5" +typing-extensions = ">=4.6.1" [package.extras] -cli = ["click (>=7.0,<8.0)"] -dev = ["bumpversion (>=0.6)", "pytest (>=6.1)", "pytest-cov (>=2.11)", "sphinx (>=3.4)", "towncrier (>=19.2)", "tox (>=3.4)"] -flex = ["flex (>=6.13,<7.0)"] -icu = ["PyICU (>=2.4,<3.0)"] -osv = ["openapi-spec-validator (>=0.2.1)"] -ssv = ["swagger-spec-validator (>=2.4,<3.0)"] +email = ["email-validator (>=2.0.0)"] [[package]] -name = "pydantic" -version = "1.10.13" -description = "Data validation and settings management using python type hints" +name = "pydantic-core" +version = "2.14.5" +description = "" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, - {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, - {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, - {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, - {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, - {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, - {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, - {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, - {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, - {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, + {file = "pydantic_core-2.14.5-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:7e88f5696153dc516ba6e79f82cc4747e87027205f0e02390c21f7cb3bd8abfd"}, + {file = "pydantic_core-2.14.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4641e8ad4efb697f38a9b64ca0523b557c7931c5f84e0fd377a9a3b05121f0de"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:774de879d212db5ce02dfbf5b0da9a0ea386aeba12b0b95674a4ce0593df3d07"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ebb4e035e28f49b6f1a7032920bb9a0c064aedbbabe52c543343d39341a5b2a3"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b53e9ad053cd064f7e473a5f29b37fc4cc9dc6d35f341e6afc0155ea257fc911"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aa1768c151cf562a9992462239dfc356b3d1037cc5a3ac829bb7f3bda7cc1f9"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eac5c82fc632c599f4639a5886f96867ffced74458c7db61bc9a66ccb8ee3113"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae91f50ccc5810b2f1b6b858257c9ad2e08da70bf890dee02de1775a387c66"}, + {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6b9ff467ffbab9110e80e8c8de3bcfce8e8b0fd5661ac44a09ae5901668ba997"}, + {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61ea96a78378e3bd5a0be99b0e5ed00057b71f66115f5404d0dae4819f495093"}, + {file = "pydantic_core-2.14.5-cp310-none-win32.whl", hash = "sha256:bb4c2eda937a5e74c38a41b33d8c77220380a388d689bcdb9b187cf6224c9720"}, + {file = "pydantic_core-2.14.5-cp310-none-win_amd64.whl", hash = "sha256:b7851992faf25eac90bfcb7bfd19e1f5ffa00afd57daec8a0042e63c74a4551b"}, + {file = "pydantic_core-2.14.5-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:4e40f2bd0d57dac3feb3a3aed50f17d83436c9e6b09b16af271b6230a2915459"}, + {file = "pydantic_core-2.14.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab1cdb0f14dc161ebc268c09db04d2c9e6f70027f3b42446fa11c153521c0e88"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aae7ea3a1c5bb40c93cad361b3e869b180ac174656120c42b9fadebf685d121b"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60b7607753ba62cf0739177913b858140f11b8af72f22860c28eabb2f0a61937"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2248485b0322c75aee7565d95ad0e16f1c67403a470d02f94da7344184be770f"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:823fcc638f67035137a5cd3f1584a4542d35a951c3cc68c6ead1df7dac825c26"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96581cfefa9123accc465a5fd0cc833ac4d75d55cc30b633b402e00e7ced00a6"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a33324437018bf6ba1bb0f921788788641439e0ed654b233285b9c69704c27b4"}, + {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9bd18fee0923ca10f9a3ff67d4851c9d3e22b7bc63d1eddc12f439f436f2aada"}, + {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:853a2295c00f1d4429db4c0fb9475958543ee80cfd310814b5c0ef502de24dda"}, + {file = "pydantic_core-2.14.5-cp311-none-win32.whl", hash = "sha256:cb774298da62aea5c80a89bd58c40205ab4c2abf4834453b5de207d59d2e1651"}, + {file = "pydantic_core-2.14.5-cp311-none-win_amd64.whl", hash = "sha256:e87fc540c6cac7f29ede02e0f989d4233f88ad439c5cdee56f693cc9c1c78077"}, + {file = "pydantic_core-2.14.5-cp311-none-win_arm64.whl", hash = "sha256:57d52fa717ff445cb0a5ab5237db502e6be50809b43a596fb569630c665abddf"}, + {file = "pydantic_core-2.14.5-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:e60f112ac88db9261ad3a52032ea46388378034f3279c643499edb982536a093"}, + {file = "pydantic_core-2.14.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6e227c40c02fd873c2a73a98c1280c10315cbebe26734c196ef4514776120aeb"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0cbc7fff06a90bbd875cc201f94ef0ee3929dfbd5c55a06674b60857b8b85ed"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:103ef8d5b58596a731b690112819501ba1db7a36f4ee99f7892c40da02c3e189"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c949f04ecad823f81b1ba94e7d189d9dfb81edbb94ed3f8acfce41e682e48cef"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1452a1acdf914d194159439eb21e56b89aa903f2e1c65c60b9d874f9b950e5d"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb4679d4c2b089e5ef89756bc73e1926745e995d76e11925e3e96a76d5fa51fc"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf9d3fe53b1ee360e2421be95e62ca9b3296bf3f2fb2d3b83ca49ad3f925835e"}, + {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:70f4b4851dbb500129681d04cc955be2a90b2248d69273a787dda120d5cf1f69"}, + {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:59986de5710ad9613ff61dd9b02bdd2f615f1a7052304b79cc8fa2eb4e336d2d"}, + {file = "pydantic_core-2.14.5-cp312-none-win32.whl", hash = "sha256:699156034181e2ce106c89ddb4b6504c30db8caa86e0c30de47b3e0654543260"}, + {file = "pydantic_core-2.14.5-cp312-none-win_amd64.whl", hash = "sha256:5baab5455c7a538ac7e8bf1feec4278a66436197592a9bed538160a2e7d11e36"}, + {file = "pydantic_core-2.14.5-cp312-none-win_arm64.whl", hash = "sha256:e47e9a08bcc04d20975b6434cc50bf82665fbc751bcce739d04a3120428f3e27"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:af36f36538418f3806048f3b242a1777e2540ff9efaa667c27da63d2749dbce0"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:45e95333b8418ded64745f14574aa9bfc212cb4fbeed7a687b0c6e53b5e188cd"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e47a76848f92529879ecfc417ff88a2806438f57be4a6a8bf2961e8f9ca9ec7"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d81e6987b27bc7d101c8597e1cd2bcaa2fee5e8e0f356735c7ed34368c471550"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34708cc82c330e303f4ce87758828ef6e457681b58ce0e921b6e97937dd1e2a3"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:652c1988019752138b974c28f43751528116bcceadad85f33a258869e641d753"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e4d090e73e0725b2904fdbdd8d73b8802ddd691ef9254577b708d413bf3006e"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5c7d5b5005f177764e96bd584d7bf28d6e26e96f2a541fdddb934c486e36fd59"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a71891847f0a73b1b9eb86d089baee301477abef45f7eaf303495cd1473613e4"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a717aef6971208f0851a2420b075338e33083111d92041157bbe0e2713b37325"}, + {file = "pydantic_core-2.14.5-cp37-none-win32.whl", hash = "sha256:de790a3b5aa2124b8b78ae5faa033937a72da8efe74b9231698b5a1dd9be3405"}, + {file = "pydantic_core-2.14.5-cp37-none-win_amd64.whl", hash = "sha256:6c327e9cd849b564b234da821236e6bcbe4f359a42ee05050dc79d8ed2a91588"}, + {file = "pydantic_core-2.14.5-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:ef98ca7d5995a82f43ec0ab39c4caf6a9b994cb0b53648ff61716370eadc43cf"}, + {file = "pydantic_core-2.14.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6eae413494a1c3f89055da7a5515f32e05ebc1a234c27674a6956755fb2236f"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcf4e6d85614f7a4956c2de5a56531f44efb973d2fe4a444d7251df5d5c4dcfd"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6637560562134b0e17de333d18e69e312e0458ee4455bdad12c37100b7cad706"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77fa384d8e118b3077cccfcaf91bf83c31fe4dc850b5e6ee3dc14dc3d61bdba1"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16e29bad40bcf97aac682a58861249ca9dcc57c3f6be22f506501833ddb8939c"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531f4b4252fac6ca476fbe0e6f60f16f5b65d3e6b583bc4d87645e4e5ddde331"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:074f3d86f081ce61414d2dc44901f4f83617329c6f3ab49d2bc6c96948b2c26b"}, + {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c2adbe22ab4babbca99c75c5d07aaf74f43c3195384ec07ccbd2f9e3bddaecec"}, + {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0f6116a558fd06d1b7c2902d1c4cf64a5bd49d67c3540e61eccca93f41418124"}, + {file = "pydantic_core-2.14.5-cp38-none-win32.whl", hash = "sha256:fe0a5a1025eb797752136ac8b4fa21aa891e3d74fd340f864ff982d649691867"}, + {file = "pydantic_core-2.14.5-cp38-none-win_amd64.whl", hash = "sha256:079206491c435b60778cf2b0ee5fd645e61ffd6e70c47806c9ed51fc75af078d"}, + {file = "pydantic_core-2.14.5-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a6a16f4a527aae4f49c875da3cdc9508ac7eef26e7977952608610104244e1b7"}, + {file = "pydantic_core-2.14.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:abf058be9517dc877227ec3223f0300034bd0e9f53aebd63cf4456c8cb1e0863"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b08aae5013640a3bfa25a8eebbd95638ec3f4b2eaf6ed82cf0c7047133f03b"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2d97e906b4ff36eb464d52a3bc7d720bd6261f64bc4bcdbcd2c557c02081ed2"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3128e0bbc8c091ec4375a1828d6118bc20404883169ac95ffa8d983b293611e6"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88e74ab0cdd84ad0614e2750f903bb0d610cc8af2cc17f72c28163acfcf372a4"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c339dabd8ee15f8259ee0f202679b6324926e5bc9e9a40bf981ce77c038553db"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3387277f1bf659caf1724e1afe8ee7dbc9952a82d90f858ebb931880216ea955"}, + {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ba6b6b3846cfc10fdb4c971980a954e49d447cd215ed5a77ec8190bc93dd7bc5"}, + {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca61d858e4107ce5e1330a74724fe757fc7135190eb5ce5c9d0191729f033209"}, + {file = "pydantic_core-2.14.5-cp39-none-win32.whl", hash = "sha256:ec1e72d6412f7126eb7b2e3bfca42b15e6e389e1bc88ea0069d0cc1742f477c6"}, + {file = "pydantic_core-2.14.5-cp39-none-win_amd64.whl", hash = "sha256:c0b97ec434041827935044bbbe52b03d6018c2897349670ff8fe11ed24d1d4ab"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79e0a2cdbdc7af3f4aee3210b1172ab53d7ddb6a2d8c24119b5706e622b346d0"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:678265f7b14e138d9a541ddabbe033012a2953315739f8cfa6d754cc8063e8ca"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b15e855ae44f0c6341ceb74df61b606e11f1087e87dcb7482377374aac6abe"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09b0e985fbaf13e6b06a56d21694d12ebca6ce5414b9211edf6f17738d82b0f8"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ad873900297bb36e4b6b3f7029d88ff9829ecdc15d5cf20161775ce12306f8a"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2d0ae0d8670164e10accbeb31d5ad45adb71292032d0fdb9079912907f0085f4"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d37f8ec982ead9ba0a22a996129594938138a1503237b87318392a48882d50b7"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:35613015f0ba7e14c29ac6c2483a657ec740e5ac5758d993fdd5870b07a61d8b"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab4ea451082e684198636565224bbb179575efc1658c48281b2c866bfd4ddf04"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ce601907e99ea5b4adb807ded3570ea62186b17f88e271569144e8cca4409c7"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb2ed8b3fe4bf4506d6dab3b93b83bbc22237e230cba03866d561c3577517d18"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70f947628e074bb2526ba1b151cee10e4c3b9670af4dbb4d73bc8a89445916b5"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4bc536201426451f06f044dfbf341c09f540b4ebdb9fd8d2c6164d733de5e634"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4791cf0f8c3104ac668797d8c514afb3431bc3305f5638add0ba1a5a37e0d88"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:038c9f763e650712b899f983076ce783175397c848da04985658e7628cbe873b"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:27548e16c79702f1e03f5628589c6057c9ae17c95b4c449de3c66b589ead0520"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97bee68898f3f4344eb02fec316db93d9700fb1e6a5b760ffa20d71d9a46ce3"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9b759b77f5337b4ea024f03abc6464c9f35d9718de01cfe6bae9f2e139c397e"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:439c9afe34638ace43a49bf72d201e0ffc1a800295bed8420c2a9ca8d5e3dbb3"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ba39688799094c75ea8a16a6b544eb57b5b0f3328697084f3f2790892510d144"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ccd4d5702bb90b84df13bd491be8d900b92016c5a455b7e14630ad7449eb03f8"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:81982d78a45d1e5396819bbb4ece1fadfe5f079335dd28c4ab3427cd95389944"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:7f8210297b04e53bc3da35db08b7302a6a1f4889c79173af69b72ec9754796b8"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:8c8a8812fe6f43a3a5b054af6ac2d7b8605c7bcab2804a8a7d68b53f3cd86e00"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:206ed23aecd67c71daf5c02c3cd19c0501b01ef3cbf7782db9e4e051426b3d0d"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2027d05c8aebe61d898d4cffd774840a9cb82ed356ba47a90d99ad768f39789"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40180930807ce806aa71eda5a5a5447abb6b6a3c0b4b3b1b1962651906484d68"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:615a0a4bff11c45eb3c1996ceed5bdaa2f7b432425253a7c2eed33bb86d80abc"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5e412d717366e0677ef767eac93566582518fe8be923361a5c204c1a62eaafe"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:513b07e99c0a267b1d954243845d8a833758a6726a3b5d8948306e3fe14675e3"}, + {file = "pydantic_core-2.14.5.tar.gz", hash = "sha256:6d30226dfc816dd0fdf120cae611dd2215117e4f9b124af8c60ab9093b6e8e71"}, ] [package.dependencies] -email-validator = {version = ">=1.0.3", optional = true, markers = "extra == \"email\""} -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pygments" @@ -1080,56 +956,6 @@ files = [ [package.dependencies] tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -[[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, - {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, - {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, - {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, - {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, - {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, -] - -[[package]] -name = "pysnooper" -version = "1.1.1" -description = "A poor man's debugger for Python." -optional = false -python-versions = "*" -files = [ - {file = "PySnooper-1.1.1-py2.py3-none-any.whl", hash = "sha256:378f13d731a3e04d3d0350e5f295bdd0f1b49fc8a8b8bf2067fe1e5290bd20be"}, - {file = "PySnooper-1.1.1.tar.gz", hash = "sha256:d17dc91cca1593c10230dce45e46b1d3ff0f8910f0c38e941edf6ba1260b3820"}, -] - -[package.extras] -tests = ["pytest"] - [[package]] name = "pytest" version = "7.4.3" @@ -1320,70 +1146,6 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] -[[package]] -name = "ruamel-yaml" -version = "0.17.21" -description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -optional = false -python-versions = ">=3" -files = [ - {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, - {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, -] - -[package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""} - -[package.extras] -docs = ["ryd"] -jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] - -[[package]] -name = "ruamel-yaml-clib" -version = "0.2.7" -description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -optional = false -python-versions = ">=3.5" -files = [ - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, - {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, -] - [[package]] name = "ruff" version = "0.1.6" @@ -1410,28 +1172,6 @@ files = [ {file = "ruff-0.1.6.tar.gz", hash = "sha256:1b09f29b16c6ead5ea6b097ef2764b42372aebe363722f1605ecbcd2b9207184"}, ] -[[package]] -name = "semver" -version = "2.13.0" -description = "Python helper for Semantic Versioning (http://semver.org/)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"}, - {file = "semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"}, -] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - [[package]] name = "sniffio" version = "1.3.0" @@ -1479,39 +1219,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "typed-ast" -version = "1.5.4" -description = "a fork of Python 2 and 3 ast modules with type comment support" -optional = false -python-versions = ">=3.6" -files = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, -] - [[package]] name = "types-pyyaml" version = "6.0.12.12" @@ -1586,4 +1293,4 @@ yaml = ["pyyaml"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4" -content-hash = "e99508660749ca44ba7238aadb11c16f5259fda31c6afbeb40c39c52765f2541" +content-hash = "39e6d613c78bec0d54b499de1a1b78525f440f472f1dbe6fe631329c27c19234" diff --git a/pyproject.toml b/pyproject.toml index 5ba4a770c..bd656f4f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ packages = [ python = ">=3.8,<4" pyyaml = { version = ">=6.0", optional = true } requests = "*" -pydantic = {extras = ["email"], version = ">=1.7,<2.0"} +pydantic = { extras = ["email"], version = ">=1.7,<3.0" } [tool.poetry.extras] yaml = ["PyYAML"] @@ -45,7 +45,7 @@ build = "*" ruff = "*" types-PyYAML = "*" jsonpath-ng = "^1.5.3" -datamodel-code-generator = {extras = ["http"], version = "^0.17.1"} +datamodel-code-generator = { extras = ["http"], version = "^0.25" } types-requests = "^2.28.11.12" pytest-clarity = "^1.0.1" pytest-sugar = "^0.9.6" @@ -136,4 +136,4 @@ combine-as-imports = true known-first-party = ["hera"] [tool.ruff.pydocstyle] -convention = "google" \ No newline at end of file +convention = "google" diff --git a/scripts/models.py b/scripts/models.py index 7519e49dc..48b18e2c7 100644 --- a/scripts/models.py +++ b/scripts/models.py @@ -159,3 +159,4 @@ def ensure_init(): root_path = assemble_root_path_from_models_type(models_type) imports = get_import_paths_from_refs(filtered_refs, root_path) write_imports(imports, models_type, openapi_spec_url) + ensure_init() diff --git a/src/hera/events/models/eventsource.py b/src/hera/events/models/eventsource.py index 3c580efe4..590725380 100644 --- a/src/hera/events/models/eventsource.py +++ b/src/hera/events/models/eventsource.py @@ -5,9 +5,7 @@ from typing import Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from .io.argoproj.events import v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 diff --git a/src/hera/events/models/eventsource.pyi b/src/hera/events/models/eventsource.pyi index 6a6eb9f8d..a8ad2eef6 100644 --- a/src/hera/events/models/eventsource.pyi +++ b/src/hera/events/models/eventsource.pyi @@ -1,6 +1,9 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from .io.argoproj.events import v1alpha1 as v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 as v1 diff --git a/src/hera/events/models/google/protobuf.py b/src/hera/events/models/google/protobuf.py index 0bb982e04..8e161b69e 100644 --- a/src/hera/events/models/google/protobuf.py +++ b/src/hera/events/models/google/protobuf.py @@ -5,7 +5,7 @@ from typing import Optional -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel class Any(BaseModel): diff --git a/src/hera/events/models/google/protobuf.pyi b/src/hera/events/models/google/protobuf.pyi index 54a09fbaf..8b3b94c4f 100644 --- a/src/hera/events/models/google/protobuf.pyi +++ b/src/hera/events/models/google/protobuf.pyi @@ -1,6 +1,6 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import BaseModel as BaseModel class Any(BaseModel): type_url: Optional[str] diff --git a/src/hera/events/models/grpc/gateway/runtime.py b/src/hera/events/models/grpc/gateway/runtime.py index a4106a4ca..62bfffbfa 100644 --- a/src/hera/events/models/grpc/gateway/runtime.py +++ b/src/hera/events/models/grpc/gateway/runtime.py @@ -5,7 +5,7 @@ from typing import List, Optional -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel from ...google import protobuf diff --git a/src/hera/events/models/grpc/gateway/runtime.pyi b/src/hera/events/models/grpc/gateway/runtime.pyi index 6f34eadc7..c032edf27 100644 --- a/src/hera/events/models/grpc/gateway/runtime.pyi +++ b/src/hera/events/models/grpc/gateway/runtime.pyi @@ -1,6 +1,6 @@ from typing import List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import BaseModel as BaseModel from ...google import protobuf as protobuf diff --git a/src/hera/events/models/io/argoproj/events/v1alpha1.py b/src/hera/events/models/io/argoproj/events/v1alpha1.py index 6e7b83f33..5f31f1388 100644 --- a/src/hera/events/models/io/argoproj/events/v1alpha1.py +++ b/src/hera/events/models/io/argoproj/events/v1alpha1.py @@ -5,9 +5,7 @@ from typing import Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...k8s.api.core import v1 from ...k8s.apimachinery.pkg.apis.meta import v1 as v1_1 diff --git a/src/hera/events/models/io/argoproj/events/v1alpha1.pyi b/src/hera/events/models/io/argoproj/events/v1alpha1.pyi index 3c58b9ff6..e0192ca9b 100644 --- a/src/hera/events/models/io/argoproj/events/v1alpha1.pyi +++ b/src/hera/events/models/io/argoproj/events/v1alpha1.pyi @@ -1,6 +1,9 @@ from typing import Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...k8s.api.core import v1 as v1 from ...k8s.apimachinery.pkg.apis.meta import v1 as v1_1 diff --git a/src/hera/events/models/io/argoproj/workflow/v1alpha1.py b/src/hera/events/models/io/argoproj/workflow/v1alpha1.py index eef754bce..f3d46ad52 100644 --- a/src/hera/events/models/io/argoproj/workflow/v1alpha1.py +++ b/src/hera/events/models/io/argoproj/workflow/v1alpha1.py @@ -5,9 +5,7 @@ from typing import Any, Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...k8s.api.core import v1 from ...k8s.api.policy import v1beta1 diff --git a/src/hera/events/models/io/argoproj/workflow/v1alpha1.pyi b/src/hera/events/models/io/argoproj/workflow/v1alpha1.pyi index 3fbb63678..09c3fff3b 100644 --- a/src/hera/events/models/io/argoproj/workflow/v1alpha1.pyi +++ b/src/hera/events/models/io/argoproj/workflow/v1alpha1.pyi @@ -1,6 +1,9 @@ from typing import Any, Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...k8s.api.core import v1 as v1 from ...k8s.api.policy import v1beta1 as v1beta1 diff --git a/src/hera/events/models/io/k8s/api/core/v1.py b/src/hera/events/models/io/k8s/api/core/v1.py index 3c30099ae..1d1b69b6f 100644 --- a/src/hera/events/models/io/k8s/api/core/v1.py +++ b/src/hera/events/models/io/k8s/api/core/v1.py @@ -6,9 +6,7 @@ from enum import Enum from typing import Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...apimachinery.pkg.api import resource from ...apimachinery.pkg.apis.meta import v1 diff --git a/src/hera/events/models/io/k8s/api/core/v1.pyi b/src/hera/events/models/io/k8s/api/core/v1.pyi index b9aef9dac..bb112abd7 100644 --- a/src/hera/events/models/io/k8s/api/core/v1.pyi +++ b/src/hera/events/models/io/k8s/api/core/v1.pyi @@ -1,7 +1,10 @@ from enum import Enum from typing import Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...apimachinery.pkg.api import resource as resource from ...apimachinery.pkg.apis.meta import v1 as v1 diff --git a/src/hera/events/models/io/k8s/api/policy/v1beta1.py b/src/hera/events/models/io/k8s/api/policy/v1beta1.py index e789c3e3f..3df7c5731 100644 --- a/src/hera/events/models/io/k8s/api/policy/v1beta1.py +++ b/src/hera/events/models/io/k8s/api/policy/v1beta1.py @@ -5,9 +5,7 @@ from typing import Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...apimachinery.pkg.apis.meta import v1 from ...apimachinery.pkg.util import intstr diff --git a/src/hera/events/models/io/k8s/api/policy/v1beta1.pyi b/src/hera/events/models/io/k8s/api/policy/v1beta1.pyi index 471065d56..bb510518f 100644 --- a/src/hera/events/models/io/k8s/api/policy/v1beta1.pyi +++ b/src/hera/events/models/io/k8s/api/policy/v1beta1.pyi @@ -1,6 +1,9 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...apimachinery.pkg.apis.meta import v1 as v1 from ...apimachinery.pkg.util import intstr as intstr diff --git a/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.py b/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.py index 2f22d13e6..d5ac8d261 100644 --- a/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.py +++ b/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.py @@ -3,9 +3,7 @@ from __future__ import annotations -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field class Quantity(BaseModel): diff --git a/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.pyi b/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.pyi index 8cb1ae92f..62e5f6b47 100644 --- a/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.pyi +++ b/src/hera/events/models/io/k8s/apimachinery/pkg/api/resource.pyi @@ -1,4 +1,7 @@ -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) class Quantity(BaseModel): __root__: str diff --git a/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.py b/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.py index 0cc3efac5..c42be1cd0 100644 --- a/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.py +++ b/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.py @@ -6,9 +6,7 @@ from datetime import datetime from typing import Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field class CreateOptions(BaseModel): diff --git a/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi b/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi index 5c25dfa7b..17085cef1 100644 --- a/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi +++ b/src/hera/events/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi @@ -1,7 +1,10 @@ from datetime import datetime from typing import Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) class CreateOptions(BaseModel): dry_run: Optional[List[str]] diff --git a/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.py b/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.py index 640b9b045..592fcbd0c 100644 --- a/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.py +++ b/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.py @@ -3,7 +3,7 @@ from __future__ import annotations -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel class IntOrString(BaseModel): diff --git a/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.pyi b/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.pyi index 4ed64fd53..6f9697c73 100644 --- a/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.pyi +++ b/src/hera/events/models/io/k8s/apimachinery/pkg/util/intstr.pyi @@ -1,4 +1,4 @@ -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import BaseModel as BaseModel class IntOrString(BaseModel): __root__: str diff --git a/src/hera/events/models/sensor.py b/src/hera/events/models/sensor.py index f42b1d304..174300031 100644 --- a/src/hera/events/models/sensor.py +++ b/src/hera/events/models/sensor.py @@ -5,9 +5,7 @@ from typing import Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from .io.argoproj.events import v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 diff --git a/src/hera/events/models/sensor.pyi b/src/hera/events/models/sensor.pyi index 5baaafad4..88ebbf238 100644 --- a/src/hera/events/models/sensor.pyi +++ b/src/hera/events/models/sensor.pyi @@ -1,6 +1,9 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from .io.argoproj.events import v1alpha1 as v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 as v1 diff --git a/src/hera/shared/_base_model.py b/src/hera/shared/_base_model.py deleted file mode 100644 index b7164d8c0..000000000 --- a/src/hera/shared/_base_model.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Module that holds the underlying base Pydantic models for Hera objects.""" -from pydantic import BaseModel as PyBaseModel - - -class BaseModel(PyBaseModel): - class Config: - """Config class dictates the behavior of the underlying Pydantic model. - - See Pydantic documentation for more info. - """ - - allow_population_by_field_name = True - """support populating Hera object fields via keyed dictionaries""" - - allow_mutation = True - """supports mutating Hera objects post instantiation""" - - use_enum_values = True - """supports using enums, which are then unpacked to obtain the actual `.value`, on Hera objects""" - - arbitrary_types_allowed = True - """supports specifying arbitrary types for any field to support Hera object fields processing""" - - smart_union = True - """uses smart union for matching a field's specified value to the underlying type that's part of a union""" diff --git a/src/hera/shared/_global_config.py b/src/hera/shared/_global_config.py index 0002caf16..205868e52 100644 --- a/src/hera/shared/_global_config.py +++ b/src/hera/shared/_global_config.py @@ -6,11 +6,8 @@ from dataclasses import dataclass, field from typing import Any, Callable, Dict, List, Optional, Type, TypeVar, Union -from pydantic import root_validator - from hera.auth import TokenGenerator - -from ._base_model import BaseModel +from hera.shared._pydantic import BaseModel, root_validator TBase = TypeVar("TBase", bound="BaseMixin") TypeTBase = Type[TBase] diff --git a/src/hera/shared/_pydantic.py b/src/hera/shared/_pydantic.py new file mode 100644 index 000000000..d7ed54142 --- /dev/null +++ b/src/hera/shared/_pydantic.py @@ -0,0 +1,66 @@ +"""Module that holds the underlying base Pydantic models for Hera objects.""" +from functools import partial + +_PYDANTIC_VERSION = 1 +# The pydantic v1 interface is used for both pydantic v1 and v2 in order to support +# users across both versions. + +try: + from pydantic import ( # type: ignore + validate_call as validate_arguments, + ) + from pydantic.v1 import ( # type: ignore + BaseModel as PydanticBaseModel, + Field, + ValidationError, + root_validator, + validator, + ) + + _PYDANTIC_VERSION = 2 +except (ImportError, ModuleNotFoundError): + from pydantic import ( # type: ignore[assignment,no-redef] + BaseModel as PydanticBaseModel, + Field, + ValidationError, + root_validator, + validate_arguments as validate_call, + validator, + ) + + validate_arguments = partial(validate_call, config=dict(smart_union=True)) # type: ignore + _PYDANTIC_VERSION = 1 + + +__all__ = [ + "BaseModel", + "Field", + "PydanticBaseModel", # Export for serialization.py to cover user-defined models + "ValidationError", + "root_validator", + "validate_arguments", + "validator", +] + + +class BaseModel(PydanticBaseModel): + class Config: + """Config class dictates the behavior of the underlying Pydantic model. + + See Pydantic documentation for more info. + """ + + allow_population_by_field_name = True + """support populating Hera object fields via keyed dictionaries""" + + allow_mutation = True + """supports mutating Hera objects post instantiation""" + + use_enum_values = True + """supports using enums, which are then unpacked to obtain the actual `.value`, on Hera objects""" + + arbitrary_types_allowed = True + """supports specifying arbitrary types for any field to support Hera object fields processing""" + + smart_union = True + """uses smart union for matching a field's specified value to the underlying type that's part of a union""" diff --git a/src/hera/shared/serialization.py b/src/hera/shared/serialization.py index 8bfd886ca..e6c45f242 100644 --- a/src/hera/shared/serialization.py +++ b/src/hera/shared/serialization.py @@ -5,11 +5,20 @@ from pydantic import BaseModel +# NOTE: Use the original BaseModel in order to support serializing user-defined models, +# for hera internal models, we still need to support v1 base models. +from hera.shared._pydantic import _PYDANTIC_VERSION + +try: + from pydantic.v1 import BaseModel as V1BaseModel # type: ignore +except (ImportError, ModuleNotFoundError): + V1BaseModel = None # type: ignore + MISSING = object() -"""`MISSING` is a placeholder that indicates field value nullity. +"""`MISSING` is a placeholder that indicates field value nullity. When the user of a Hera object sets the field of an object specifically to `None`, Hera needs to distinguish between -default nullity/None and user-provided `None` on, say, something like the `source` of `Script`. +default nullity/None and user-provided `None` on, say, something like the `source` of `Script`. """ @@ -18,8 +27,17 @@ class PydanticEncoder(JSONEncoder): def default(self, o: Any): """Return the default representation of the given object.""" - if isinstance(o, BaseModel): - return o.dict(by_alias=True) + # Note that these are slightly different outputs b/w v1 and v2 + # v1 will give the actual python object whereas v2 will serialize it into + # a json compatible format. + if _PYDANTIC_VERSION == 1: + if isinstance(o, BaseModel): + return o.dict(by_alias=True) + else: + if isinstance(o, BaseModel): + return o.model_dump(by_alias=True, mode="json") # type: ignore + if isinstance(o, V1BaseModel): + return o.dict(by_alias=True) return super().default(o) diff --git a/src/hera/workflows/_mixins.py b/src/hera/workflows/_mixins.py index a7d77d2c2..10ff55ee0 100644 --- a/src/hera/workflows/_mixins.py +++ b/src/hera/workflows/_mixins.py @@ -18,10 +18,8 @@ except ImportError: from typing_extensions import Annotated, get_args, get_origin # type: ignore -from pydantic import root_validator, validator - from hera.shared import BaseMixin, global_config -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, root_validator, validator from hera.shared.serialization import serialize from hera.workflows._context import SubNodeMixin, _context from hera.workflows.artifact import Artifact @@ -384,7 +382,7 @@ def _build_env(self) -> Optional[List[EnvVar]]: if isinstance(e, EnvVar): result.append(e) elif issubclass(e.__class__, _BaseEnv): - result.append(e.build()) + result.append(e.build()) # type: ignore elif isinstance(e, dict): for k, v in e.items(): result.append(EnvVar(name=k, value=v)) @@ -566,7 +564,7 @@ def _build_volume_mounts(self) -> Optional[List[VolumeMount]]: return None if self.volumes is None: - volumes = [] + volumes: list = [] else: volumes = self.volumes if isinstance(self.volumes, list) else [self.volumes] diff --git a/src/hera/workflows/archive.py b/src/hera/workflows/archive.py index a47f1d2d1..7c4e6793b 100644 --- a/src/hera/workflows/archive.py +++ b/src/hera/workflows/archive.py @@ -1,7 +1,7 @@ """The archive module provides archival behavior strategies for artifacts.""" from typing import Optional -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel from hera.workflows.models import ( ArchiveStrategy as _ModelArchiveStrategy, NoneStrategy as _ModelNoneStrategy, diff --git a/src/hera/workflows/artifact.py b/src/hera/workflows/artifact.py index 0330ecbb0..2cf38322f 100644 --- a/src/hera/workflows/artifact.py +++ b/src/hera/workflows/artifact.py @@ -8,7 +8,7 @@ from enum import Enum from typing import List, Optional, Union, cast -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel from hera.workflows.archive import ArchiveStrategy from hera.workflows.models import ( ArchiveStrategy as _ModelArchiveStrategy, diff --git a/src/hera/workflows/cluster_workflow_template.py b/src/hera/workflows/cluster_workflow_template.py index 67303b49d..3f92651da 100644 --- a/src/hera/workflows/cluster_workflow_template.py +++ b/src/hera/workflows/cluster_workflow_template.py @@ -1,7 +1,6 @@ """Module that provides Hera objects for cluster workflow templates.""" -from pydantic import validator - from hera.exceptions import NotFound +from hera.shared._pydantic import validator from hera.workflows.models import ( ClusterWorkflowTemplate as _ModelClusterWorkflowTemplate, ClusterWorkflowTemplateCreateRequest, diff --git a/src/hera/workflows/cron_workflow.py b/src/hera/workflows/cron_workflow.py index 5a33fb04e..d134ceca0 100644 --- a/src/hera/workflows/cron_workflow.py +++ b/src/hera/workflows/cron_workflow.py @@ -12,7 +12,7 @@ from typing_extensions import Annotated, get_args, get_origin # type: ignore from hera.exceptions import NotFound -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel from hera.workflows._mixins import ( ModelMapperMixin, _get_model_attr, diff --git a/src/hera/workflows/env.py b/src/hera/workflows/env.py index ec306261c..8719da0b7 100644 --- a/src/hera/workflows/env.py +++ b/src/hera/workflows/env.py @@ -5,10 +5,12 @@ from itertools import islice from typing import Any, Optional, Union -from pydantic import root_validator, validator - from hera.shared import global_config -from hera.shared._base_model import BaseModel as _BaseModel +from hera.shared._pydantic import ( + BaseModel as _BaseModel, + root_validator, + validator, +) from hera.workflows.models import ( ConfigMapKeySelector as _ModelConfigMapKeySelector, EnvVar as _ModelEnvVar, diff --git a/src/hera/workflows/env_from.py b/src/hera/workflows/env_from.py index 80338c461..0f03482ca 100644 --- a/src/hera/workflows/env_from.py +++ b/src/hera/workflows/env_from.py @@ -1,7 +1,7 @@ """A module that provides implementations of environment variables that can be created from K8s objects.""" from typing import Optional -from hera.shared._base_model import BaseModel as _BaseModel +from hera.shared._pydantic import BaseModel as _BaseModel from hera.workflows.models import ( ConfigMapEnvSource as _ModelConfigMapEnvSource, EnvFromSource as _ModelEnvFromSource, diff --git a/src/hera/workflows/models/eventsource.py b/src/hera/workflows/models/eventsource.py index 3c580efe4..590725380 100644 --- a/src/hera/workflows/models/eventsource.py +++ b/src/hera/workflows/models/eventsource.py @@ -5,9 +5,7 @@ from typing import Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from .io.argoproj.events import v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 diff --git a/src/hera/workflows/models/eventsource.pyi b/src/hera/workflows/models/eventsource.pyi index 6a6eb9f8d..a8ad2eef6 100644 --- a/src/hera/workflows/models/eventsource.pyi +++ b/src/hera/workflows/models/eventsource.pyi @@ -1,6 +1,9 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from .io.argoproj.events import v1alpha1 as v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 as v1 diff --git a/src/hera/workflows/models/google/protobuf.py b/src/hera/workflows/models/google/protobuf.py index 0bb982e04..8e161b69e 100644 --- a/src/hera/workflows/models/google/protobuf.py +++ b/src/hera/workflows/models/google/protobuf.py @@ -5,7 +5,7 @@ from typing import Optional -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel class Any(BaseModel): diff --git a/src/hera/workflows/models/google/protobuf.pyi b/src/hera/workflows/models/google/protobuf.pyi index 54a09fbaf..8b3b94c4f 100644 --- a/src/hera/workflows/models/google/protobuf.pyi +++ b/src/hera/workflows/models/google/protobuf.pyi @@ -1,6 +1,6 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import BaseModel as BaseModel class Any(BaseModel): type_url: Optional[str] diff --git a/src/hera/workflows/models/grpc/gateway/runtime.py b/src/hera/workflows/models/grpc/gateway/runtime.py index a4106a4ca..62bfffbfa 100644 --- a/src/hera/workflows/models/grpc/gateway/runtime.py +++ b/src/hera/workflows/models/grpc/gateway/runtime.py @@ -5,7 +5,7 @@ from typing import List, Optional -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel from ...google import protobuf diff --git a/src/hera/workflows/models/grpc/gateway/runtime.pyi b/src/hera/workflows/models/grpc/gateway/runtime.pyi index 6f34eadc7..c032edf27 100644 --- a/src/hera/workflows/models/grpc/gateway/runtime.pyi +++ b/src/hera/workflows/models/grpc/gateway/runtime.pyi @@ -1,6 +1,6 @@ from typing import List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import BaseModel as BaseModel from ...google import protobuf as protobuf diff --git a/src/hera/workflows/models/io/argoproj/events/v1alpha1.py b/src/hera/workflows/models/io/argoproj/events/v1alpha1.py index 6e7b83f33..5f31f1388 100644 --- a/src/hera/workflows/models/io/argoproj/events/v1alpha1.py +++ b/src/hera/workflows/models/io/argoproj/events/v1alpha1.py @@ -5,9 +5,7 @@ from typing import Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...k8s.api.core import v1 from ...k8s.apimachinery.pkg.apis.meta import v1 as v1_1 diff --git a/src/hera/workflows/models/io/argoproj/events/v1alpha1.pyi b/src/hera/workflows/models/io/argoproj/events/v1alpha1.pyi index 3c58b9ff6..e0192ca9b 100644 --- a/src/hera/workflows/models/io/argoproj/events/v1alpha1.pyi +++ b/src/hera/workflows/models/io/argoproj/events/v1alpha1.pyi @@ -1,6 +1,9 @@ from typing import Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...k8s.api.core import v1 as v1 from ...k8s.apimachinery.pkg.apis.meta import v1 as v1_1 diff --git a/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.py b/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.py index eef754bce..f3d46ad52 100644 --- a/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.py +++ b/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.py @@ -5,9 +5,7 @@ from typing import Any, Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...k8s.api.core import v1 from ...k8s.api.policy import v1beta1 diff --git a/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.pyi b/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.pyi index 3fbb63678..09c3fff3b 100644 --- a/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.pyi +++ b/src/hera/workflows/models/io/argoproj/workflow/v1alpha1.pyi @@ -1,6 +1,9 @@ from typing import Any, Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...k8s.api.core import v1 as v1 from ...k8s.api.policy import v1beta1 as v1beta1 diff --git a/src/hera/workflows/models/io/k8s/api/core/v1.py b/src/hera/workflows/models/io/k8s/api/core/v1.py index 3c30099ae..1d1b69b6f 100644 --- a/src/hera/workflows/models/io/k8s/api/core/v1.py +++ b/src/hera/workflows/models/io/k8s/api/core/v1.py @@ -6,9 +6,7 @@ from enum import Enum from typing import Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...apimachinery.pkg.api import resource from ...apimachinery.pkg.apis.meta import v1 diff --git a/src/hera/workflows/models/io/k8s/api/core/v1.pyi b/src/hera/workflows/models/io/k8s/api/core/v1.pyi index b9aef9dac..bb112abd7 100644 --- a/src/hera/workflows/models/io/k8s/api/core/v1.pyi +++ b/src/hera/workflows/models/io/k8s/api/core/v1.pyi @@ -1,7 +1,10 @@ from enum import Enum from typing import Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...apimachinery.pkg.api import resource as resource from ...apimachinery.pkg.apis.meta import v1 as v1 diff --git a/src/hera/workflows/models/io/k8s/api/policy/v1beta1.py b/src/hera/workflows/models/io/k8s/api/policy/v1beta1.py index e789c3e3f..3df7c5731 100644 --- a/src/hera/workflows/models/io/k8s/api/policy/v1beta1.py +++ b/src/hera/workflows/models/io/k8s/api/policy/v1beta1.py @@ -5,9 +5,7 @@ from typing import Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from ...apimachinery.pkg.apis.meta import v1 from ...apimachinery.pkg.util import intstr diff --git a/src/hera/workflows/models/io/k8s/api/policy/v1beta1.pyi b/src/hera/workflows/models/io/k8s/api/policy/v1beta1.pyi index 471065d56..bb510518f 100644 --- a/src/hera/workflows/models/io/k8s/api/policy/v1beta1.pyi +++ b/src/hera/workflows/models/io/k8s/api/policy/v1beta1.pyi @@ -1,6 +1,9 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from ...apimachinery.pkg.apis.meta import v1 as v1 from ...apimachinery.pkg.util import intstr as intstr diff --git a/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.py b/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.py index 2f22d13e6..d5ac8d261 100644 --- a/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.py +++ b/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.py @@ -3,9 +3,7 @@ from __future__ import annotations -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field class Quantity(BaseModel): diff --git a/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.pyi b/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.pyi index 8cb1ae92f..62e5f6b47 100644 --- a/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.pyi +++ b/src/hera/workflows/models/io/k8s/apimachinery/pkg/api/resource.pyi @@ -1,4 +1,7 @@ -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) class Quantity(BaseModel): __root__: str diff --git a/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.py b/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.py index 0cc3efac5..c42be1cd0 100644 --- a/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.py +++ b/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.py @@ -6,9 +6,7 @@ from datetime import datetime from typing import Dict, List, Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field class CreateOptions(BaseModel): diff --git a/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi b/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi index 5c25dfa7b..17085cef1 100644 --- a/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi +++ b/src/hera/workflows/models/io/k8s/apimachinery/pkg/apis/meta/v1.pyi @@ -1,7 +1,10 @@ from datetime import datetime from typing import Dict, List, Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) class CreateOptions(BaseModel): dry_run: Optional[List[str]] diff --git a/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.py b/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.py index 640b9b045..592fcbd0c 100644 --- a/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.py +++ b/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.py @@ -3,7 +3,7 @@ from __future__ import annotations -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel class IntOrString(BaseModel): diff --git a/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.pyi b/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.pyi index 4ed64fd53..6f9697c73 100644 --- a/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.pyi +++ b/src/hera/workflows/models/io/k8s/apimachinery/pkg/util/intstr.pyi @@ -1,4 +1,4 @@ -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import BaseModel as BaseModel class IntOrString(BaseModel): __root__: str diff --git a/src/hera/workflows/models/sensor.py b/src/hera/workflows/models/sensor.py index f42b1d304..174300031 100644 --- a/src/hera/workflows/models/sensor.py +++ b/src/hera/workflows/models/sensor.py @@ -5,9 +5,7 @@ from typing import Optional -from pydantic import Field - -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, Field from .io.argoproj.events import v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 diff --git a/src/hera/workflows/models/sensor.pyi b/src/hera/workflows/models/sensor.pyi index 5baaafad4..88ebbf238 100644 --- a/src/hera/workflows/models/sensor.pyi +++ b/src/hera/workflows/models/sensor.pyi @@ -1,6 +1,9 @@ from typing import Optional -from hera.shared._base_model import BaseModel as BaseModel +from hera.shared._pydantic import ( + BaseModel as BaseModel, + Field as Field, +) from .io.argoproj.events import v1alpha1 as v1alpha1 from .io.k8s.apimachinery.pkg.apis.meta import v1 as v1 diff --git a/src/hera/workflows/parameter.py b/src/hera/workflows/parameter.py index 5ad92abb8..f3a136a57 100644 --- a/src/hera/workflows/parameter.py +++ b/src/hera/workflows/parameter.py @@ -7,8 +7,7 @@ from typing import Any, Optional -from pydantic import root_validator - +from hera.shared._pydantic import root_validator from hera.shared.serialization import MISSING, serialize from hera.workflows.models import Parameter as _ModelParameter diff --git a/src/hera/workflows/resources.py b/src/hera/workflows/resources.py index 41a3a9945..bc7d54123 100644 --- a/src/hera/workflows/resources.py +++ b/src/hera/workflows/resources.py @@ -1,9 +1,10 @@ """Holds the resource specification.""" from typing import Dict, Optional, Union -from pydantic import root_validator - -from hera.shared._base_model import BaseModel as _BaseModel +from hera.shared._pydantic import ( + BaseModel as _BaseModel, + root_validator, +) from hera.workflows.models import ResourceRequirements as _ModelResourceRequirements from hera.workflows.validators import validate_storage_units diff --git a/src/hera/workflows/retry_strategy.py b/src/hera/workflows/retry_strategy.py index af47ff415..a991eef23 100644 --- a/src/hera/workflows/retry_strategy.py +++ b/src/hera/workflows/retry_strategy.py @@ -2,9 +2,10 @@ from enum import Enum from typing import Optional, Union, cast -from pydantic import validator - -from hera.shared._base_model import BaseModel as _BaseModel +from hera.shared._pydantic import ( + BaseModel as _BaseModel, + validator, +) from hera.workflows.models import ( Backoff, IntOrString, diff --git a/src/hera/workflows/runner.py b/src/hera/workflows/runner.py index 0aeb88471..3beacff6b 100644 --- a/src/hera/workflows/runner.py +++ b/src/hera/workflows/runner.py @@ -6,10 +6,9 @@ import json import os from pathlib import Path -from typing import Any, Callable, Dict, List, Tuple, Union, cast - -from pydantic import validate_arguments +from typing import Any, Callable, Dict, List, Optional, Tuple, Union, cast +from hera.shared._pydantic import validate_arguments from hera.shared.serialization import serialize from hera.workflows import Artifact, Parameter from hera.workflows.artifact import ArtifactLoader @@ -72,22 +71,24 @@ def _parse(value, key, f): return value -def _is_str_kwarg_of(key: str, f: Callable): - """Check if param `key` of function `f` has a type annotation of a subclass of str.""" +def _get_type(key: str, f: Callable) -> Optional[type]: type_ = inspect.signature(f).parameters[key].annotation - if type_ is inspect.Parameter.empty: - # Untyped args are interpreted according to json spec - # ie. we will try to load it via json.loads in _parse - return False + return None if get_origin(type_) is None: - return issubclass(type_, str) - + return type_ origin_type = cast(type, get_origin(type_)) if origin_type is Annotated: - return issubclass(get_args(type_)[0], str) + return get_args(type_)[0] + return origin_type + - return issubclass(origin_type, str) +def _is_str_kwarg_of(key: str, f: Callable) -> bool: + """Check if param `key` of function `f` has a type annotation of a subclass of str.""" + type_ = _get_type(key, f) + if type_ is None: + return False + return issubclass(type_, str) def _is_artifact_loaded(key, f): @@ -270,10 +271,10 @@ def _runner(entrypoint: str, kwargs_list: List) -> Any: else: kwargs = _map_argo_inputs_to_function(function, kwargs) - # using smart union by default just in case clients do not rely on it. This means that if a function uses a union + # The imported validate_arguments uses smart union by default just in case clients do not rely on it. This means that if a function uses a union # type for any of its inputs, then this will at least try to map those types correctly if the input object is # not a pydantic model with smart_union enabled - function = validate_arguments(function, config=dict(smart_union=True)) + function = validate_arguments(function) function = _ignore_unmatched_kwargs(function) if os.environ.get("hera__script_annotations", None) is not None: diff --git a/src/hera/workflows/script.py b/src/hera/workflows/script.py index e0adf0df1..0f61f1f42 100644 --- a/src/hera/workflows/script.py +++ b/src/hera/workflows/script.py @@ -22,11 +22,11 @@ overload, ) -from pydantic import root_validator, validator from typing_extensions import ParamSpec, get_args, get_origin from hera.expr import g from hera.shared import BaseMixin, global_config +from hera.shared._pydantic import root_validator, validator from hera.workflows._context import _context from hera.workflows._mixins import ( CallableTemplateMixin, diff --git a/src/hera/workflows/volume.py b/src/hera/workflows/volume.py index ac16b1635..e9321fa22 100644 --- a/src/hera/workflows/volume.py +++ b/src/hera/workflows/volume.py @@ -3,8 +3,7 @@ from enum import Enum from typing import List, Optional, Union, cast -from pydantic import root_validator, validator - +from hera.shared._pydantic import root_validator, validator from hera.workflows.models import ( AWSElasticBlockStoreVolumeSource as _ModelAWSElasticBlockStoreVolumeSource, AzureDiskVolumeSource as _ModelAzureDiskVolumeSource, diff --git a/src/hera/workflows/workflow.py b/src/hera/workflows/workflow.py index 73eee2040..ad37932e2 100644 --- a/src/hera/workflows/workflow.py +++ b/src/hera/workflows/workflow.py @@ -13,11 +13,8 @@ except ImportError: from typing_extensions import Annotated, get_args # type: ignore - -from pydantic import validator - from hera.shared import global_config -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, validator from hera.workflows._mixins import ( ArgumentsMixin, ArgumentsT, diff --git a/src/hera/workflows/workflow_template.py b/src/hera/workflows/workflow_template.py index 1a398d20f..384336028 100644 --- a/src/hera/workflows/workflow_template.py +++ b/src/hera/workflows/workflow_template.py @@ -11,10 +11,8 @@ except ImportError: from typing_extensions import Annotated # type: ignore -from pydantic import validator - from hera.exceptions import NotFound -from hera.shared._base_model import BaseModel +from hera.shared._pydantic import BaseModel, validator from hera.workflows._mixins import ModelMapperMixin from hera.workflows.models import ( ObjectMeta, diff --git a/tests/script_runner/artifact_loaders.py b/tests/script_runner/artifact_loaders.py index 898cf3904..d96c1bab2 100644 --- a/tests/script_runner/artifact_loaders.py +++ b/tests/script_runner/artifact_loaders.py @@ -16,8 +16,8 @@ class MyArtifact(BaseModel): - a = "a" - b = "b" + a: str = "a" + b: str = "b" @script(constructor="runner") diff --git a/tests/script_runner/parameter_inputs.py b/tests/script_runner/parameter_inputs.py index 8fb238eba..f4259e549 100644 --- a/tests/script_runner/parameter_inputs.py +++ b/tests/script_runner/parameter_inputs.py @@ -62,17 +62,3 @@ def str_parameter_expects_jsonstr_list(my_json_str: str) -> list: @script() def annotated_str_parameter_expects_jsonstr_dict(my_json_str: Annotated[str, "some metadata"]) -> list: return json.loads(my_json_str) - - -class MyStr(str): - pass - - -@script() -def str_subclass_parameter_expects_jsonstr_dict(my_json_str: MyStr) -> list: - return json.loads(my_json_str) - - -@script() -def str_subclass_annotated_parameter_expects_jsonstr_dict(my_json_str: Annotated[MyStr, "some metadata"]) -> list: - return json.loads(my_json_str) diff --git a/tests/test_runner.py b/tests/test_runner.py index 03b1a39b2..bcd06d628 100644 --- a/tests/test_runner.py +++ b/tests/test_runner.py @@ -78,18 +78,6 @@ {"my": "dict"}, id="str-json-annotated-param-as-dict", ), - pytest.param( - "tests.script_runner.parameter_inputs:str_subclass_parameter_expects_jsonstr_dict", - [{"name": "my_json_str", "value": json.dumps({"my": "dict"})}], - {"my": "dict"}, - id="str-subclass-json-param-as-dict", - ), - pytest.param( - "tests.script_runner.parameter_inputs:str_subclass_annotated_parameter_expects_jsonstr_dict", - [{"name": "my_json_str", "value": json.dumps({"my": "dict"})}], - {"my": "dict"}, - id="str-subclass-json-annotated-param-as-dict", - ), ), ) def test_parameter_loading( @@ -475,12 +463,9 @@ def test_script_annotations_artifact_input_loader_error( importlib.reload(module) - # WHEN - with pytest.raises(ValidationError) as e: - _ = _runner(f"{module.__name__}:{function_name}", kwargs_list) - # THEN - assert "value is not a valid integer" in str(e.value) + with pytest.raises(ValidationError): + _ = _runner(f"{module.__name__}:{function_name}", kwargs_list) @pytest.mark.parametrize(