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
|
from decimal import Decimal
import pytest
from pydantic_core import SchemaError, SchemaValidator, ValidationError, core_schema
from pydantic_core import core_schema as cs
from ..conftest import PyAndJson
def test_chain():
validator = SchemaValidator(
cs.chain_schema(
steps=[cs.str_schema(), core_schema.with_info_plain_validator_function(lambda v, info: Decimal(v))]
)
)
assert validator.validate_python('1.44') == Decimal('1.44')
assert validator.validate_python(b'1.44') == Decimal('1.44')
def test_chain_many():
validator = SchemaValidator(
cs.chain_schema(
steps=[
core_schema.with_info_plain_validator_function(lambda v, info: f'{v}-1'),
core_schema.with_info_plain_validator_function(lambda v, info: f'{v}-2'),
core_schema.with_info_plain_validator_function(lambda v, info: f'{v}-3'),
core_schema.with_info_plain_validator_function(lambda v, info: f'{v}-4'),
]
)
)
assert validator.validate_python('input') == 'input-1-2-3-4'
def test_chain_error():
validator = SchemaValidator(cs.chain_schema(steps=[cs.str_schema(), cs.int_schema()]))
assert validator.validate_python('123') == 123
assert validator.validate_python(b'123') == 123
with pytest.raises(ValidationError) as exc_info:
validator.validate_python('abc')
# insert_assert(exc_info.value.errors(include_url=False))
assert exc_info.value.errors(include_url=False) == [
{
'type': 'int_parsing',
'loc': (),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'input': 'abc',
}
]
@pytest.mark.parametrize(
'input_value,expected', [('1.44', Decimal('1.44')), (1, Decimal(1)), (1.44, pytest.approx(1.44))]
)
def test_json(py_and_json: PyAndJson, input_value, expected):
validator = py_and_json(
{
'type': 'chain',
'steps': [
{'type': 'union', 'choices': [{'type': 'str'}, {'type': 'float'}]},
core_schema.with_info_plain_validator_function(lambda v, info: Decimal(v)),
],
}
)
output = validator.validate_test(input_value)
assert output == expected
assert isinstance(output, Decimal)
def test_flatten():
validator = SchemaValidator(
cs.chain_schema(
steps=[
core_schema.with_info_plain_validator_function(lambda v, info: f'{v}-1'),
cs.chain_schema(
steps=[
{
'type': 'function-plain',
'function': {'type': 'with-info', 'function': lambda v, info: f'{v}-2'},
},
{
'type': 'function-plain',
'function': {'type': 'with-info', 'function': lambda v, info: f'{v}-3'},
},
]
),
]
)
)
assert validator.validate_python('input') == 'input-1-2-3'
assert validator.title == 'chain[function-plain[<lambda>()],function-plain[<lambda>()],function-plain[<lambda>()]]'
def test_chain_empty():
with pytest.raises(SchemaError, match='One or more steps are required for a chain validator'):
SchemaValidator(cs.chain_schema(steps=[]))
def test_chain_one():
validator = SchemaValidator(
cs.chain_schema(steps=[core_schema.with_info_plain_validator_function(lambda v, info: f'{v}-1')])
)
assert validator.validate_python('input') == 'input-1'
assert validator.title == 'function-plain[<lambda>()]'
|