Skip to content

Commit d0d0b89

Browse files
committed
chore: ♻️ Ensure typing details are all setup correctly
1 parent cbf59db commit d0d0b89

File tree

4 files changed

+33
-28
lines changed

4 files changed

+33
-28
lines changed

pydantic_async_validation/metaclasses.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import TYPE_CHECKING, Any, Optional
1+
from typing import TYPE_CHECKING, Any, List, Optional, Tuple
22

33
from pydantic._internal._model_construction import ModelMetaclass # noqa
44

@@ -21,8 +21,12 @@ def __new__(
2121
namespace: dict[str, Any],
2222
**kwargs: Any,
2323
) -> Any:
24-
async_field_validators = []
25-
async_model_validators = []
24+
async_field_validators: List[Tuple[List[str], Validator]] = []
25+
async_model_validators: List[Validator] = []
26+
27+
async_field_validator_fields: Optional[List[str]]
28+
async_field_validator_config: "Optional[Validator]"
29+
async_model_validator_config: "Optional[Validator]"
2630

2731
for base in bases:
2832
async_field_validators += getattr(
@@ -37,23 +41,21 @@ def __new__(
3741
)
3842

3943
for _attr_name, attr_value in namespace.items():
40-
async_model_validator_config: "Optional[Validator]"
41-
4244
# Register all validators
43-
async_field_validator_fields, async_model_validator_config = getattr(
45+
async_field_validator_fields, async_field_validator_config = getattr(
4446
attr_value,
4547
ASYNC_FIELD_VALIDATOR_CONFIG_KEY,
4648
(None, None),
4749
)
4850
if (
4951
async_field_validator_fields is not None
50-
and async_model_validator_config is not None
51-
and callable(async_model_validator_config.func)
52+
and async_field_validator_config is not None
53+
and callable(async_field_validator_config.func)
5254
):
5355
async_field_validators.append(attr_value)
5456

5557
# Register all root validators
56-
async_model_validator_config: "Optional[Validator]" = getattr(
58+
async_model_validator_config = getattr(
5759
attr_value,
5860
ASYNC_MODEL_VALIDATOR_CONFIG_KEY,
5961
None,

pydantic_async_validation/mixins.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,39 @@ class AsyncValidationModelMixin(
2323
pydantic_model_async_model_validators: ClassVar[List[Validator]]
2424

2525
async def model_async_validate(self) -> None:
26+
field_names: list[str]
27+
validator: Validator
28+
2629
validation_errors = []
2730
validators = getattr(self, ASYNC_FIELD_VALIDATORS_KEY, [])
2831
root_validators = getattr(self, ASYNC_MODEL_VALIDATORS_KEY, [])
2932

3033
for validator_attr in validators:
31-
fields: list[str]
32-
validator: Validator
33-
fields, validator = getattr(
34+
field_names, validator = getattr(
3435
validator_attr,
3536
ASYNC_FIELD_VALIDATOR_CONFIG_KEY,
3637
)
37-
for field in fields:
38+
for field_name in field_names:
3839
try:
3940
await validator.func(
4041
self.__class__,
41-
getattr(self, field, None),
42+
getattr(self, field_name, None),
4243
self,
43-
field,
44+
field_name,
4445
validator,
4546
)
4647
except (ValueError, TypeError, AssertionError) as o_O:
4748
validation_errors.append(
4849
ErrorDetails(
4950
type='value_error',
5051
msg=str(o_O),
51-
loc=(field,),
52-
input=getattr(self, field, None),
52+
loc=(field_name,),
53+
input=getattr(self, field_name, None),
5354
),
5455
)
5556

5657
for validator_attr in root_validators:
57-
validator: Validator = getattr(
58+
validator = getattr(
5859
validator_attr,
5960
ASYNC_MODEL_VALIDATOR_CONFIG_KEY,
6061
)

pydantic_async_validation/utils.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,20 @@ def prepare_validator(function: Callable, allow_reuse: bool = False) -> classmet
1717
which generally isn't the intended behaviour,
1818
don't run in ipython (see #312) or if allow_reuse is False.
1919
"""
20-
f_cls = (
20+
f_cls: classmethod = (
2121
function
2222
if isinstance(function, classmethod)
2323
else classmethod(function)
2424
)
2525
if not allow_reuse:
2626
ref = f_cls.__func__.__module__ + '.' + f_cls.__func__.__qualname__
2727
if ref in _ASYNC_VALIDATOR_FUNCS:
28-
raise pydantic.ConfigError(
28+
# TODO: Does this still make sense? pydantic v2 seems to now need this?
29+
raise pydantic.PydanticUserError(
2930
f'Duplicate validator function "{ref}"; if this is intended, '
3031
f'set `allow_reuse=True`',
32+
# TODO: Find correct code for this - if we keep this exception
33+
code='validator-reuse', # type: ignore
3134
)
3235
_ASYNC_VALIDATOR_FUNCS.add(ref)
3336
return f_cls

pydantic_async_validation/validators.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from types import FunctionType
2-
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
2+
from typing import TYPE_CHECKING, Any, Callable, Optional, Tuple, Union
33

44
from pydantic.errors import PydanticUserError
55

@@ -24,7 +24,6 @@ def __init__(
2424
if TYPE_CHECKING:
2525
from inspect import Signature # noqa
2626

27-
from pydantic.fields import ModelField # noqa
2827
from pydantic.main import BaseConfig # noqa
2928
from pydantic.types import ModelOrDc # noqa
3029

@@ -33,7 +32,7 @@ def __init__(
3332
Optional[ModelOrDc],
3433
Any,
3534
dict[str, Any],
36-
ModelField,
35+
str,
3736
type[BaseConfig],
3837
],
3938
Any,
@@ -44,9 +43,9 @@ def __init__(
4443

4544

4645
def async_field_validator(
47-
__field: str,
46+
__field_name: str,
4847
/,
49-
*additional_fields: str,
48+
*additional_field_names: str,
5049
allow_reuse: bool = False,
5150
) -> Callable[[Callable], classmethod]:
5251
"""
@@ -56,23 +55,23 @@ def async_field_validator(
5655
function to a list of fields.
5756
"""
5857

59-
if isinstance(__field, FunctionType):
58+
if isinstance(__field_name, FunctionType):
6059
raise PydanticUserError(
6160
"validators should be used with fields and keyword arguments, "
6261
"not bare. "
6362
"E.g. usage should be `@async_field_validator('<field_name>', ...)`",
6463
code='validator-instance-method',
6564
)
6665

67-
fields = __field, *additional_fields
66+
field_names: Tuple[str, ...] = __field_name, *additional_field_names
6867

6968
def dec(func: Callable) -> classmethod:
7069
f_cls = prepare_validator(func, allow_reuse)
7170
setattr(
7271
f_cls,
7372
ASYNC_FIELD_VALIDATOR_CONFIG_KEY,
7473
(
75-
fields,
74+
field_names,
7675
Validator(
7776
func=make_generic_validator(f_cls.__func__),
7877
),

0 commit comments

Comments
 (0)