mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
* Strict validation of `list`, `set` and `tuple` (#86) * review fixes
This commit is contained in:
committed by
Samuel Colvin
parent
7e44bcaf7a
commit
4f19d2b94a
@@ -3,6 +3,10 @@
|
||||
History
|
||||
-------
|
||||
|
||||
v0.10.1 (2018-xx-xx)
|
||||
....................
|
||||
* make ``list``, ``tuple`` and ``set`` types stricter #86
|
||||
|
||||
v0.10.0 (2018-06-11)
|
||||
....................
|
||||
* add ``Config.allow_population_by_alias`` #160, thanks @bendemaree
|
||||
|
||||
+10
-6
@@ -1,3 +1,4 @@
|
||||
import inspect
|
||||
from collections import OrderedDict
|
||||
from datetime import date, datetime, time, timedelta
|
||||
from decimal import Decimal, DecimalException
|
||||
@@ -133,25 +134,28 @@ def dict_validator(v) -> dict:
|
||||
def list_validator(v) -> list:
|
||||
if isinstance(v, list):
|
||||
return v
|
||||
|
||||
with change_exception(errors.ListError, TypeError):
|
||||
elif isinstance(v, (tuple, set)) or inspect.isgenerator(v):
|
||||
return list(v)
|
||||
else:
|
||||
raise errors.ListError()
|
||||
|
||||
|
||||
def tuple_validator(v) -> tuple:
|
||||
if isinstance(v, tuple):
|
||||
return v
|
||||
|
||||
with change_exception(errors.TupleError, TypeError):
|
||||
elif isinstance(v, (list, set)) or inspect.isgenerator(v):
|
||||
return tuple(v)
|
||||
else:
|
||||
raise errors.TupleError()
|
||||
|
||||
|
||||
def set_validator(v) -> set:
|
||||
if isinstance(v, set):
|
||||
return v
|
||||
|
||||
with change_exception(errors.SetError, TypeError):
|
||||
elif isinstance(v, (list, tuple)) or inspect.isgenerator(v):
|
||||
return set(v)
|
||||
else:
|
||||
raise errors.SetError()
|
||||
|
||||
|
||||
def enum_validator(v, field, config, **kwargs) -> Enum:
|
||||
|
||||
+54
-15
@@ -428,16 +428,29 @@ def test_dict():
|
||||
]
|
||||
|
||||
|
||||
def test_list():
|
||||
@pytest.mark.parametrize('value,result', (
|
||||
([1, 2, '3'], [1, 2, '3']),
|
||||
((1, 2, '3'), [1, 2, '3']),
|
||||
({1, 2, '3'}, [1, 2, '3']),
|
||||
((i**2 for i in range(5)), [0, 1, 4, 9, 16]),
|
||||
))
|
||||
def test_list_success(value, result):
|
||||
class Model(BaseModel):
|
||||
v: list
|
||||
|
||||
assert Model(v=[1, 2, '3']).v == [1, 2, '3']
|
||||
assert Model(v='xyz').v == ['x', 'y', 'z']
|
||||
assert Model(v=(i**2 for i in range(5))).v == [0, 1, 4, 9, 16]
|
||||
assert Model(v=value).v == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value', (
|
||||
123,
|
||||
'123',
|
||||
))
|
||||
def test_list_fails(value):
|
||||
class Model(BaseModel):
|
||||
v: list
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Model(v=1)
|
||||
Model(v=value)
|
||||
assert exc_info.value.errors() == [
|
||||
{
|
||||
'loc': ('v',),
|
||||
@@ -466,16 +479,29 @@ def test_ordered_dict():
|
||||
]
|
||||
|
||||
|
||||
def test_tuple():
|
||||
@pytest.mark.parametrize('value,result', (
|
||||
([1, 2, '3'], (1, 2, '3')),
|
||||
((1, 2, '3'), (1, 2, '3')),
|
||||
({1, 2, '3'}, (1, 2, '3')),
|
||||
((i**2 for i in range(5)), (0, 1, 4, 9, 16)),
|
||||
))
|
||||
def test_tuple_success(value, result):
|
||||
class Model(BaseModel):
|
||||
v: tuple
|
||||
|
||||
assert Model(v=(1, 2, '3')).v == (1, 2, '3')
|
||||
assert Model(v='xyz').v == ('x', 'y', 'z')
|
||||
assert Model(v=(i**2 for i in range(5))).v == (0, 1, 4, 9, 16)
|
||||
assert Model(v=value).v == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value', (
|
||||
123,
|
||||
'123',
|
||||
))
|
||||
def test_tuple_fails(value):
|
||||
class Model(BaseModel):
|
||||
v: tuple
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Model(v=1)
|
||||
Model(v=value)
|
||||
assert exc_info.value.errors() == [
|
||||
{
|
||||
'loc': ('v',),
|
||||
@@ -485,16 +511,29 @@ def test_tuple():
|
||||
]
|
||||
|
||||
|
||||
def test_set():
|
||||
@pytest.mark.parametrize('value,result', (
|
||||
({1, 2, 2, '3'}, {1, 2, '3'}),
|
||||
((1, 2, 2, '3'), {1, 2, '3'}),
|
||||
([1, 2, 2, '3'], {1, 2, '3'}),
|
||||
({i**2 for i in range(5)}, {0, 1, 4, 9, 16}),
|
||||
))
|
||||
def test_set_success(value, result):
|
||||
class Model(BaseModel):
|
||||
v: set
|
||||
|
||||
assert Model(v={1, 2, 2, '3'}).v == {1, 2, '3'}
|
||||
assert Model(v='xyzxyz').v == {'x', 'y', 'z'}
|
||||
assert Model(v={i**2 for i in range(5)}).v == {0, 1, 4, 9, 16}
|
||||
assert Model(v=value).v == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value', (
|
||||
123,
|
||||
'123',
|
||||
))
|
||||
def test_set_fails(value):
|
||||
class Model(BaseModel):
|
||||
v: set
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Model(v=1)
|
||||
Model(v=value)
|
||||
assert exc_info.value.errors() == [
|
||||
{
|
||||
'loc': ('v',),
|
||||
|
||||
Reference in New Issue
Block a user