Skip to content

Commit 757ada6

Browse files
authored
Merge pull request #423 from tomschr/422-doc-pydantic
Fix #422: Update advanced topic about Pydantic v2
2 parents 8fe4ef6 + 2ae1a21 commit 757ada6

File tree

1 file changed

+42
-18
lines changed

1 file changed

+42
-18
lines changed

docs/advanced/combine-pydantic-and-semver.rst

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,59 @@ According to its homepage, `Pydantic <https://pydantic-docs.helpmanual.io>`_
55
"enforces type hints at runtime, and provides user friendly errors when data
66
is invalid."
77

8-
To work with Pydantic, use the following steps:
8+
To work with Pydantic>2.0, use the following steps:
99

1010

1111
1. Derive a new class from :class:`~semver.version.Version`
12-
first and add the magic methods :py:meth:`__get_validators__`
13-
and :py:meth:`__modify_schema__` like this:
12+
first and add the magic methods :py:meth:`__get_pydantic_core_schema__`
13+
and :py:meth:`__get_pydantic_json_schema__` like this:
1414

1515
.. code-block:: python
1616
17+
from typing import Annotated, Any, Callable
18+
from pydantic import GetJsonSchemaHandler
19+
from pydantic_core import core_schema
20+
from pydantic.json_schema import JsonSchemaValue
1721
from semver import Version
1822
19-
class PydanticVersion(Version):
20-
@classmethod
21-
def _parse(cls, version):
22-
return cls.parse(version)
2323
24+
class _VersionPydanticAnnotation:
2425
@classmethod
25-
def __get_validators__(cls):
26-
"""Return a list of validator methods for pydantic models."""
27-
yield cls._parse
26+
def __get_pydantic_core_schema__(
27+
cls,
28+
_source_type: Any,
29+
_handler: Callable[[Any], core_schema.CoreSchema],
30+
) -> core_schema.CoreSchema:
31+
def validate_from_str(value: str) -> Version:
32+
return Version.parse(value)
33+
34+
from_str_schema = core_schema.chain_schema(
35+
[
36+
core_schema.str_schema(),
37+
core_schema.no_info_plain_validator_function(validate_from_str),
38+
]
39+
)
40+
41+
return core_schema.json_or_python_schema(
42+
json_schema=from_str_schema,
43+
python_schema=core_schema.union_schema(
44+
[
45+
core_schema.is_instance_schema(Version),
46+
from_str_schema,
47+
]
48+
),
49+
serialization=core_schema.plain_serializer_function_ser_schema(
50+
lambda instance: instance.x
51+
),
52+
)
2853
2954
@classmethod
30-
def __modify_schema__(cls, field_schema):
31-
"""Inject/mutate the pydantic field schema in-place."""
32-
field_schema.update(examples=["1.0.2",
33-
"2.15.3-alpha",
34-
"21.3.15-beta+12345",
35-
]
36-
)
55+
def __get_pydantic_json_schema__(
56+
cls, _core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler
57+
) -> JsonSchemaValue:
58+
return handler(core_schema.str_schema())
59+
60+
ManifestVersion = Annotated[Version, _VersionPydanticAnnotation]
3761
3862
2. Create a new model (in this example :class:`MyModel`) and derive
3963
it from :class:`pydantic.BaseModel`:
@@ -43,7 +67,7 @@ To work with Pydantic, use the following steps:
4367
import pydantic
4468
4569
class MyModel(pydantic.BaseModel):
46-
version: PydanticVersion
70+
version: _VersionPydanticAnnotation
4771
4872
3. Use your model like this:
4973

0 commit comments

Comments
 (0)