Extend type checker validate Sequence specs

This commit is contained in:
Aldo Cortesi 2016-12-11 17:04:19 +13:00
parent c5717b17df
commit ca33bea296
2 changed files with 24 additions and 7 deletions

View File

@ -21,7 +21,7 @@ def check_type(attr_name: str, value: typing.Any, typeinfo: type) -> None:
type(value) type(value)
)) ))
if isinstance(typeinfo, typing.UnionMeta): if typeinfo.__qualname__ == "Union":
for T in typeinfo.__union_params__: for T in typeinfo.__union_params__:
try: try:
check_type(attr_name, value, T) check_type(attr_name, value, T)
@ -30,18 +30,24 @@ def check_type(attr_name: str, value: typing.Any, typeinfo: type) -> None:
else: else:
return return
raise e raise e
if isinstance(typeinfo, typing.TupleMeta): elif typeinfo.__qualname__ == "Tuple":
check_type(attr_name, value, tuple) if not isinstance(value, (tuple, list)):
raise e
if len(typeinfo.__tuple_params__) != len(value): if len(typeinfo.__tuple_params__) != len(value):
raise e raise e
for i, (x, T) in enumerate(zip(value, typeinfo.__tuple_params__)): for i, (x, T) in enumerate(zip(value, typeinfo.__tuple_params__)):
check_type("{}[{}]".format(attr_name, i), x, T) check_type("{}[{}]".format(attr_name, i), x, T)
return return
if issubclass(typeinfo, typing.IO): elif typeinfo.__qualname__ == "Sequence":
T = typeinfo.__args__[0]
if not isinstance(value, (tuple, list)):
raise e
for v in value:
check_type(attr_name, v, T)
elif typeinfo.__qualname__ == "IO":
if hasattr(value, "read"): if hasattr(value, "read"):
return return
elif not isinstance(value, typeinfo):
if not isinstance(value, typeinfo):
raise e raise e

View File

@ -26,6 +26,8 @@ def test_check_type():
typecheck.check_type("foo", 42, str) typecheck.check_type("foo", 42, str)
with pytest.raises(TypeError): with pytest.raises(TypeError):
typecheck.check_type("foo", None, str) typecheck.check_type("foo", None, str)
with pytest.raises(TypeError):
typecheck.check_type("foo", b"foo", str)
def test_check_union(): def test_check_union():
@ -44,5 +46,14 @@ def test_check_tuple():
typecheck.check_type("foo", (42, 42), typing.Tuple[int, str]) typecheck.check_type("foo", (42, 42), typing.Tuple[int, str])
with pytest.raises(TypeError): with pytest.raises(TypeError):
typecheck.check_type("foo", ("42", 42), typing.Tuple[int, str]) typecheck.check_type("foo", ("42", 42), typing.Tuple[int, str])
typecheck.check_type("foo", (42, "42"), typing.Tuple[int, str]) typecheck.check_type("foo", (42, "42"), typing.Tuple[int, str])
def test_check_sequence():
typecheck.check_type("foo", [10], typing.Sequence[int])
with pytest.raises(TypeError):
typecheck.check_type("foo", ["foo"], typing.Sequence[int])
with pytest.raises(TypeError):
typecheck.check_type("foo", [10, "foo"], typing.Sequence[int])
with pytest.raises(TypeError):
typecheck.check_type("foo", [b"foo"], typing.Sequence[str])