mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
@@ -0,0 +1 @@
|
||||
Support plain `typing.Tuple` type
|
||||
+15
-9
@@ -346,7 +346,6 @@ class ModelField(Representation):
|
||||
Note: this method is **not** idempotent (because _type_analysis is not idempotent),
|
||||
e.g. calling it it multiple times may modify the field and configure it incorrectly.
|
||||
"""
|
||||
|
||||
self._set_default_and_type()
|
||||
if self.type_.__class__ == ForwardRef:
|
||||
# self.type_ is currently a ForwardRef and there's nothing we can do now,
|
||||
@@ -448,14 +447,19 @@ class ModelField(Representation):
|
||||
return
|
||||
|
||||
if issubclass(origin, Tuple): # type: ignore
|
||||
self.shape = SHAPE_TUPLE
|
||||
self.sub_fields = []
|
||||
for i, t in enumerate(get_args(self.type_)):
|
||||
if t is Ellipsis:
|
||||
self.type_ = get_args(self.type_)[0]
|
||||
self.shape = SHAPE_TUPLE_ELLIPSIS
|
||||
return
|
||||
self.sub_fields.append(self._create_sub_type(t, f'{self.name}_{i}'))
|
||||
# origin == Tuple without item type
|
||||
if not get_args(self.type_):
|
||||
self.type_ = Any
|
||||
self.shape = SHAPE_TUPLE_ELLIPSIS
|
||||
else:
|
||||
self.shape = SHAPE_TUPLE
|
||||
self.sub_fields = []
|
||||
for i, t in enumerate(get_args(self.type_)):
|
||||
if t is Ellipsis:
|
||||
self.type_ = get_args(self.type_)[0]
|
||||
self.shape = SHAPE_TUPLE_ELLIPSIS
|
||||
return
|
||||
self.sub_fields.append(self._create_sub_type(t, f'{self.name}_{i}'))
|
||||
return
|
||||
|
||||
if issubclass(origin, List):
|
||||
@@ -605,6 +609,8 @@ class ModelField(Representation):
|
||||
e: errors_.PydanticTypeError
|
||||
if self.shape == SHAPE_LIST:
|
||||
e = errors_.ListError()
|
||||
elif self.shape in (SHAPE_TUPLE, SHAPE_TUPLE_ELLIPSIS):
|
||||
e = errors_.TupleError()
|
||||
elif self.shape == SHAPE_SET:
|
||||
e = errors_.SetError()
|
||||
elif self.shape == SHAPE_FROZENSET:
|
||||
|
||||
+6
-3
@@ -2341,21 +2341,24 @@ def test_generic_without_params():
|
||||
class Model(BaseModel):
|
||||
generic_list: List
|
||||
generic_dict: Dict
|
||||
generic_tuple: Tuple
|
||||
|
||||
m = Model(generic_list=[0, 'a'], generic_dict={0: 'a', 'a': 0})
|
||||
assert m.dict() == {'generic_list': [0, 'a'], 'generic_dict': {0: 'a', 'a': 0}}
|
||||
m = Model(generic_list=[0, 'a'], generic_dict={0: 'a', 'a': 0}, generic_tuple=(1, 'q'))
|
||||
assert m.dict() == {'generic_list': [0, 'a'], 'generic_dict': {0: 'a', 'a': 0}, 'generic_tuple': (1, 'q')}
|
||||
|
||||
|
||||
def test_generic_without_params_error():
|
||||
class Model(BaseModel):
|
||||
generic_list: List
|
||||
generic_dict: Dict
|
||||
generic_tuple: Tuple
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Model(generic_list=0, generic_dict=0)
|
||||
Model(generic_list=0, generic_dict=0, generic_tuple=0)
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('generic_list',), 'msg': 'value is not a valid list', 'type': 'type_error.list'},
|
||||
{'loc': ('generic_dict',), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'},
|
||||
{'loc': ('generic_tuple',), 'msg': 'value is not a valid tuple', 'type': 'type_error.tuple'},
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user