Skip to content

Commit 529f7dd

Browse files
committed
Fix error message for invalid validator signatures
Backport of: #12366
1 parent 445fa79 commit 529f7dd

File tree

4 files changed

+18
-13
lines changed

4 files changed

+18
-13
lines changed

pydantic/_internal/_decorators.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,14 +522,17 @@ def update_from_config(self, config_wrapper: ConfigWrapper) -> None:
522522
computed_field_dec.info._update_from_config(config_wrapper, name)
523523

524524

525-
def inspect_validator(validator: Callable[..., Any], mode: FieldValidatorModes) -> bool:
525+
def inspect_validator(
526+
validator: Callable[..., Any], *, mode: FieldValidatorModes, type: Literal['field', 'model']
527+
) -> bool:
526528
"""Look at a field or model validator function and determine whether it takes an info argument.
527529
528530
An error is raised if the function has an invalid signature.
529531
530532
Args:
531533
validator: The validator function to inspect.
532534
mode: The proposed validator mode.
535+
type: The type of validator, either 'field' or 'model'.
533536
534537
Returns:
535538
Whether the validator takes an info argument.
@@ -554,7 +557,7 @@ def inspect_validator(validator: Callable[..., Any], mode: FieldValidatorModes)
554557
return False
555558

556559
raise PydanticUserError(
557-
f'Unrecognized field_validator function signature for {validator} with `mode={mode}`:{sig}',
560+
f'Unrecognized {type} validator function signature for {validator} with `mode={mode}`: {sig}',
558561
code='validator-signature',
559562
)
560563

pydantic/_internal/_generate_schema.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,7 +2508,9 @@ def apply_validators(
25082508
The updated schema.
25092509
"""
25102510
for validator in validators:
2511-
info_arg = inspect_validator(validator.func, validator.info.mode)
2511+
# Actually, type could be 'field' or 'model', but this is only used for deprecated
2512+
# decorators, so let's not worry about it.
2513+
info_arg = inspect_validator(validator.func, mode=validator.info.mode, type='field')
25122514
val_type = 'with-info' if info_arg else 'no-info'
25132515

25142516
schema = _VALIDATOR_F_MATCH[(validator.info.mode, val_type)](validator.func, schema)
@@ -2565,7 +2567,7 @@ def apply_model_validators(
25652567
continue
25662568
if mode == 'outer' and validator.info.mode == 'before':
25672569
continue
2568-
info_arg = inspect_validator(validator.func, validator.info.mode)
2570+
info_arg = inspect_validator(validator.func, mode=validator.info.mode, type='model')
25692571
if validator.info.mode == 'wrap':
25702572
if info_arg:
25712573
schema = core_schema.with_info_wrap_validator_function(function=validator.func, schema=schema)

pydantic/functional_validators.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class Model(BaseModel):
7373

7474
def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
7575
schema = handler(source_type)
76-
info_arg = _inspect_validator(self.func, 'after')
76+
info_arg = _inspect_validator(self.func, mode='after', type='field')
7777
if info_arg:
7878
func = cast(core_schema.WithInfoValidatorFunction, self.func)
7979
return core_schema.with_info_after_validator_function(func, schema=schema)
@@ -131,7 +131,7 @@ def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaH
131131
else handler.generate_schema(self.json_schema_input_type)
132132
)
133133

134-
info_arg = _inspect_validator(self.func, 'before')
134+
info_arg = _inspect_validator(self.func, mode='before', type='field')
135135
if info_arg:
136136
func = cast(core_schema.WithInfoValidatorFunction, self.func)
137137
return core_schema.with_info_before_validator_function(
@@ -229,7 +229,7 @@ def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaH
229229

230230
input_schema = handler.generate_schema(self.json_schema_input_type)
231231

232-
info_arg = _inspect_validator(self.func, 'plain')
232+
info_arg = _inspect_validator(self.func, mode='plain', type='field')
233233
if info_arg:
234234
func = cast(core_schema.WithInfoValidatorFunction, self.func)
235235
return core_schema.with_info_plain_validator_function(
@@ -304,7 +304,7 @@ def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaH
304304
else handler.generate_schema(self.json_schema_input_type)
305305
)
306306

307-
info_arg = _inspect_validator(self.func, 'wrap')
307+
info_arg = _inspect_validator(self.func, mode='wrap', type='field')
308308
if info_arg:
309309
func = cast(core_schema.WithInfoWrapValidatorFunction, self.func)
310310
return core_schema.with_info_wrap_validator_function(

tests/test_decorators.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def _one_pos_required_arg_one_optional(a, b=1):
4141
],
4242
)
4343
def test_inspect_validator(obj, mode, expected):
44-
assert inspect_validator(obj, mode=mode) == expected
44+
assert inspect_validator(obj, mode=mode, type='field') == expected
4545

4646

4747
def test_inspect_validator_error_wrap():
@@ -52,12 +52,12 @@ def validator4(arg1, arg2, arg3, arg4):
5252
pass
5353

5454
with pytest.raises(PydanticUserError) as e:
55-
inspect_validator(validator1, mode='wrap')
55+
inspect_validator(validator1, mode='wrap', type='field')
5656

5757
assert e.value.code == 'validator-signature'
5858

5959
with pytest.raises(PydanticUserError) as e:
60-
inspect_validator(validator4, mode='wrap')
60+
inspect_validator(validator4, mode='wrap', type='field')
6161

6262
assert e.value.code == 'validator-signature'
6363

@@ -71,12 +71,12 @@ def validator3(arg1, arg2, arg3):
7171
pass
7272

7373
with pytest.raises(PydanticUserError) as e:
74-
inspect_validator(validator, mode=mode)
74+
inspect_validator(validator, mode=mode, type='field')
7575

7676
assert e.value.code == 'validator-signature'
7777

7878
with pytest.raises(PydanticUserError) as e:
79-
inspect_validator(validator3, mode=mode)
79+
inspect_validator(validator3, mode=mode, type='field')
8080

8181
assert e.value.code == 'validator-signature'
8282

0 commit comments

Comments
 (0)