Source code for edify.integrations.pydantic
"""Pydantic integration — validate string fields against an edify :class:`Pattern`.
Requires the ``pydantic`` extra: ``pip install edify[pydantic]``. Importing this module
without the framework installed raises :class:`ImportError` at import time.
Typical usage:
.. code-block:: python
from typing import Annotated
from pydantic import AfterValidator, BaseModel
from edify.integrations.pydantic import pattern_validator
from edify.library import email
class Contact(BaseModel):
address: Annotated[str, AfterValidator(pattern_validator(email))]
"""
from __future__ import annotations
from collections.abc import Callable
from edify.errors.integration import PatternDidNotMatchError
from edify.pattern.composition import Pattern
[docs]
def pattern_validator(pattern: Pattern) -> Callable[[str], str]:
"""Return a Pydantic-compatible validator callable for ``pattern``.
The returned callable accepts a string and returns it unchanged when the
pattern matches; otherwise raises :class:`edify.errors.integration.PatternDidNotMatchError`
(a :class:`ValueError` subclass) that Pydantic embeds in its :class:`ValidationError`.
Args:
pattern: The :class:`edify.Pattern` the field must match anywhere in.
"""
pattern_source = pattern.to_regex_string()
def validate(value: str) -> str:
if pattern(value):
return value
raise PatternDidNotMatchError(pattern_source, value)
return validate