fix: support empty tuple type (#2319)

This commit is contained in:
Eric Jolibois
2021-02-13 12:10:08 +01:00
committed by GitHub
parent 12ebf0cfab
commit 9ca8fe85eb
3 changed files with 27 additions and 12 deletions
+1
View File
@@ -0,0 +1 @@
Support empty tuple type
+10 -8
View File
@@ -452,18 +452,20 @@ class ModelField(Representation):
if issubclass(origin, Tuple): # type: ignore
# origin == Tuple without item type
if not get_args(self.type_):
args = get_args(self.type_)
if not args: # plain tuple
self.type_ = Any
self.shape = SHAPE_TUPLE_ELLIPSIS
elif len(args) == 2 and args[1] is Ellipsis: # e.g. Tuple[int, ...]
self.type_ = args[0]
self.shape = SHAPE_TUPLE_ELLIPSIS
elif args == ((),): # Tuple[()] means empty tuple
self.shape = SHAPE_TUPLE
self.type_ = Any
self.sub_fields = []
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}'))
self.sub_fields = [self._create_sub_type(t, f'{self.name}_{i}') for i, t in enumerate(args)]
return
if issubclass(origin, List):
+16 -4
View File
@@ -194,26 +194,38 @@ def test_tuple():
def test_tuple_more():
class Model(BaseModel):
empty_tuple: Tuple[()]
simple_tuple: tuple = None
tuple_of_different_types: Tuple[int, float, str, bool] = None
m = Model(simple_tuple=[1, 2, 3, 4], tuple_of_different_types=[4, 3, 2, 1])
assert m.dict() == {'simple_tuple': (1, 2, 3, 4), 'tuple_of_different_types': (4, 3.0, '2', True)}
m = Model(empty_tuple=[], simple_tuple=[1, 2, 3, 4], tuple_of_different_types=[4, 3, 2, 1])
assert m.dict() == {
'empty_tuple': (),
'simple_tuple': (1, 2, 3, 4),
'tuple_of_different_types': (4, 3.0, '2', True),
}
def test_tuple_length_error():
class Model(BaseModel):
v: Tuple[int, float, bool]
w: Tuple[()]
with pytest.raises(ValidationError) as exc_info:
Model(v=[1, 2])
Model(v=[1, 2], w=[1])
assert exc_info.value.errors() == [
{
'loc': ('v',),
'msg': 'wrong tuple length 2, expected 3',
'type': 'value_error.tuple.length',
'ctx': {'actual_length': 2, 'expected_length': 3},
}
},
{
'loc': ('w',),
'msg': 'wrong tuple length 1, expected 0',
'type': 'value_error.tuple.length',
'ctx': {'actual_length': 1, 'expected_length': 0},
},
]