forked from pydantic/pydantic-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_typing.py
180 lines (152 loc) · 6.46 KB
/
test_typing.py
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
from __future__ import annotations as _annotations
from datetime import date, datetime, time
from typing import Any
from pydantic_core import PydanticKnownError, SchemaError, SchemaValidator
from pydantic_core.core_schema import CoreConfig, CoreSchema, function_plain_schema
class Foo:
bar: str
def foo(bar: str) -> None:
...
def validator(value: Any, **kwargs: Any) -> None:
...
def test_schema_typing() -> None:
# this gets run by pyright, but we also check that it executes
schema: CoreSchema = {
'type': 'union',
'choices': [{'type': 'int'}, {'type': 'int', 'ge': 1}, {'type': 'float', 'lt': 1.0}],
}
SchemaValidator(schema)
schema: CoreSchema = {
'type': 'tagged-union',
'discriminator': 'type',
'choices': {
'apple': {'type': 'typed-dict', 'fields': {'pips': {'schema': {'type': 'int'}}}},
'banana': {'type': 'typed-dict', 'fields': {'curvature': {'schema': {'type': 'float'}}}},
},
}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'int', 'ge': 1}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'float', 'lt': 1.0}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'str', 'pattern': r'http://.*'}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'bool', 'strict': False}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'literal', 'expected': [1, '1']}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'any'}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'none'}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'bytes'}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'list', 'items_schema': {'type': 'str'}, 'min_length': 3}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'set', 'items_schema': {'type': 'str'}, 'max_length': 3}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'tuple', 'mode': 'variable', 'items_schema': {'type': 'str'}, 'max_length': 3}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'tuple', 'mode': 'positional', 'items_schema': [{'type': 'str'}, {'type': 'int'}]}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'frozenset', 'items_schema': {'type': 'str'}, 'max_length': 3}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'dict', 'keys_schema': {'type': 'str'}, 'values_schema': {'type': 'any'}}
SchemaValidator(schema)
schema: CoreSchema = {
'type': 'new-class',
'cls': Foo,
'schema': {'type': 'typed-dict', 'return_fields_set': True, 'fields': {'bar': {'schema': {'type': 'str'}}}},
}
SchemaValidator(schema)
# waiting for https://github.com/microsoft/pyright/issues/4313 to be fixed
schema: CoreSchema = { # type: ignore
'type': 'typed-dict',
'fields': {
'a': {'schema': {'type': 'str'}},
'b': {'schema': {'type': 'str'}, 'alias': 'foobar'},
'c': {'schema': {'type': 'str'}, 'alias': [['foobar', 0, 'bar'], ['foo']]},
'd': {'schema': {'type': 'default', 'schema': {'type': 'str'}, 'default': 'spam'}},
},
}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'function', 'mode': 'wrap', 'function': validator, 'schema': {'type': 'str'}}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'function', 'mode': 'plain', 'function': validator}
SchemaValidator(schema)
schema: CoreSchema = {
'ref': 'Branch',
'type': 'typed-dict',
'fields': {
'name': {'schema': {'type': 'str'}},
'sub_branch': {
'schema': {
'type': 'default',
'schema': {
'type': 'union',
'choices': [{'type': 'none'}, {'type': 'recursive-ref', 'schema_ref': 'Branch'}],
},
'default': None,
}
},
},
}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'date', 'le': date.today()}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'time', 'lt': time(12, 13, 14)}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'datetime', 'ge': datetime.now()}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'is-instance', 'cls': Foo}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'callable'}
SchemaValidator(schema)
schema: CoreSchema = {
'type': 'arguments',
'arguments_schema': [
{'name': 'a', 'mode': 'positional_only', 'schema': {'type': 'int'}},
{'name': 'b', 'schema': {'type': 'str'}},
{'name': 'c', 'mode': 'keyword_only', 'schema': {'type': 'bool'}},
],
}
SchemaValidator(schema)
schema: CoreSchema = {'type': 'call', 'arguments_schema': {'type': 'any'}, 'function': foo}
SchemaValidator(schema)
def test_schema_typing_error() -> None:
_: CoreSchema = {'type': 'wrong'} # type: ignore
def test_schema_validator() -> None:
SchemaValidator({'type': 'int'})
def test_schema_validator_wrong() -> None:
# use this instead of pytest.raises since pyright complains about input when pytest isn't installed
try:
SchemaValidator({'type': 'bad'}) # type: ignore
except SchemaError:
pass
else:
raise AssertionError('SchemaValidator did not raise SchemaError')
def test_correct_function_signature() -> None:
def my_validator(value: Any, *, data: Any, config: CoreConfig | None, context: Any, **future_kwargs: Any) -> str:
return str(value)
v = SchemaValidator(function_plain_schema(my_validator))
assert v.validate_python(1) == '1'
def test_wrong_function_signature() -> None:
def wrong_validator(value: Any) -> Any:
return value
v = SchemaValidator(function_plain_schema(wrong_validator)) # type: ignore
# use this instead of pytest.raises since pyright complains about input when pytest isn't installed
try:
v.validate_python(1)
except TypeError as exc:
assert 'unexpected keyword argument' in str(exc)
else:
raise AssertionError('v.validate_python(1) did not raise TypeError')
def test_type_error():
try:
PydanticKnownError('foobar') # type: ignore
except KeyError as exc:
assert str(exc) == '"Invalid error type: \'foobar\'"'
else:
raise AssertionError("PydanticKnownError('foobar') did not raise KeyError")
e = PydanticKnownError('recursion_loop')
assert isinstance(e, PydanticKnownError)