Skip to content

Commit 8df178d

Browse files
committed
Update tests and fix lint errors
1 parent 095950b commit 8df178d

File tree

6 files changed

+98
-41
lines changed

6 files changed

+98
-41
lines changed

python/pydantic_core/core_schema.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,6 +2067,7 @@ def fn(v: bytes, info: core_schema.ValidationInfo) -> str:
20672067
Args:
20682068
function: The validator function to call
20692069
field_name: The name of the field
2070+
model_type: The type of the model
20702071
schema: The schema to validate the output of the validator function
20712072
ref: optional unique identifier of the schema, used to reference the schema in other places
20722073
json_schema_input_schema: The core schema to be used to generate the corresponding JSON Schema input type
@@ -2137,6 +2138,7 @@ def with_info_after_validator_function(
21372138
schema: CoreSchema,
21382139
*,
21392140
field_name: str | None = None,
2141+
model_type: type | None = None,
21402142
ref: str | None = None,
21412143
metadata: Dict[str, Any] | None = None,
21422144
serialization: SerSchema | None = None,
@@ -2165,14 +2167,15 @@ def fn(v: str, info: core_schema.ValidationInfo) -> str:
21652167
Args:
21662168
function: The validator function to call after the schema is validated
21672169
schema: The schema to validate before the validator function
2168-
field_name: The name of the field this validators is applied to, if any
2170+
field_name: The name of the field this validator is applied to, if any
2171+
model_type: The type of the model this validator is applied to, if any
21692172
ref: optional unique identifier of the schema, used to reference the schema in other places
21702173
metadata: Any other information you want to include with the schema, not used by pydantic-core
21712174
serialization: Custom serialization schema
21722175
"""
21732176
return _dict_not_none(
21742177
type='function-after',
2175-
function=_dict_not_none(type='with-info', function=function, field_name=field_name),
2178+
function=_dict_not_none(type='with-info', function=function, field_name=field_name, model_type=model_type),
21762179
schema=schema,
21772180
ref=ref,
21782181
metadata=metadata,
@@ -2272,6 +2275,7 @@ def with_info_wrap_validator_function(
22722275
schema: CoreSchema,
22732276
*,
22742277
field_name: str | None = None,
2278+
model_type: type | None = None,
22752279
json_schema_input_schema: CoreSchema | None = None,
22762280
ref: str | None = None,
22772281
metadata: Dict[str, Any] | None = None,
@@ -2302,15 +2306,16 @@ def fn(
23022306
Args:
23032307
function: The validator function to call
23042308
schema: The schema to validate the output of the validator function
2305-
field_name: The name of the field this validators is applied to, if any
2309+
field_name: The name of the field this validator is applied to, if any
2310+
model_type: The type of the model this validator is applied to, if any
23062311
json_schema_input_schema: The core schema to be used to generate the corresponding JSON Schema input type
23072312
ref: optional unique identifier of the schema, used to reference the schema in other places
23082313
metadata: Any other information you want to include with the schema, not used by pydantic-core
23092314
serialization: Custom serialization schema
23102315
"""
23112316
return _dict_not_none(
23122317
type='function-wrap',
2313-
function=_dict_not_none(type='with-info', function=function, field_name=field_name),
2318+
function=_dict_not_none(type='with-info', function=function, field_name=field_name, model_type=model_type),
23142319
schema=schema,
23152320
json_schema_input_schema=json_schema_input_schema,
23162321
ref=ref,
@@ -2372,6 +2377,7 @@ def with_info_plain_validator_function(
23722377
function: WithInfoValidatorFunction,
23732378
*,
23742379
field_name: str | None = None,
2380+
model_type: type | None = None,
23752381
ref: str | None = None,
23762382
json_schema_input_schema: CoreSchema | None = None,
23772383
metadata: Dict[str, Any] | None = None,
@@ -2394,15 +2400,16 @@ def fn(v: str, info: core_schema.ValidationInfo) -> str:
23942400
23952401
Args:
23962402
function: The validator function to call
2397-
field_name: The name of the field this validators is applied to, if any
2403+
field_name: The name of the field this validator is applied to, if any
2404+
model_type: The type of the model this validator is applied to, if any
23982405
ref: optional unique identifier of the schema, used to reference the schema in other places
23992406
json_schema_input_schema: The core schema to be used to generate the corresponding JSON Schema input type
24002407
metadata: Any other information you want to include with the schema, not used by pydantic-core
24012408
serialization: Custom serialization schema
24022409
"""
24032410
return _dict_not_none(
24042411
type='function-plain',
2405-
function=_dict_not_none(type='with-info', function=function, field_name=field_name),
2412+
function=_dict_not_none(type='with-info', function=function, field_name=field_name, model_type=model_type),
24062413
ref=ref,
24072414
json_schema_input_schema=json_schema_input_schema,
24082415
metadata=metadata,

src/validators/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ impl ValidationInfo {
555555
config: config.clone_ref(py),
556556
context: extra.context.map(|ctx| ctx.clone().into()),
557557
field_name,
558-
model_type: model_type.map(|t| t.clone().into()),
558+
model_type,
559559
data: extra.data.as_ref().map(|data| data.clone().into()),
560560
mode: extra.input_type,
561561
}

tests/validators/test_dataclasses.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ def func(x, info):
880880
core_schema.dataclass_field(
881881
'field_b',
882882
core_schema.with_info_after_validator_function(
883-
func, core_schema.int_schema(), field_name='field_b'
883+
func, core_schema.int_schema(), field_name='field_b', model_type=MyDataclass
884884
),
885885
),
886886
core_schema.dataclass_field('field_c', core_schema.int_schema()),
@@ -894,14 +894,16 @@ def func(x, info):
894894
assert m.field_a == 'x'
895895
assert m.field_b == 246
896896
assert m.field_c == 456
897-
assert calls == ["ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b')"]
897+
assert calls == [
898+
"ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b', model_type=<class 'tests.validators.test_dataclasses.test_validate_assignment_function.<locals>.MyDataclass'>)"
899+
]
898900

899901
v.validate_assignment(m, 'field_b', '111')
900902

901903
assert m.field_b == 222
902904
assert calls == [
903-
"ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b')",
904-
"ValidationInfo(config=None, context=None, data={'field_a': 'x', 'field_c': 456}, field_name='field_b')",
905+
"ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b', model_type=<class 'tests.validators.test_dataclasses.test_validate_assignment_function.<locals>.MyDataclass'>)",
906+
"ValidationInfo(config=None, context=None, data={'field_a': 'x', 'field_c': 456}, field_name='field_b', model_type=<class 'tests.validators.test_dataclasses.test_validate_assignment_function.<locals>.MyDataclass'>)",
905907
]
906908

907909

tests/validators/test_function.py

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,22 @@ def f(input_value, info):
145145
@pytest.mark.parametrize(
146146
'config,kwargs,expected_repr',
147147
[
148-
(None, {}, 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
149-
(None, {'context': {1: 2}}, 'ValidationInfo(config=None, context={1: 2}, data=None, field_name=None)'),
150-
(None, {'context': None}, 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
151-
({'title': 'hello'}, {}, "ValidationInfo(config={'title': 'hello'}, context=None, data=None, field_name=None)"),
148+
(None, {}, 'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)'),
149+
(
150+
None,
151+
{'context': {1: 2}},
152+
'ValidationInfo(config=None, context={1: 2}, data=None, field_name=None, model_type=None)',
153+
),
154+
(
155+
None,
156+
{'context': None},
157+
'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)',
158+
),
159+
(
160+
{'title': 'hello'},
161+
{},
162+
"ValidationInfo(config={'title': 'hello'}, context=None, data=None, field_name=None, model_type=None)",
163+
),
152164
],
153165
)
154166
def test_val_info_repr(config, kwargs, expected_repr):
@@ -591,8 +603,14 @@ class Model:
591603
def f(input_value: Any, info: core_schema.ValidationInfo) -> Any:
592604
assert info.field_name == 'x'
593605
assert info.data == {}
594-
assert repr(info) == "ValidationInfo(config=None, context=None, data={}, field_name='x')"
595-
assert str(info) == "ValidationInfo(config=None, context=None, data={}, field_name='x')"
606+
assert (
607+
repr(info)
608+
== "ValidationInfo(config=None, context=None, data={}, field_name='x', model_type=<class 'tests.validators.test_function.test_model_field_before_validator.<locals>.Model'>)"
609+
)
610+
assert (
611+
str(info)
612+
== "ValidationInfo(config=None, context=None, data={}, field_name='x', model_type=<class 'tests.validators.test_function.test_model_field_before_validator.<locals>.Model'>)"
613+
)
596614
assert isinstance(input_value, bytes)
597615
return f'input: {input_value.decode()}'
598616

@@ -602,7 +620,9 @@ def f(input_value: Any, info: core_schema.ValidationInfo) -> Any:
602620
core_schema.model_fields_schema(
603621
{
604622
'x': core_schema.model_field(
605-
core_schema.with_info_before_validator_function(f, core_schema.str_schema(), field_name='x')
623+
core_schema.with_info_before_validator_function(
624+
f, core_schema.str_schema(), field_name='x', model_type=Model
625+
)
606626
)
607627
}
608628
),
@@ -628,7 +648,9 @@ def f(input_value: str, info: core_schema.ValidationInfo) -> Any:
628648
core_schema.model_fields_schema(
629649
{
630650
'x': core_schema.model_field(
631-
core_schema.with_info_after_validator_function(f, core_schema.str_schema(), field_name='x')
651+
core_schema.with_info_after_validator_function(
652+
f, core_schema.str_schema(), field_name='x', model_type=Model
653+
)
632654
)
633655
}
634656
),
@@ -652,7 +674,11 @@ def f(input_value: Any, info: core_schema.ValidationInfo) -> Any:
652674
core_schema.model_schema(
653675
Model,
654676
core_schema.model_fields_schema(
655-
{'x': core_schema.model_field(core_schema.with_info_plain_validator_function(f, field_name='x'))}
677+
{
678+
'x': core_schema.model_field(
679+
core_schema.with_info_plain_validator_function(f, field_name='x', model_type=Model)
680+
)
681+
}
656682
),
657683
)
658684
)
@@ -676,7 +702,9 @@ def f(input_value: Any, val: core_schema.ValidatorFunctionWrapHandler, info: cor
676702
core_schema.model_fields_schema(
677703
{
678704
'x': core_schema.model_field(
679-
core_schema.with_info_wrap_validator_function(f, core_schema.str_schema(), field_name='x')
705+
core_schema.with_info_wrap_validator_function(
706+
f, core_schema.str_schema(), field_name='x', model_type=Model
707+
)
680708
)
681709
}
682710
),
@@ -921,25 +949,27 @@ def sample_repr(v: Any, info: core_schema.ValidationInfo) -> Any:
921949
reprs.append(repr(info))
922950
return v
923951

952+
class Foo:
953+
def __repr__(self) -> str:
954+
return 'This is Foo!'
955+
924956
v = SchemaValidator(
925957
core_schema.chain_schema(
926958
[
927959
core_schema.with_info_plain_validator_function(sample_repr),
928960
core_schema.with_info_plain_validator_function(sample_repr, field_name='x'),
961+
core_schema.with_info_plain_validator_function(sample_repr, field_name='x', model_type=Foo),
929962
]
930963
)
931964
)
932965

933-
class Foo:
934-
def __repr__(self) -> str:
935-
return 'This is Foo!'
936-
937966
v.validate_python(Foo())
938967

939968
# insert_assert(reprs)
940969
assert reprs == [
941-
'ValidationInfo(config=None, context=None, data=None, field_name=None)',
942-
"ValidationInfo(config=None, context=None, data=None, field_name='x')",
970+
'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)',
971+
"ValidationInfo(config=None, context=None, data=None, field_name='x', model_type=None)",
972+
"ValidationInfo(config=None, context=None, data=None, field_name='x', model_type=<class 'tests.validators.test_function.test_reprs.<locals>.Foo'>)",
943973
]
944974

945975

tests/validators/test_model.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ def func(x, info):
10921092
'field_a': core_schema.model_field(core_schema.str_schema()),
10931093
'field_b': core_schema.model_field(
10941094
core_schema.with_info_after_validator_function(
1095-
func, core_schema.int_schema(), field_name='field_b'
1095+
func, core_schema.int_schema(), field_name='field_b', model_type=MyModel
10961096
)
10971097
),
10981098
'field_c': core_schema.model_field(core_schema.int_schema()),
@@ -1106,14 +1106,16 @@ def func(x, info):
11061106
assert m.field_b == 246
11071107
assert m.field_c == 456
11081108
assert m.__pydantic_fields_set__ == {'field_a', 'field_b', 'field_c'}
1109-
assert calls == ["ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b')"]
1109+
assert calls == [
1110+
"ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b', model_type=<class 'tests.validators.test_model.test_validate_assignment_function.<locals>.MyModel'>)"
1111+
]
11101112

11111113
v.validate_assignment(m, 'field_b', '111')
11121114

11131115
assert m.field_b == 222
11141116
assert calls == [
1115-
"ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b')",
1116-
"ValidationInfo(config=None, context=None, data={'field_a': 'x', 'field_c': 456}, field_name='field_b')",
1117+
"ValidationInfo(config=None, context=None, data={'field_a': 'x'}, field_name='field_b', model_type=<class 'tests.validators.test_model.test_validate_assignment_function.<locals>.MyModel'>)",
1118+
"ValidationInfo(config=None, context=None, data={'field_a': 'x', 'field_c': 456}, field_name='field_b', model_type=<class 'tests.validators.test_model.test_validate_assignment_function.<locals>.MyModel'>)",
11171119
]
11181120

11191121

@@ -1183,18 +1185,30 @@ class MyModel:
11831185
[
11841186
(
11851187
core_schema.with_info_after_validator_function,
1186-
(({'a': 1, 'b': 2}, None, {'b'}), 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
1187-
(({'a': 10, 'b': 2}, None, {'a'}), 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
1188+
(
1189+
({'a': 1, 'b': 2}, None, {'b'}),
1190+
'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)',
1191+
),
1192+
(
1193+
({'a': 10, 'b': 2}, None, {'a'}),
1194+
'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)',
1195+
),
11881196
),
11891197
(
11901198
core_schema.with_info_before_validator_function,
1191-
({'b': 2}, 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
1192-
({'a': 10, 'b': 2}, 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
1199+
({'b': 2}, 'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)'),
1200+
(
1201+
{'a': 10, 'b': 2},
1202+
'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)',
1203+
),
11931204
),
11941205
(
11951206
core_schema.with_info_wrap_validator_function,
1196-
({'b': 2}, 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
1197-
({'a': 10, 'b': 2}, 'ValidationInfo(config=None, context=None, data=None, field_name=None)'),
1207+
({'b': 2}, 'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)'),
1208+
(
1209+
{'a': 10, 'b': 2},
1210+
'ValidationInfo(config=None, context=None, data=None, field_name=None, model_type=None)',
1211+
),
11981212
),
11991213
],
12001214
)

tests/validators/test_model_root.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,21 +140,25 @@ def f(input_value: str, info):
140140
v = SchemaValidator(
141141
core_schema.model_schema(
142142
RootModel,
143-
core_schema.with_info_after_validator_function(f, core_schema.str_schema(), field_name='root'),
143+
core_schema.with_info_after_validator_function(
144+
f, core_schema.str_schema(), field_name='root', model_type=RootModel
145+
),
144146
root_model=True,
145147
)
146148
)
147149
m = v.validate_python('foobar', context='call 1')
148150
assert isinstance(m, RootModel)
149151
assert m.root == 'foobar validated'
150-
assert call_infos == ["ValidationInfo(config=None, context='call 1', data=None, field_name='root')"]
152+
assert call_infos == [
153+
"ValidationInfo(config=None, context='call 1', data=None, field_name='root', model_type=<class 'tests.validators.test_model_root.test_field_function.<locals>.RootModel'>)"
154+
]
151155

152156
m2 = v.validate_assignment(m, 'root', 'baz', context='assignment call')
153157
assert m2 is m
154158
assert m.root == 'baz validated'
155159
assert call_infos == [
156-
"ValidationInfo(config=None, context='call 1', data=None, field_name='root')",
157-
"ValidationInfo(config=None, context='assignment call', data=None, field_name='root')",
160+
"ValidationInfo(config=None, context='call 1', data=None, field_name='root', model_type=<class 'tests.validators.test_model_root.test_field_function.<locals>.RootModel'>)",
161+
"ValidationInfo(config=None, context='assignment call', data=None, field_name='root', model_type=<class 'tests.validators.test_model_root.test_field_function.<locals>.RootModel'>)",
158162
]
159163

160164

0 commit comments

Comments
 (0)