Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
class_validators.py257 linesDownload Raw Back to deprecated
1"""Old `@validator` and `@root_validator` function validators from V1."""2 3from __future__ import annotations as _annotations4 5from functools import partial, partialmethod6from types import FunctionType7from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar, Union, overload8from warnings import warn9 10from typing_extensions import Protocol, TypeAlias, deprecated11 12from .._internal import _decorators, _decorators_v113from ..errors import PydanticUserError14from ..warnings import PydanticDeprecatedSince2015 16_ALLOW_REUSE_WARNING_MESSAGE = '`allow_reuse` is deprecated and will be ignored; it should no longer be necessary'17 18 19if TYPE_CHECKING:20 21    class _OnlyValueValidatorClsMethod(Protocol):22        def __call__(self, __cls: Any, __value: Any) -> Any: ...23 24    class _V1ValidatorWithValuesClsMethod(Protocol):25        def __call__(self, __cls: Any, __value: Any, values: dict[str, Any]) -> Any: ...26 27    class _V1ValidatorWithValuesKwOnlyClsMethod(Protocol):28        def __call__(self, __cls: Any, __value: Any, *, values: dict[str, Any]) -> Any: ...29 30    class _V1ValidatorWithKwargsClsMethod(Protocol):31        def __call__(self, __cls: Any, **kwargs: Any) -> Any: ...32 33    class _V1ValidatorWithValuesAndKwargsClsMethod(Protocol):34        def __call__(self, __cls: Any, values: dict[str, Any], **kwargs: Any) -> Any: ...35 36    class _V1RootValidatorClsMethod(Protocol):37        def __call__(38            self, __cls: Any, __values: _decorators_v1.RootValidatorValues39        ) -> _decorators_v1.RootValidatorValues: ...40 41    V1Validator = Union[42        _OnlyValueValidatorClsMethod,43        _V1ValidatorWithValuesClsMethod,44        _V1ValidatorWithValuesKwOnlyClsMethod,45        _V1ValidatorWithKwargsClsMethod,46        _V1ValidatorWithValuesAndKwargsClsMethod,47        _decorators_v1.V1ValidatorWithValues,48        _decorators_v1.V1ValidatorWithValuesKwOnly,49        _decorators_v1.V1ValidatorWithKwargs,50        _decorators_v1.V1ValidatorWithValuesAndKwargs,51    ]52 53    V1RootValidator = Union[54        _V1RootValidatorClsMethod,55        _decorators_v1.V1RootValidatorFunction,56    ]57 58    _PartialClsOrStaticMethod: TypeAlias = Union[classmethod[Any, Any, Any], staticmethod[Any, Any], partialmethod[Any]]59 60    # Allow both a V1 (assumed pre=False) or V2 (assumed mode='after') validator61    # We lie to type checkers and say we return the same thing we get62    # but in reality we return a proxy object that _mostly_ behaves like the wrapped thing63    _V1ValidatorType = TypeVar('_V1ValidatorType', V1Validator, _PartialClsOrStaticMethod)64    _V1RootValidatorFunctionType = TypeVar(65        '_V1RootValidatorFunctionType',66        _decorators_v1.V1RootValidatorFunction,67        _V1RootValidatorClsMethod,68        _PartialClsOrStaticMethod,69    )70else:71    # See PyCharm issues https://youtrack.jetbrains.com/issue/PY-2191572    # and https://youtrack.jetbrains.com/issue/PY-5142873    DeprecationWarning = PydanticDeprecatedSince2074 75 76@deprecated(77    'Pydantic V1 style `@validator` validators are deprecated.'78    ' You should migrate to Pydantic V2 style `@field_validator` validators,'79    ' see the migration guide for more details',80    category=None,81)82def validator(83    __field: str,84    *fields: str,85    pre: bool = False,86    each_item: bool = False,87    always: bool = False,88    check_fields: bool | None = None,89    allow_reuse: bool = False,90) -> Callable[[_V1ValidatorType], _V1ValidatorType]:91    """Decorate methods on the class indicating that they should be used to validate fields.92 93    Args:94        __field (str): The first field the validator should be called on; this is separate95            from `fields` to ensure an error is raised if you don't pass at least one.96        *fields (str): Additional field(s) the validator should be called on.97        pre (bool, optional): Whether this validator should be called before the standard98            validators (else after). Defaults to False.99        each_item (bool, optional): For complex objects (sets, lists etc.) whether to validate100            individual elements rather than the whole object. Defaults to False.101        always (bool, optional): Whether this method and other validators should be called even if102            the value is missing. Defaults to False.103        check_fields (bool | None, optional): Whether to check that the fields actually exist on the model.104            Defaults to None.105        allow_reuse (bool, optional): Whether to track and raise an error if another validator refers to106            the decorated function. Defaults to False.107 108    Returns:109        Callable: A decorator that can be used to decorate a110            function to be used as a validator.111    """112    warn(113        'Pydantic V1 style `@validator` validators are deprecated.'114        ' You should migrate to Pydantic V2 style `@field_validator` validators,'115        ' see the migration guide for more details',116        DeprecationWarning,117        stacklevel=2,118    )119 120    if allow_reuse is True:  # pragma: no cover121        warn(_ALLOW_REUSE_WARNING_MESSAGE, DeprecationWarning, stacklevel=2)122    fields = __field, *fields123    if isinstance(fields[0], FunctionType):124        raise PydanticUserError(125            '`@validator` should be used with fields and keyword arguments, not bare. '126            "E.g. usage should be `@validator('<field_name>', ...)`",127            code='decorator-missing-arguments',128        )129    elif not all(isinstance(field, str) for field in fields):130        raise PydanticUserError(131            '`@validator` fields should be passed as separate string args. '132            "E.g. usage should be `@validator('<field_name_1>', '<field_name_2>', ...)`",133            code='decorator-invalid-fields',134        )135 136    mode: Literal['before', 'after'] = 'before' if pre is True else 'after'137 138    def dec(f: Any) -> _decorators.PydanticDescriptorProxy[Any]:139        if _decorators.is_instance_method_from_sig(f):140            raise PydanticUserError(141                '`@validator` cannot be applied to instance methods', code='validator-instance-method'142            )143        # auto apply the @classmethod decorator144        f = _decorators.ensure_classmethod_based_on_signature(f)145        wrap = _decorators_v1.make_generic_v1_field_validator146        validator_wrapper_info = _decorators.ValidatorDecoratorInfo(147            fields=fields,148            mode=mode,149            each_item=each_item,150            always=always,151            check_fields=check_fields,152        )153        return _decorators.PydanticDescriptorProxy(f, validator_wrapper_info, shim=wrap)154 155    return dec  # type: ignore[return-value]156 157 158@overload159def root_validator(160    *,161    # if you don't specify `pre` the default is `pre=False`162    # which means you need to specify `skip_on_failure=True`163    skip_on_failure: Literal[True],164    allow_reuse: bool = ...,165) -> Callable[166    [_V1RootValidatorFunctionType],167    _V1RootValidatorFunctionType,168]: ...169 170 171@overload172def root_validator(173    *,174    # if you specify `pre=True` then you don't need to specify175    # `skip_on_failure`, in fact it is not allowed as an argument!176    pre: Literal[True],177    allow_reuse: bool = ...,178) -> Callable[179    [_V1RootValidatorFunctionType],180    _V1RootValidatorFunctionType,181]: ...182 183 184@overload185def root_validator(186    *,187    # if you explicitly specify `pre=False` then you188    # MUST specify `skip_on_failure=True`189    pre: Literal[False],190    skip_on_failure: Literal[True],191    allow_reuse: bool = ...,192) -> Callable[193    [_V1RootValidatorFunctionType],194    _V1RootValidatorFunctionType,195]: ...196 197 198@deprecated(199    'Pydantic V1 style `@root_validator` validators are deprecated.'200    ' You should migrate to Pydantic V2 style `@model_validator` validators,'201    ' see the migration guide for more details',202    category=None,203)204def root_validator(205    *__args,206    pre: bool = False,207    skip_on_failure: bool = False,208    allow_reuse: bool = False,209) -> Any:210    """Decorate methods on a model indicating that they should be used to validate (and perhaps211    modify) data either before or after standard model parsing/validation is performed.212 213    Args:214        pre (bool, optional): Whether this validator should be called before the standard215            validators (else after). Defaults to False.216        skip_on_failure (bool, optional): Whether to stop validation and return as soon as a217            failure is encountered. Defaults to False.218        allow_reuse (bool, optional): Whether to track and raise an error if another validator219            refers to the decorated function. Defaults to False.220 221    Returns:222        Any: A decorator that can be used to decorate a function to be used as a root_validator.223    """224    warn(225        'Pydantic V1 style `@root_validator` validators are deprecated.'226        ' You should migrate to Pydantic V2 style `@model_validator` validators,'227        ' see the migration guide for more details',228        DeprecationWarning,229        stacklevel=2,230    )231 232    if __args:233        # Ensure a nice error is raised if someone attempts to use the bare decorator234        return root_validator()(*__args)  # type: ignore235 236    if allow_reuse is True:  # pragma: no cover237        warn(_ALLOW_REUSE_WARNING_MESSAGE, DeprecationWarning, stacklevel=2)238    mode: Literal['before', 'after'] = 'before' if pre is True else 'after'239    if pre is False and skip_on_failure is not True:240        raise PydanticUserError(241            'If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`.'242            ' Note that `@root_validator` is deprecated and should be replaced with `@model_validator`.',243            code='root-validator-pre-skip',244        )245 246    wrap = partial(_decorators_v1.make_v1_generic_root_validator, pre=pre)247 248    def dec(f: Callable[..., Any] | classmethod[Any, Any, Any] | staticmethod[Any, Any]) -> Any:249        if _decorators.is_instance_method_from_sig(f):250            raise TypeError('`@root_validator` cannot be applied to instance methods')251        # auto apply the @classmethod decorator252        res = _decorators.ensure_classmethod_based_on_signature(f)253        dec_info = _decorators.RootValidatorDecoratorInfo(mode=mode)254        return _decorators.PydanticDescriptorProxy(res, dec_info, shim=wrap)255 256    return dec257 
codekingpro/portable-devtools · Team Ai