From 73bd190a1cb06517868c9b176ce386f95f66cdd9 Mon Sep 17 00:00:00 2001 From: Tom Schraitle Date: Thu, 27 Jan 2022 11:22:43 +0100 Subject: [PATCH] Describe Pydantic and semver in "Advanced topics" Related to issue #343 Co-authored-by: Caleb Stewart --- changelog.d/343.doc.rst | 2 + docs/advanced/combine-pydantic-and-semver.rst | 53 +++++++++++++++++++ docs/advanced/index.rst | 4 +- 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 changelog.d/343.doc.rst create mode 100644 docs/advanced/combine-pydantic-and-semver.rst diff --git a/changelog.d/343.doc.rst b/changelog.d/343.doc.rst new file mode 100644 index 00000000..630d7474 --- /dev/null +++ b/changelog.d/343.doc.rst @@ -0,0 +1,2 @@ +Describe combining Pydantic with semver in the "Advanced topic" +section. diff --git a/docs/advanced/combine-pydantic-and-semver.rst b/docs/advanced/combine-pydantic-and-semver.rst new file mode 100644 index 00000000..a9249daf --- /dev/null +++ b/docs/advanced/combine-pydantic-and-semver.rst @@ -0,0 +1,53 @@ +Combining Pydantic and semver +============================= + +According to its homepage, `Pydantic `_ +"enforces type hints at runtime, and provides user friendly errors when data +is invalid." + +To work with Pydantic, use the following steps: + + +1. Derive a new class from :class:`~semver.version.Version` + first and add the magic methods :py:meth:`__get_validators__` + and :py:meth:`__modify_schema__` like this: + + .. code-block:: python + + from semver import Version + + class PydanticVersion(Version): + @classmethod + def __get_validators__(cls): + """Return a list of validator methods for pydantic models.""" + yield cls.parse + + @classmethod + def __modify_schema__(cls, field_schema): + """Inject/mutate the pydantic field schema in-place.""" + field_schema.update(examples=["1.0.2", + "2.15.3-alpha", + "21.3.15-beta+12345", + ] + ) + +2. Create a new model (in this example :class:`MyModel`) and derive + it from :class:`pydantic.BaseModel`: + + .. code-block:: python + + import pydantic + + class MyModel(pydantic.BaseModel): + version: PydanticVersion + +3. Use your model like this: + + .. code-block:: python + + model = MyModel.parse_obj({"version": "1.2.3"}) + + The attribute :py:attr:`model.version` will be an instance of + :class:`~semver.version.Version`. + If the version is invalid, the construction will raise a + :py:exc:`pydantic.ValidationError`. diff --git a/docs/advanced/index.rst b/docs/advanced/index.rst index de7da166..f45a2f9e 100644 --- a/docs/advanced/index.rst +++ b/docs/advanced/index.rst @@ -2,9 +2,9 @@ Advanced topics =============== - .. toctree:: deal-with-invalid-versions create-subclasses-from-version - display-deprecation-warnings \ No newline at end of file + display-deprecation-warnings + combine-pydantic-and-semver \ No newline at end of file