diff --git a/mitmproxy/utils/typecheck.py b/mitmproxy/utils/typecheck.py index c68357b70..ca2c7d5dd 100644 --- a/mitmproxy/utils/typecheck.py +++ b/mitmproxy/utils/typecheck.py @@ -21,7 +21,7 @@ def check_type(attr_name: str, value: typing.Any, typeinfo: type) -> None: type(value) )) - if isinstance(typeinfo, typing.UnionMeta): + if typeinfo.__qualname__ == "Union": for T in typeinfo.__union_params__: try: check_type(attr_name, value, T) @@ -30,18 +30,24 @@ def check_type(attr_name: str, value: typing.Any, typeinfo: type) -> None: else: return raise e - if isinstance(typeinfo, typing.TupleMeta): - check_type(attr_name, value, tuple) + elif typeinfo.__qualname__ == "Tuple": + if not isinstance(value, (tuple, list)): + raise e if len(typeinfo.__tuple_params__) != len(value): raise e for i, (x, T) in enumerate(zip(value, typeinfo.__tuple_params__)): check_type("{}[{}]".format(attr_name, i), x, T) 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"): return - - if not isinstance(value, typeinfo): + elif not isinstance(value, typeinfo): raise e diff --git a/test/mitmproxy/utils/test_typecheck.py b/test/mitmproxy/utils/test_typecheck.py index 85684df94..3ec74b205 100644 --- a/test/mitmproxy/utils/test_typecheck.py +++ b/test/mitmproxy/utils/test_typecheck.py @@ -26,6 +26,8 @@ def test_check_type(): typecheck.check_type("foo", 42, str) with pytest.raises(TypeError): typecheck.check_type("foo", None, str) + with pytest.raises(TypeError): + typecheck.check_type("foo", b"foo", str) def test_check_union(): @@ -44,5 +46,14 @@ def test_check_tuple(): typecheck.check_type("foo", (42, 42), typing.Tuple[int, str]) with pytest.raises(TypeError): 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])