From dee3fa77836f88c2a8566c0b3eef4cdd0ceca708 Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Fri, 25 Oct 2024 20:33:06 -0300 Subject: [PATCH 1/4] fix(extras): Fix generation of JSON Schema for Pydantic `Rut` type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attempting to generate a JSON Schema using `pydantic.BaseModel.model_json_schema()` or `pydantic.TypeAdapter.json_schema()` fails with the following error message: > pydantic.errors.PydanticInvalidForJsonSchema: > Cannot generate a JsonSchema for core_schema.PlainValidatorFunctionSchema ({ > 'type': 'no-info', > 'function': .validate_from_str at 0x…> > }) This commit fixes the above error by implementing `__get_pydantic_json_schema__` to override the generated JSON Schema. --- src/cl_sii/extras/pydantic_types.py | 19 ++++++++++++++- src/tests/test_extras_pydantic_types.py | 32 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/cl_sii/extras/pydantic_types.py b/src/cl_sii/extras/pydantic_types.py index cd0f3a89..b1dd73e7 100644 --- a/src/cl_sii/extras/pydantic_types.py +++ b/src/cl_sii/extras/pydantic_types.py @@ -41,6 +41,9 @@ class _RutPydanticAnnotation: - Customizing the core schema and JSON schema: https://docs.pydantic.dev/2.9/architecture/#customizing-the-core-schema-and-json-schema (https://github.com/pydantic/pydantic/blob/v2.9.2/docs/architecture.md#customizing-the-core-schema-and-json-schema) + - Implementing __get_pydantic_json_schema__: + https://docs.pydantic.dev/2.9/concepts/json_schema/#implementing-__get_pydantic_json_schema__ + (https://github.com/pydantic/pydantic/blob/v2.9.2/docs/concepts/json_schema.md#implementing-__get_pydantic_json_schema__-) Examples: @@ -73,6 +76,7 @@ class _RutPydanticAnnotation: '78773510-K' >>> example_type_adapter.dump_json(cl_sii.rut.Rut('78773510-K')) b'"78773510-K"' + >>> example_json_schema = example_type_adapter.json_schema() """ RUT_CANONICAL_STRICT_REGEX: ClassVar[Pattern] = re.compile( @@ -99,7 +103,7 @@ def validate_from_str(value: str) -> cl_sii.rut.Rut: from_str_schema = pydantic_core.core_schema.chain_schema( [ - pydantic_core.core_schema.str_schema(pattern=cls.RUT_CANONICAL_STRICT_REGEX), + cls.str_schema(), pydantic_core.core_schema.no_info_plain_validator_function(validate_from_str), ] ) @@ -117,6 +121,19 @@ def validate_from_str(value: str) -> cl_sii.rut.Rut: ), ) + @classmethod + def __get_pydantic_json_schema__( + cls, + core_schema: pydantic_core.core_schema.CoreSchema, + handler: pydantic.GetJsonSchemaHandler, + ) -> pydantic.json_schema.JsonSchemaValue: + core_schema = cls.str_schema() + return handler(core_schema) + + @classmethod + def str_schema(cls) -> pydantic_core.core_schema.CoreSchema: + return pydantic_core.core_schema.str_schema(pattern=cls.RUT_CANONICAL_STRICT_REGEX) + Rut = Annotated[cl_sii.rut.Rut, _RutPydanticAnnotation] """ diff --git a/src/tests/test_extras_pydantic_types.py b/src/tests/test_extras_pydantic_types.py index e66221d8..3664e122 100644 --- a/src/tests/test_extras_pydantic_types.py +++ b/src/tests/test_extras_pydantic_types.py @@ -133,3 +133,35 @@ def test_deserialize_invalid(self) -> None: with self.assertRaises(pydantic.ValidationError): self.pydantic_type_adapter.validate_json(data) + + def test_json_schema_for_validation(self) -> None: + # -----Arrange----- + + expected_json_schema = { + 'type': 'string', + 'pattern': '^(\\d{1,8})-([\\dK])$', + } + + # -----Act----- + + actual_json_schema = self.pydantic_type_adapter.json_schema(mode='validation') + + # -----Assert----- + + self.assertEqual(expected_json_schema, actual_json_schema) + + def test_json_schema_for_serialization(self) -> None: + # -----Arrange----- + + expected_json_schema = { + 'type': 'string', + 'pattern': '^(\\d{1,8})-([\\dK])$', + } + + # -----Act----- + + actual_json_schema = self.pydantic_type_adapter.json_schema(mode='serialization') + + # -----Assert----- + + self.assertEqual(expected_json_schema, actual_json_schema) From dc5990fc280d626593abe91b293f88bb3ad07302 Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Mon, 28 Oct 2024 09:17:53 -0300 Subject: [PATCH 2/4] chore(deps): Update `mypy` from 1.11.2 to 1.13.0 - [Software Repository](https://pypi.org/project/mypy/1.13.0/) - [Release notes](https://github.com/python/mypy/releases/tag/v1.13.0) - [Changelog](https://github.com/python/mypy/blob/v1.13.0/CHANGELOG.md#mypy-113) - [Commits](https://github.com/python/mypy/compare/v1.11.2...v1.13.0) --- requirements-dev.in | 2 +- requirements-dev.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-dev.in b/requirements-dev.in index 88e92206..1379f1cf 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -10,7 +10,7 @@ bumpversion==0.5.3 coverage==7.6.1 flake8==7.1.1 isort==5.13.2 -mypy==1.11.2 +mypy==1.13.0 pip-tools==7.4.1 tox==4.21.0 twine==5.1.1 diff --git a/requirements-dev.txt b/requirements-dev.txt index ebfed6f7..92ccab52 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -78,7 +78,7 @@ mccabe==0.7.0 # via flake8 mdurl==0.1.2 # via markdown-it-py -mypy==1.11.2 +mypy==1.13.0 # via -r requirements-dev.in mypy-extensions==1.0.0 # via From e6d8226f15918439ff16bf568d5f1d03093f0afd Mon Sep 17 00:00:00 2001 From: Felipe Pinto Date: Mon, 28 Oct 2024 09:41:18 -0300 Subject: [PATCH 3/4] chore: Update history for new version --- HISTORY.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 8e554a74..09c48a39 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # History +## 0.38.0 (2024-10-28) + +- (PR #725, 2024-10-28) extras: Fix generation of JSON Schema for Pydantic `Rut` type +- (PR #726, 2024-10-28) chore(deps): Update `mypy` from 1.11.2 to 1.13.0 + ## 0.37.0 (2024-10-25) - (PR #721, 2024-10-11) rut: Improve type annotation; Add method to validate DV From 2f0d11fdb85844ebef22b4ee3ba3ba9cfa11dfb4 Mon Sep 17 00:00:00 2001 From: Felipe Pinto Date: Mon, 28 Oct 2024 09:41:42 -0300 Subject: [PATCH 4/4] chore: Bump version from 0.37.0 to 0.38.0 --- .bumpversion.cfg | 2 +- src/cl_sii/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 8ed6bf66..eaffc880 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.37.0 +current_version = 0.38.0 commit = True tag = False message = chore: Bump version from {current_version} to {new_version} diff --git a/src/cl_sii/__init__.py b/src/cl_sii/__init__.py index a4e3c5d7..708d3cb0 100644 --- a/src/cl_sii/__init__.py +++ b/src/cl_sii/__init__.py @@ -4,4 +4,4 @@ """ -__version__ = '0.37.0' +__version__ = '0.38.0'