diff --git a/changes/984-samuelcolvin.md b/changes/984-samuelcolvin.md new file mode 100644 index 0000000..8cd180e --- /dev/null +++ b/changes/984-samuelcolvin.md @@ -0,0 +1 @@ +Fix mypy complaint about `@root_validator(pre=True)` diff --git a/pydantic/class_validators.py b/pydantic/class_validators.py index fbe940e..e93254a 100644 --- a/pydantic/class_validators.py +++ b/pydantic/class_validators.py @@ -4,7 +4,7 @@ from functools import wraps from inspect import Signature, signature from itertools import chain from types import FunctionType -from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Type, Union +from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Type, Union, overload from .errors import ConfigError from .typing import AnyCallable @@ -90,9 +90,23 @@ def validator( return dec +@overload +def root_validator(_func: AnyCallable) -> classmethod: + ... + + +@overload +def root_validator(*, pre: bool = False) -> Callable[[AnyCallable], classmethod]: + ... + + def root_validator( _func: Optional[AnyCallable] = None, *, pre: bool = False ) -> Union[classmethod, Callable[[AnyCallable], classmethod]]: + """ + Decorate methods on a model indicating that they should be used to validate (and perhaps modify) data either + before or after standard model parsing/validation is performed. + """ if _func: _check_validator_name(_func) f_cls = classmethod(_func) diff --git a/tests/mypy/modules/success.py b/tests/mypy/modules/success.py index fb98d81..5e64c42 100644 --- a/tests/mypy/modules/success.py +++ b/tests/mypy/modules/success.py @@ -6,9 +6,9 @@ Do a little skipping about with types to demonstrate its usage. import json import sys from datetime import datetime -from typing import Generic, List, Optional, TypeVar +from typing import Any, Dict, Generic, List, Optional, TypeVar -from pydantic import BaseModel, NoneStr, StrictBool +from pydantic import BaseModel, NoneStr, StrictBool, root_validator, validator from pydantic.dataclasses import dataclass from pydantic.fields import Field from pydantic.generics import GenericModel @@ -25,6 +25,19 @@ class Model(BaseModel): signup_ts: Optional[datetime] = None list_of_ints: List[int] + @validator('age') + def check_age(cls, value: int) -> int: + assert value < 100, 'too old' + return value + + @root_validator + def root_check(cls, values: Dict[str, Any]) -> Dict[str, Any]: + return values + + @root_validator(pre=True) + def pre_root_check(cls, values: Dict[str, Any]) -> Dict[str, Any]: + return values + def dog_years(age: int) -> int: return age * 7