1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
import dataclasses
import re
from datetime import date, datetime
import pytest
from pydantic_core import SchemaValidator, ValidationError, core_schema
from .conftest import Err
def test_bool():
v = SchemaValidator(core_schema.bool_schema())
assert v.validate_strings('true') is True
assert v.validate_strings('true', strict=True) is True
assert v.validate_strings('false') is False
@pytest.mark.parametrize(
'schema,input_value,expected,strict',
[
(core_schema.int_schema(), '1', 1, False),
(core_schema.int_schema(), '1', 1, True),
(core_schema.int_schema(), 'xxx', Err('type=int_parsing'), True),
(core_schema.float_schema(), '1.1', 1.1, False),
(core_schema.float_schema(), '1.10', 1.1, False),
(core_schema.float_schema(), '1.1', 1.1, True),
(core_schema.float_schema(), '1.10', 1.1, True),
(core_schema.date_schema(), '2017-01-01', date(2017, 1, 1), False),
(core_schema.date_schema(), '2017-01-01', date(2017, 1, 1), True),
(core_schema.datetime_schema(), '2017-01-01T12:13:14.567', datetime(2017, 1, 1, 12, 13, 14, 567_000), False),
(core_schema.datetime_schema(), '2017-01-01T12:13:14.567', datetime(2017, 1, 1, 12, 13, 14, 567_000), True),
(core_schema.date_schema(), '2017-01-01T12:13:14.567', Err('type=date_from_datetime_inexact'), False),
(core_schema.date_schema(), '2017-01-01T12:13:14.567', Err('type=date_parsing'), True),
(core_schema.date_schema(), '2017-01-01T00:00:00', date(2017, 1, 1), False),
(core_schema.date_schema(), '2017-01-01T00:00:00', Err('type=date_parsing'), True),
],
ids=repr,
)
def test_validate_strings(schema, input_value, expected, strict):
v = SchemaValidator(schema)
if isinstance(expected, Err):
with pytest.raises(ValidationError, match=re.escape(expected.message)):
v.validate_strings(input_value, strict=strict)
else:
assert v.validate_strings(input_value, strict=strict) == expected
def test_dict():
v = SchemaValidator(core_schema.dict_schema(core_schema.int_schema(), core_schema.date_schema()))
assert v.validate_strings({'1': '2017-01-01', '2': '2017-01-02'}) == {1: date(2017, 1, 1), 2: date(2017, 1, 2)}
assert v.validate_strings({'1': '2017-01-01', '2': '2017-01-02'}, strict=True) == {
1: date(2017, 1, 1),
2: date(2017, 1, 2),
}
def test_model():
class MyModel:
# this is not required, but it avoids `__pydantic_fields_set__` being included in `__dict__`
__slots__ = '__dict__', '__pydantic_fields_set__', '__pydantic_extra__', '__pydantic_private__'
field_a: int
field_b: date
v = SchemaValidator(
core_schema.model_schema(
MyModel,
core_schema.model_fields_schema(
{
'field_a': core_schema.model_field(core_schema.int_schema()),
'field_b': core_schema.model_field(core_schema.date_schema()),
}
),
)
)
m2 = v.validate_strings({'field_a': '1', 'field_b': '2017-01-01'})
assert m2.__dict__ == {'field_a': 1, 'field_b': date(2017, 1, 1)}
m2 = v.validate_strings({'field_a': '1', 'field_b': '2017-01-01'}, strict=True)
assert m2.__dict__ == {'field_a': 1, 'field_b': date(2017, 1, 1)}
def test_dataclass():
@dataclasses.dataclass
class MyDataClass:
field_a: int
field_b: date
v = SchemaValidator(
core_schema.dataclass_schema(
MyDataClass,
core_schema.dataclass_args_schema(
'MyDataClass',
[
core_schema.dataclass_field('field_a', core_schema.int_schema()),
core_schema.dataclass_field('field_b', core_schema.date_schema()),
],
),
['field_a', 'field_b'],
)
)
m2 = v.validate_strings({'field_a': '1', 'field_b': '2017-01-01'})
assert m2.__dict__ == {'field_a': 1, 'field_b': date(2017, 1, 1)}
m2 = v.validate_strings({'field_a': '1', 'field_b': '2017-01-01'}, strict=True)
assert m2.__dict__ == {'field_a': 1, 'field_b': date(2017, 1, 1)}
def test_typed_dict():
v = SchemaValidator(
core_schema.typed_dict_schema(
{
'field_a': core_schema.typed_dict_field(core_schema.int_schema()),
'field_b': core_schema.typed_dict_field(core_schema.date_schema()),
}
)
)
m2 = v.validate_strings({'field_a': '1', 'field_b': '2017-01-01'})
assert m2 == {'field_a': 1, 'field_b': date(2017, 1, 1)}
m2 = v.validate_strings({'field_a': '1', 'field_b': '2017-01-01'}, strict=True)
assert m2 == {'field_a': 1, 'field_b': date(2017, 1, 1)}
def test_validate_strings_forbid_extra_fn_override():
v = SchemaValidator(
core_schema.typed_dict_schema(
{
'f': core_schema.typed_dict_field(core_schema.int_schema()),
}
)
)
with pytest.raises(ValidationError, match='Extra inputs are not permitted'):
v.validate_strings({'f': '1', 'extra_field': '123'}, extra='forbid')
|