Skip to content

Functional Validators

This module contains related classes and functions for validation.

ModelAfterValidatorWithoutInfo module-attribute

ModelAfterValidatorWithoutInfo = Callable[
    [_ModelType], _ModelType
]

A @model_validator decorated function signature. This is used when mode='after' and the function does not have info argument.

ModelAfterValidator module-attribute

ModelAfterValidator = Callable[
    [_ModelType, ValidationInfo], _ModelType
]

A @model_validator decorated function signature. This is used when mode='after'.

AfterValidator dataclass

AfterValidator(
    func: (
        NoInfoValidatorFunction | WithInfoValidatorFunction
    ),
)

Usage Documentation

Annotated Validators

A metadata class that indicates that a validation should be applied after the inner validation logic.

Attributes:

Name Type Description
func NoInfoValidatorFunction | WithInfoValidatorFunction

The validator function.

Example
from typing_extensions import Annotated

from pydantic import AfterValidator, BaseModel, ValidationError

MyInt = Annotated[int, AfterValidator(lambda v: v + 1)]

class Model(BaseModel):
    a: MyInt

print(Model(a=1).a)
#> 2

try:
    Model(a='a')
except ValidationError as e:
    print(e.json(indent=2))
    '''
    [
      {
        "type": "int_parsing",
        "loc": [
          "a"
        ],
        "msg": "Input should be a valid integer, unable to parse string as an integer",
        "input": "a",
        "url": "https://errors.pydantic.dev/2/v/int_parsing"
      }
    ]
    '''

BeforeValidator dataclass

BeforeValidator(
    func: (
        NoInfoValidatorFunction | WithInfoValidatorFunction
    ),
    json_schema_input_type: Any = PydanticUndefined,
)

Usage Documentation

Annotated Validators

A metadata class that indicates that a validation should be applied before the inner validation logic.

Attributes:

Name Type Description
func NoInfoValidatorFunction | WithInfoValidatorFunction

The validator function.

json_schema_input_type Any

The input type of the function. This is only used to generate the appropriate JSON Schema (in validation mode).

Example
from typing_extensions import Annotated

from pydantic import BaseModel, BeforeValidator

MyInt = Annotated[int, BeforeValidator(lambda v: v + 1)]

class Model(BaseModel):
    a: MyInt

print(Model(a=1).a)
#> 2

try:
    Model(a='a')
except TypeError as e:
    print(e)
    #> can only concatenate str (not "int") to str

PlainValidator dataclass

PlainValidator(
    func: (
        NoInfoValidatorFunction | WithInfoValidatorFunction
    ),
    json_schema_input_type: Any = Any,
)

Usage Documentation

Annotated Validators

A metadata class that indicates that a validation should be applied instead of the inner validation logic.

Attributes:

Name Type Description
func NoInfoValidatorFunction | WithInfoValidatorFunction

The validator function.

json_schema_input_type Any

The input type of the function. This is only used to generate the appropriate JSON Schema (in validation mode). If not provided, will default to Any.

Example
from typing_extensions import Annotated

from pydantic import BaseModel, PlainValidator

MyInt = Annotated[int, PlainValidator(lambda v: int(v) + 1)]

class Model(BaseModel):
    a: MyInt

print(Model(a='1').a)
#> 2

WrapValidator dataclass

WrapValidator(
    func: (
        NoInfoWrapValidatorFunction
        | WithInfoWrapValidatorFunction
    ),
    json_schema_input_type: Any = PydanticUndefined,
)

Usage Documentation

Annotated Validators

A metadata class that indicates that a validation should be applied around the inner validation logic.

Attributes:

Name Type Description
func NoInfoWrapValidatorFunction | WithInfoWrapValidatorFunction

The validator function.

json_schema_input_type Any

The input type of the function. This is only used to generate the appropriate JSON Schema (in validation mode).

from datetime import datetime

from typing_extensions import Annotated

from pydantic import BaseModel, ValidationError, WrapValidator

def validate_timestamp(v, handler):
    if v == 'now':
        # we don't want to bother with further validation, just return the new value
        return datetime.now()
    try:
        return handler(v)
    except ValidationError:
        # validation failed, in this case we want to return a default value
        return datetime(2000, 1, 1)

MyTimestamp = Annotated[datetime, WrapValidator(validate_timestamp)]

class Model(BaseModel):
    a: MyTimestamp

print(Model(a='now').a)
#> 2032-01-02 03:04:05.000006
print(Model(a='invalid').a)
#> 2000-01-01 00:00:00

ModelWrapValidatorHandler

Bases: ValidatorFunctionWrapHandler, Protocol[_ModelTypeCo]

@model_validator decorated function handler argument type. This is used when mode='wrap'.

ModelWrapValidatorWithoutInfo

Bases: Protocol[_ModelType]

A @model_validator decorated function signature. This is used when mode='wrap' and the function does not have info argument.

ModelWrapValidator

Bases: Protocol[_ModelType]

A @model_validator decorated function signature. This is used when mode='wrap'.

FreeModelBeforeValidatorWithoutInfo

Bases: Protocol

A @model_validator decorated function signature. This is used when mode='before' and the function does not have info argument.

ModelBeforeValidatorWithoutInfo

Bases: Protocol

A @model_validator decorated function signature. This is used when mode='before' and the function does not have info argument.

FreeModelBeforeValidator

Bases: Protocol

A @model_validator decorated function signature. This is used when mode='before'.

ModelBeforeValidator

Bases: Protocol

A @model_validator decorated function signature. This is used when mode='before'.

InstanceOf dataclass

InstanceOf()

Generic type for annotating a type that is an instance of a given class.

Example
from pydantic import BaseModel, InstanceOf

class Foo:
    ...

class Bar(BaseModel):
    foo: InstanceOf[Foo]

Bar(foo=Foo())
try:
    Bar(foo=42)
except ValidationError as e:
    print(e)
    """
    [
    │   {
    │   │   'type': 'is_instance_of',
    │   │   'loc': ('foo',),
    │   │   'msg': 'Input should be an instance of Foo',
    │   │   'input': 42,
    │   │   'ctx': {'class': 'Foo'},
    │   │   'url': 'https://errors.pydantic.dev/0.38.0/v/is_instance_of'
    │   }
    ]
    """

SkipValidation dataclass

SkipValidation()

If this is applied as an annotation (e.g., via x: Annotated[int, SkipValidation]), validation will be skipped. You can also use SkipValidation[int] as a shorthand for Annotated[int, SkipValidation].

This can be useful if you want to use a type annotation for documentation/IDE/type-checking purposes, and know that it is safe to skip validation for one or more of the fields.

Because this converts the validation schema to any_schema, subsequent annotation-applied transformations may not have the expected effects. Therefore, when used, this annotation should generally be the final annotation applied to a type.

field_validator

field_validator(
    field: str,
    /,
    *fields: str,
    mode: FieldValidatorModes = "after",
    check_fields: bool | None = None,
    json_schema_input_type: Any = PydanticUndefined,
) -> Callable[[Any], Any]

Usage Documentation

Field validators

Decorate methods on the class indicating that they should be used to validate fields.

Example usage:

from typing import Any

from pydantic import (
    BaseModel,
    ValidationError,
    field_validator,
)

class Model(BaseModel):
    a: str

    @field_validator('a')
    @classmethod
    def ensure_foobar(cls, v: Any):
        if 'foobar' not in v:
            raise ValueError('"foobar" not found in a')
        return v

print(repr(Model(a='this is foobar good')))
#> Model(a='this is foobar good')

try:
    Model(a='snap')
except ValidationError as exc_info:
    print(exc_info)
    '''
    1 validation error for Model
    a
      Value error, "foobar" not found in a [type=value_error, input_value='snap', input_type=str]
    '''

For more in depth examples, see Field Validators.

Parameters:

Name Type Description Default
field str

The first field the field_validator should be called on; this is separate from fields to ensure an error is raised if you don't pass at least one.

required
*fields str

Additional field(s) the field_validator should be called on.

()
mode FieldValidatorModes

Specifies whether to validate the fields before or after validation.

'after'
check_fields bool | None

Whether to check that the fields actually exist on the model.

None
json_schema_input_type Any

The input type of the function. This is only used to generate the appropriate JSON Schema (in validation mode) and can only specified when mode is either 'before', 'plain' or 'wrap'.

PydanticUndefined

Returns:

Type Description
Callable[[Any], Any]

A decorator that can be used to decorate a function to be used as a field_validator.

Raises:

Type Description
PydanticUserError
  • If @field_validator is used bare (with no fields).
  • If the args passed to @field_validator as fields are not strings.
  • If @field_validator applied to instance methods.
Source code in pydantic/functional_validators.py
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
def field_validator(
    field: str,
    /,
    *fields: str,
    mode: FieldValidatorModes = 'after',
    check_fields: bool | None = None,
    json_schema_input_type: Any = PydanticUndefined,
) -> Callable[[Any], Any]:
    """Usage docs: https://docs.pydantic.dev/2.9/concepts/validators/#field-validators

    Decorate methods on the class indicating that they should be used to validate fields.

    Example usage:
    ```py
    from typing import Any

    from pydantic import (
        BaseModel,
        ValidationError,
        field_validator,
    )

    class Model(BaseModel):
        a: str

        @field_validator('a')
        @classmethod
        def ensure_foobar(cls, v: Any):
            if 'foobar' not in v:
                raise ValueError('"foobar" not found in a')
            return v

    print(repr(Model(a='this is foobar good')))
    #> Model(a='this is foobar good')

    try:
        Model(a='snap')
    except ValidationError as exc_info:
        print(exc_info)
        '''
        1 validation error for Model
        a
          Value error, "foobar" not found in a [type=value_error, input_value='snap', input_type=str]
        '''
    ```

    For more in depth examples, see [Field Validators](../concepts/validators.md#field-validators).

    Args:
        field: The first field the `field_validator` should be called on; this is separate
            from `fields` to ensure an error is raised if you don't pass at least one.
        *fields: Additional field(s) the `field_validator` should be called on.
        mode: Specifies whether to validate the fields before or after validation.
        check_fields: Whether to check that the fields actually exist on the model.
        json_schema_input_type: The input type of the function. This is only used to generate
            the appropriate JSON Schema (in validation mode) and can only specified
            when `mode` is either `'before'`, `'plain'` or `'wrap'`.

    Returns:
        A decorator that can be used to decorate a function to be used as a field_validator.

    Raises:
        PydanticUserError:
            - If `@field_validator` is used bare (with no fields).
            - If the args passed to `@field_validator` as fields are not strings.
            - If `@field_validator` applied to instance methods.
    """
    if isinstance(field, FunctionType):
        raise PydanticUserError(
            '`@field_validator` should be used with fields and keyword arguments, not bare. '
            "E.g. usage should be `@validator('<field_name>', ...)`",
            code='validator-no-fields',
        )

    if mode not in ('before', 'plain', 'wrap') and json_schema_input_type is not PydanticUndefined:
        raise PydanticUserError(
            f"`json_schema_input_type` can't be used when mode is set to {mode!r}",
            code='validator-input-type',
        )

    if json_schema_input_type is PydanticUndefined and mode == 'plain':
        json_schema_input_type = Any

    fields = field, *fields
    if not all(isinstance(field, str) for field in fields):
        raise PydanticUserError(
            '`@field_validator` fields should be passed as separate string args. '
            "E.g. usage should be `@validator('<field_name_1>', '<field_name_2>', ...)`",
            code='validator-invalid-fields',
        )

    def dec(
        f: Callable[..., Any] | staticmethod[Any, Any] | classmethod[Any, Any, Any],
    ) -> _decorators.PydanticDescriptorProxy[Any]:
        if _decorators.is_instance_method_from_sig(f):
            raise PydanticUserError(
                '`@field_validator` cannot be applied to instance methods', code='validator-instance-method'
            )

        # auto apply the @classmethod decorator
        f = _decorators.ensure_classmethod_based_on_signature(f)

        dec_info = _decorators.FieldValidatorDecoratorInfo(
            fields=fields, mode=mode, check_fields=check_fields, json_schema_input_type=json_schema_input_type
        )
        return _decorators.PydanticDescriptorProxy(f, dec_info)

    return dec

model_validator

model_validator(
    *, mode: Literal["wrap", "before", "after"]
) -> Any

Usage Documentation

Model validators

Decorate model methods for validation purposes.

Example usage:

from typing_extensions import Self

from pydantic import BaseModel, ValidationError, model_validator

class Square(BaseModel):
    width: float
    height: float

    @model_validator(mode='after')
    def verify_square(self) -> Self:
        if self.width != self.height:
            raise ValueError('width and height do not match')
        return self

s = Square(width=1, height=1)
print(repr(s))
#> Square(width=1.0, height=1.0)

try:
    Square(width=1, height=2)
except ValidationError as e:
    print(e)
    '''
    1 validation error for Square
      Value error, width and height do not match [type=value_error, input_value={'width': 1, 'height': 2}, input_type=dict]
    '''

For more in depth examples, see Model Validators.

Parameters:

Name Type Description Default
mode Literal['wrap', 'before', 'after']

A required string literal that specifies the validation mode. It can be one of the following: 'wrap', 'before', or 'after'.

required

Returns:

Type Description
Any

A decorator that can be used to decorate a function to be used as a model validator.

Source code in pydantic/functional_validators.py
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
def model_validator(
    *,
    mode: Literal['wrap', 'before', 'after'],
) -> Any:
    """Usage docs: https://docs.pydantic.dev/2.9/concepts/validators/#model-validators

    Decorate model methods for validation purposes.

    Example usage:
    ```py
    from typing_extensions import Self

    from pydantic import BaseModel, ValidationError, model_validator

    class Square(BaseModel):
        width: float
        height: float

        @model_validator(mode='after')
        def verify_square(self) -> Self:
            if self.width != self.height:
                raise ValueError('width and height do not match')
            return self

    s = Square(width=1, height=1)
    print(repr(s))
    #> Square(width=1.0, height=1.0)

    try:
        Square(width=1, height=2)
    except ValidationError as e:
        print(e)
        '''
        1 validation error for Square
          Value error, width and height do not match [type=value_error, input_value={'width': 1, 'height': 2}, input_type=dict]
        '''
    ```

    For more in depth examples, see [Model Validators](../concepts/validators.md#model-validators).

    Args:
        mode: A required string literal that specifies the validation mode.
            It can be one of the following: 'wrap', 'before', or 'after'.

    Returns:
        A decorator that can be used to decorate a function to be used as a model validator.
    """

    def dec(f: Any) -> _decorators.PydanticDescriptorProxy[Any]:
        # auto apply the @classmethod decorator
        f = _decorators.ensure_classmethod_based_on_signature(f)
        dec_info = _decorators.ModelValidatorDecoratorInfo(mode=mode)
        return _decorators.PydanticDescriptorProxy(f, dec_info)

    return dec