about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/pydantic/functional_validators.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/pydantic/functional_validators.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-4a52a71956a8d46fcb7294ac71734504bb09bcc2.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/pydantic/functional_validators.py')
-rw-r--r--.venv/lib/python3.12/site-packages/pydantic/functional_validators.py825
1 files changed, 825 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pydantic/functional_validators.py b/.venv/lib/python3.12/site-packages/pydantic/functional_validators.py
new file mode 100644
index 00000000..aa3da8c2
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/pydantic/functional_validators.py
@@ -0,0 +1,825 @@
+"""This module contains related classes and functions for validation."""
+
+from __future__ import annotations as _annotations
+
+import dataclasses
+import sys
+from functools import partialmethod
+from types import FunctionType
+from typing import TYPE_CHECKING, Any, Callable, TypeVar, Union, cast, overload
+
+from pydantic_core import PydanticUndefined, core_schema
+from pydantic_core import core_schema as _core_schema
+from typing_extensions import Annotated, Literal, Self, TypeAlias
+
+from ._internal import _decorators, _generics, _internal_dataclass
+from .annotated_handlers import GetCoreSchemaHandler
+from .errors import PydanticUserError
+
+if sys.version_info < (3, 11):
+    from typing_extensions import Protocol
+else:
+    from typing import Protocol
+
+_inspect_validator = _decorators.inspect_validator
+
+
+@dataclasses.dataclass(frozen=True, **_internal_dataclass.slots_true)
+class AfterValidator:
+    """Usage docs: https://docs.pydantic.dev/2.10/concepts/validators/#field-validators
+
+    A metadata class that indicates that a validation should be applied **after** the inner validation logic.
+
+    Attributes:
+        func: The validator function.
+
+    Example:
+        ```python
+        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"
+              }
+            ]
+            '''
+        ```
+    """
+
+    func: core_schema.NoInfoValidatorFunction | core_schema.WithInfoValidatorFunction
+
+    def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
+        schema = handler(source_type)
+        info_arg = _inspect_validator(self.func, 'after')
+        if info_arg:
+            func = cast(core_schema.WithInfoValidatorFunction, self.func)
+            return core_schema.with_info_after_validator_function(func, schema=schema, field_name=handler.field_name)
+        else:
+            func = cast(core_schema.NoInfoValidatorFunction, self.func)
+            return core_schema.no_info_after_validator_function(func, schema=schema)
+
+    @classmethod
+    def _from_decorator(cls, decorator: _decorators.Decorator[_decorators.FieldValidatorDecoratorInfo]) -> Self:
+        return cls(func=decorator.func)
+
+
+@dataclasses.dataclass(frozen=True, **_internal_dataclass.slots_true)
+class BeforeValidator:
+    """Usage docs: https://docs.pydantic.dev/2.10/concepts/validators/#field-validators
+
+    A metadata class that indicates that a validation should be applied **before** the inner validation logic.
+
+    Attributes:
+        func: The validator function.
+        json_schema_input_type: The input type of the function. This is only used to generate the appropriate
+            JSON Schema (in validation mode).
+
+    Example:
+        ```python
+        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
+        ```
+    """
+
+    func: core_schema.NoInfoValidatorFunction | core_schema.WithInfoValidatorFunction
+    json_schema_input_type: Any = PydanticUndefined
+
+    def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
+        schema = handler(source_type)
+        input_schema = (
+            None
+            if self.json_schema_input_type is PydanticUndefined
+            else handler.generate_schema(self.json_schema_input_type)
+        )
+
+        info_arg = _inspect_validator(self.func, 'before')
+        if info_arg:
+            func = cast(core_schema.WithInfoValidatorFunction, self.func)
+            return core_schema.with_info_before_validator_function(
+                func,
+                schema=schema,
+                field_name=handler.field_name,
+                json_schema_input_schema=input_schema,
+            )
+        else:
+            func = cast(core_schema.NoInfoValidatorFunction, self.func)
+            return core_schema.no_info_before_validator_function(
+                func, schema=schema, json_schema_input_schema=input_schema
+            )
+
+    @classmethod
+    def _from_decorator(cls, decorator: _decorators.Decorator[_decorators.FieldValidatorDecoratorInfo]) -> Self:
+        return cls(
+            func=decorator.func,
+            json_schema_input_type=decorator.info.json_schema_input_type,
+        )
+
+
+@dataclasses.dataclass(frozen=True, **_internal_dataclass.slots_true)
+class PlainValidator:
+    """Usage docs: https://docs.pydantic.dev/2.10/concepts/validators/#field-validators
+
+    A metadata class that indicates that a validation should be applied **instead** of the inner validation logic.
+
+    !!! note
+        Before v2.9, `PlainValidator` wasn't always compatible with JSON Schema generation for `mode='validation'`.
+        You can now use the `json_schema_input_type` argument to specify the input type of the function
+        to be used in the JSON schema when `mode='validation'` (the default). See the example below for more details.
+
+    Attributes:
+        func: The validator function.
+        json_schema_input_type: 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:
+        ```python
+        from typing import Union
+
+        from typing_extensions import Annotated
+
+        from pydantic import BaseModel, PlainValidator
+
+        MyInt = Annotated[
+            int,
+            PlainValidator(
+                lambda v: int(v) + 1, json_schema_input_type=Union[str, int]  # (1)!
+            ),
+        ]
+
+        class Model(BaseModel):
+            a: MyInt
+
+        print(Model(a='1').a)
+        #> 2
+
+        print(Model(a=1).a)
+        #> 2
+        ```
+
+        1. In this example, we've specified the `json_schema_input_type` as `Union[str, int]` which indicates to the JSON schema
+        generator that in validation mode, the input type for the `a` field can be either a `str` or an `int`.
+    """
+
+    func: core_schema.NoInfoValidatorFunction | core_schema.WithInfoValidatorFunction
+    json_schema_input_type: Any = Any
+
+    def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
+        # Note that for some valid uses of PlainValidator, it is not possible to generate a core schema for the
+        # source_type, so calling `handler(source_type)` will error, which prevents us from generating a proper
+        # serialization schema. To work around this for use cases that will not involve serialization, we simply
+        # catch any PydanticSchemaGenerationError that may be raised while attempting to build the serialization schema
+        # and abort any attempts to handle special serialization.
+        from pydantic import PydanticSchemaGenerationError
+
+        try:
+            schema = handler(source_type)
+            # TODO if `schema['serialization']` is one of `'include-exclude-dict/sequence',
+            # schema validation will fail. That's why we use 'type ignore' comments below.
+            serialization = schema.get(
+                'serialization',
+                core_schema.wrap_serializer_function_ser_schema(
+                    function=lambda v, h: h(v),
+                    schema=schema,
+                    return_schema=handler.generate_schema(source_type),
+                ),
+            )
+        except PydanticSchemaGenerationError:
+            serialization = None
+
+        input_schema = handler.generate_schema(self.json_schema_input_type)
+
+        info_arg = _inspect_validator(self.func, 'plain')
+        if info_arg:
+            func = cast(core_schema.WithInfoValidatorFunction, self.func)
+            return core_schema.with_info_plain_validator_function(
+                func,
+                field_name=handler.field_name,
+                serialization=serialization,  # pyright: ignore[reportArgumentType]
+                json_schema_input_schema=input_schema,
+            )
+        else:
+            func = cast(core_schema.NoInfoValidatorFunction, self.func)
+            return core_schema.no_info_plain_validator_function(
+                func,
+                serialization=serialization,  # pyright: ignore[reportArgumentType]
+                json_schema_input_schema=input_schema,
+            )
+
+    @classmethod
+    def _from_decorator(cls, decorator: _decorators.Decorator[_decorators.FieldValidatorDecoratorInfo]) -> Self:
+        return cls(
+            func=decorator.func,
+            json_schema_input_type=decorator.info.json_schema_input_type,
+        )
+
+
+@dataclasses.dataclass(frozen=True, **_internal_dataclass.slots_true)
+class WrapValidator:
+    """Usage docs: https://docs.pydantic.dev/2.10/concepts/validators/#field-validators
+
+    A metadata class that indicates that a validation should be applied **around** the inner validation logic.
+
+    Attributes:
+        func: The validator function.
+        json_schema_input_type: The input type of the function. This is only used to generate the appropriate
+            JSON Schema (in validation mode).
+
+    ```python
+    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
+    ```
+    """
+
+    func: core_schema.NoInfoWrapValidatorFunction | core_schema.WithInfoWrapValidatorFunction
+    json_schema_input_type: Any = PydanticUndefined
+
+    def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
+        schema = handler(source_type)
+        input_schema = (
+            None
+            if self.json_schema_input_type is PydanticUndefined
+            else handler.generate_schema(self.json_schema_input_type)
+        )
+
+        info_arg = _inspect_validator(self.func, 'wrap')
+        if info_arg:
+            func = cast(core_schema.WithInfoWrapValidatorFunction, self.func)
+            return core_schema.with_info_wrap_validator_function(
+                func,
+                schema=schema,
+                field_name=handler.field_name,
+                json_schema_input_schema=input_schema,
+            )
+        else:
+            func = cast(core_schema.NoInfoWrapValidatorFunction, self.func)
+            return core_schema.no_info_wrap_validator_function(
+                func,
+                schema=schema,
+                json_schema_input_schema=input_schema,
+            )
+
+    @classmethod
+    def _from_decorator(cls, decorator: _decorators.Decorator[_decorators.FieldValidatorDecoratorInfo]) -> Self:
+        return cls(
+            func=decorator.func,
+            json_schema_input_type=decorator.info.json_schema_input_type,
+        )
+
+
+if TYPE_CHECKING:
+
+    class _OnlyValueValidatorClsMethod(Protocol):
+        def __call__(self, cls: Any, value: Any, /) -> Any: ...
+
+    class _V2ValidatorClsMethod(Protocol):
+        def __call__(self, cls: Any, value: Any, info: _core_schema.ValidationInfo, /) -> Any: ...
+
+    class _OnlyValueWrapValidatorClsMethod(Protocol):
+        def __call__(self, cls: Any, value: Any, handler: _core_schema.ValidatorFunctionWrapHandler, /) -> Any: ...
+
+    class _V2WrapValidatorClsMethod(Protocol):
+        def __call__(
+            self,
+            cls: Any,
+            value: Any,
+            handler: _core_schema.ValidatorFunctionWrapHandler,
+            info: _core_schema.ValidationInfo,
+            /,
+        ) -> Any: ...
+
+    _V2Validator = Union[
+        _V2ValidatorClsMethod,
+        _core_schema.WithInfoValidatorFunction,
+        _OnlyValueValidatorClsMethod,
+        _core_schema.NoInfoValidatorFunction,
+    ]
+
+    _V2WrapValidator = Union[
+        _V2WrapValidatorClsMethod,
+        _core_schema.WithInfoWrapValidatorFunction,
+        _OnlyValueWrapValidatorClsMethod,
+        _core_schema.NoInfoWrapValidatorFunction,
+    ]
+
+    _PartialClsOrStaticMethod: TypeAlias = Union[classmethod[Any, Any, Any], staticmethod[Any, Any], partialmethod[Any]]
+
+    _V2BeforeAfterOrPlainValidatorType = TypeVar(
+        '_V2BeforeAfterOrPlainValidatorType',
+        bound=Union[_V2Validator, _PartialClsOrStaticMethod],
+    )
+    _V2WrapValidatorType = TypeVar('_V2WrapValidatorType', bound=Union[_V2WrapValidator, _PartialClsOrStaticMethod])
+
+FieldValidatorModes: TypeAlias = Literal['before', 'after', 'wrap', 'plain']
+
+
+@overload
+def field_validator(
+    field: str,
+    /,
+    *fields: str,
+    mode: Literal['wrap'],
+    check_fields: bool | None = ...,
+    json_schema_input_type: Any = ...,
+) -> Callable[[_V2WrapValidatorType], _V2WrapValidatorType]: ...
+
+
+@overload
+def field_validator(
+    field: str,
+    /,
+    *fields: str,
+    mode: Literal['before', 'plain'],
+    check_fields: bool | None = ...,
+    json_schema_input_type: Any = ...,
+) -> Callable[[_V2BeforeAfterOrPlainValidatorType], _V2BeforeAfterOrPlainValidatorType]: ...
+
+
+@overload
+def field_validator(
+    field: str,
+    /,
+    *fields: str,
+    mode: Literal['after'] = ...,
+    check_fields: bool | None = ...,
+) -> Callable[[_V2BeforeAfterOrPlainValidatorType], _V2BeforeAfterOrPlainValidatorType]: ...
+
+
+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.10/concepts/validators/#field-validators
+
+    Decorate methods on the class indicating that they should be used to validate fields.
+
+    Example usage:
+    ```python
+    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
+
+
+_ModelType = TypeVar('_ModelType')
+_ModelTypeCo = TypeVar('_ModelTypeCo', covariant=True)
+
+
+class ModelWrapValidatorHandler(_core_schema.ValidatorFunctionWrapHandler, Protocol[_ModelTypeCo]):
+    """`@model_validator` decorated function handler argument type. This is used when `mode='wrap'`."""
+
+    def __call__(  # noqa: D102
+        self,
+        value: Any,
+        outer_location: str | int | None = None,
+        /,
+    ) -> _ModelTypeCo:  # pragma: no cover
+        ...
+
+
+class ModelWrapValidatorWithoutInfo(Protocol[_ModelType]):
+    """A `@model_validator` decorated function signature.
+    This is used when `mode='wrap'` and the function does not have info argument.
+    """
+
+    def __call__(  # noqa: D102
+        self,
+        cls: type[_ModelType],
+        # this can be a dict, a model instance
+        # or anything else that gets passed to validate_python
+        # thus validators _must_ handle all cases
+        value: Any,
+        handler: ModelWrapValidatorHandler[_ModelType],
+        /,
+    ) -> _ModelType: ...
+
+
+class ModelWrapValidator(Protocol[_ModelType]):
+    """A `@model_validator` decorated function signature. This is used when `mode='wrap'`."""
+
+    def __call__(  # noqa: D102
+        self,
+        cls: type[_ModelType],
+        # this can be a dict, a model instance
+        # or anything else that gets passed to validate_python
+        # thus validators _must_ handle all cases
+        value: Any,
+        handler: ModelWrapValidatorHandler[_ModelType],
+        info: _core_schema.ValidationInfo,
+        /,
+    ) -> _ModelType: ...
+
+
+class FreeModelBeforeValidatorWithoutInfo(Protocol):
+    """A `@model_validator` decorated function signature.
+    This is used when `mode='before'` and the function does not have info argument.
+    """
+
+    def __call__(  # noqa: D102
+        self,
+        # this can be a dict, a model instance
+        # or anything else that gets passed to validate_python
+        # thus validators _must_ handle all cases
+        value: Any,
+        /,
+    ) -> Any: ...
+
+
+class ModelBeforeValidatorWithoutInfo(Protocol):
+    """A `@model_validator` decorated function signature.
+    This is used when `mode='before'` and the function does not have info argument.
+    """
+
+    def __call__(  # noqa: D102
+        self,
+        cls: Any,
+        # this can be a dict, a model instance
+        # or anything else that gets passed to validate_python
+        # thus validators _must_ handle all cases
+        value: Any,
+        /,
+    ) -> Any: ...
+
+
+class FreeModelBeforeValidator(Protocol):
+    """A `@model_validator` decorated function signature. This is used when `mode='before'`."""
+
+    def __call__(  # noqa: D102
+        self,
+        # this can be a dict, a model instance
+        # or anything else that gets passed to validate_python
+        # thus validators _must_ handle all cases
+        value: Any,
+        info: _core_schema.ValidationInfo,
+        /,
+    ) -> Any: ...
+
+
+class ModelBeforeValidator(Protocol):
+    """A `@model_validator` decorated function signature. This is used when `mode='before'`."""
+
+    def __call__(  # noqa: D102
+        self,
+        cls: Any,
+        # this can be a dict, a model instance
+        # or anything else that gets passed to validate_python
+        # thus validators _must_ handle all cases
+        value: Any,
+        info: _core_schema.ValidationInfo,
+        /,
+    ) -> Any: ...
+
+
+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 = Callable[[_ModelType, _core_schema.ValidationInfo], _ModelType]
+"""A `@model_validator` decorated function signature. This is used when `mode='after'`."""
+
+_AnyModelWrapValidator = Union[ModelWrapValidator[_ModelType], ModelWrapValidatorWithoutInfo[_ModelType]]
+_AnyModelBeforeValidator = Union[
+    FreeModelBeforeValidator, ModelBeforeValidator, FreeModelBeforeValidatorWithoutInfo, ModelBeforeValidatorWithoutInfo
+]
+_AnyModelAfterValidator = Union[ModelAfterValidator[_ModelType], ModelAfterValidatorWithoutInfo[_ModelType]]
+
+
+@overload
+def model_validator(
+    *,
+    mode: Literal['wrap'],
+) -> Callable[
+    [_AnyModelWrapValidator[_ModelType]], _decorators.PydanticDescriptorProxy[_decorators.ModelValidatorDecoratorInfo]
+]: ...
+
+
+@overload
+def model_validator(
+    *,
+    mode: Literal['before'],
+) -> Callable[
+    [_AnyModelBeforeValidator], _decorators.PydanticDescriptorProxy[_decorators.ModelValidatorDecoratorInfo]
+]: ...
+
+
+@overload
+def model_validator(
+    *,
+    mode: Literal['after'],
+) -> Callable[
+    [_AnyModelAfterValidator[_ModelType]], _decorators.PydanticDescriptorProxy[_decorators.ModelValidatorDecoratorInfo]
+]: ...
+
+
+def model_validator(
+    *,
+    mode: Literal['wrap', 'before', 'after'],
+) -> Any:
+    """Usage docs: https://docs.pydantic.dev/2.10/concepts/validators/#model-validators
+
+    Decorate model methods for validation purposes.
+
+    Example usage:
+    ```python
+    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
+
+
+AnyType = TypeVar('AnyType')
+
+
+if TYPE_CHECKING:
+    # If we add configurable attributes to IsInstance, we'd probably need to stop hiding it from type checkers like this
+    InstanceOf = Annotated[AnyType, ...]  # `IsInstance[Sequence]` will be recognized by type checkers as `Sequence`
+
+else:
+
+    @dataclasses.dataclass(**_internal_dataclass.slots_true)
+    class InstanceOf:
+        '''Generic type for annotating a type that is an instance of a given class.
+
+        Example:
+            ```python
+            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'
+                │   }
+                ]
+                """
+            ```
+        '''
+
+        @classmethod
+        def __class_getitem__(cls, item: AnyType) -> AnyType:
+            return Annotated[item, cls()]
+
+        @classmethod
+        def __get_pydantic_core_schema__(cls, source: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
+            from pydantic import PydanticSchemaGenerationError
+
+            # use the generic _origin_ as the second argument to isinstance when appropriate
+            instance_of_schema = core_schema.is_instance_schema(_generics.get_origin(source) or source)
+
+            try:
+                # Try to generate the "standard" schema, which will be used when loading from JSON
+                original_schema = handler(source)
+            except PydanticSchemaGenerationError:
+                # If that fails, just produce a schema that can validate from python
+                return instance_of_schema
+            else:
+                # Use the "original" approach to serialization
+                instance_of_schema['serialization'] = core_schema.wrap_serializer_function_ser_schema(
+                    function=lambda v, h: h(v), schema=original_schema
+                )
+                return core_schema.json_or_python_schema(python_schema=instance_of_schema, json_schema=original_schema)
+
+        __hash__ = object.__hash__
+
+
+if TYPE_CHECKING:
+    SkipValidation = Annotated[AnyType, ...]  # SkipValidation[list[str]] will be treated by type checkers as list[str]
+else:
+
+    @dataclasses.dataclass(**_internal_dataclass.slots_true)
+    class 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.
+        """
+
+        def __class_getitem__(cls, item: Any) -> Any:
+            return Annotated[item, SkipValidation()]
+
+        @classmethod
+        def __get_pydantic_core_schema__(cls, source: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
+            original_schema = handler(source)
+            metadata = {'pydantic_js_annotation_functions': [lambda _c, h: h(original_schema)]}
+            return core_schema.any_schema(
+                metadata=metadata,
+                serialization=core_schema.wrap_serializer_function_ser_schema(
+                    function=lambda v, h: h(v), schema=original_schema
+                ),
+            )
+
+        __hash__ = object.__hash__