def test_Set_Tc_not_OK(): with expected(tc.InputParameterError("")): assert foo_Set_Tc_Tc_to_bool(set(("yes",b"maybe")), "yes") with expected(tc.InputParameterError("")): assert foo_Set_Tc_Tc_to_bool(set((1, 2)), 2) with expected(tc.InputParameterError("")): assert foo_Set_Tc_Tc_to_bool(set((("yes",),("maybe",))), ("yes",))
def test_NamedTuple_not_OK(): with expected(tc.InputParameterError("name=8, id=9)")): foo_Employee(Employee(name=8, id=9)) with expected(tc.InputParameterError("'aaa')")): foo_Employee(Employee(name='Jones', id='aaa')) with expected(tc.InputParameterError("Employee2(name='Jones', id=999)")): foo_Employee(Employee2(name='Jones', id=999))
def test_Union_not_OK(): with expected(tc.InputParameterError("u: wrong")): foo_Union_int_SequenceFloat("wrong") with expected(tc.InputParameterError("u: [4]")): foo_Union_int_SequenceFloat([4]) with expected(tc.InputParameterError("u: None")): foo_Union_int_SequenceFloat(None)
def test_complex_example_not_OK(): with expected(tc.InputParameterError("1")): assert foo_wow_thats_nested(1) == 1 with expected(IndexError("")): foo_wow_thats_nested([]) with expected(tc.ReturnValueError("")): assert foo_wow_thats_nested(None) == None with expected(tc.ReturnValueError("")): assert foo_wow_thats_nested(dt.date.today()) == dt.date.today() with expected(tc.ReturnValueError("None")): assert foo_wow_thats_nested([dict(a=None, b=2.0)]) == None
def test_Iterator_Container_content_not_OK_catchable(): """ Because there is no suitable way to access their contents, such generic types may still pass the typecheck if their content is of the wrong type. This is a fundamental problem, not an implementation gap. The only cases where improper contents will be caught is when the argument is _also_ tg.Iterable. """ with expected(tc.InputParameterError("list_iterator")): foo_Iterator(["shouldn't be", "strings here"].__iter__()) with expected(tc.InputParameterError("3, 4")): foo_Container([[3, 4], [5, 6]])
def test_re_is_halfhearted(): """ As of 3.5, the implementation of tg appears to be incomplete for TypeAlias. All those asserts should in fact be successful. """ error = TypeError("Type aliases cannot be used with isinstance().") with expected(error): assert isinstance(re.compile("regexp"), tg.re.Pattern[str]) with expected(error): assert isinstance(re.compile(b"byteregexp"), tg.re.Pattern[bytes]) with expected(error): assert isinstance(re.match("regexp", "string"), tg.re.Match[str]) with expected(error): assert isinstance(re.match(b"regexp", b"string"), tg.re.Match[bytes])
def test_forward_reference_to_local_class_OK_or_not_OK(): class B: @tc.typecheck def foo_something(self, another: 'B') -> 'B': return self b1 = B() b2 = B() b1.foo_something(b2) with expected(tc.InputParameterError("something different")): b1.foo_something("something different")
def test_MyGeneric_OK_and_not_OK(): for element1 in diverse_collection: for element2 in diverse_collection: if type(element1) == type(element2): continue mygen = MyGeneric(element1) mygen.append(element1) # binds X mygen.append(element1) # checks X binding: OK print(element1, element2) if (issubclass(type(element1), type(element2)) or issubclass(type(element2), type(element1))): mygen.append(element2) # conforms to X binding else: with expected(tc.InputParameterError("")): mygen.append(element2) # violates X binding
def test_Tuple_not_OK(): with expected(tc.InputParameterError("t: 2")): foo_Tuple_int_float_to_float(2) with expected(tc.InputParameterError("t: (2,)")): foo_Tuple_int_float_to_float((2,)) with expected(tc.InputParameterError("t: (2, None)")): foo_Tuple_int_float_to_float((2, None)) with expected(tc.InputParameterError("t: None")): foo_Tuple_int_float_to_float(None) with expected(tc.InputParameterError("t: (2, 3)")): foo_Tuple_int_float_to_float((2, 3)) with expected(tc.InputParameterError("t: (2, 3.0, 4.0)")): foo_Tuple_int_float_to_float((2, 3.0, 4.0))
def test_Sequence_X_int_notOK(): with expected(tc.InputParameterError( "foo_Sequence_X_to_Sequence_X() has got an incompatible value for x: a_string")): foo_Sequence_X_to_Sequence_X([1, 2], "a_string")
def test_Sequence_int_with_wrong_result(): with expected(tc.ReturnValueError( "has returned an incompatible value: [1, '2']")): foo_Sequence_int_to_List_int([1], "2")
def test_Sequence_int_with_wrong_Sequence(): with expected(tc.InputParameterError( "has got an incompatible value for x: ['mystring']")): foo_Sequence_int_to_List_int(["mystring"], 77)
def test_TypeVar_constraint_not_OK(): with (expected(tc.InputParameterError(""))): foo_with_constraint("str1", b"bytes1") with (expected(tc.InputParameterError(""))): foo_with_constraint(("b","y"), ("t","e"))
def test_Sequence_int_with_no_Sequence(): with expected(tc.InputParameterError( "has got an incompatible value for x: 4")): foo_Sequence_int_to_List_int(4)
def test_forward_reference_not_OK(): a1 = A() with expected(tc.InputParameterError("something different")): a1.foo_something("something different")
def test_Mapping_str_float_not_OK(): with expected(tc.InputParameterError("{'a': True}")): # wrong value type assert foo_Mapping_str_float_to_float(dict(a=True), "a") == True with expected(tc.InputParameterError("{b'a': 4.0}")): # wrong key type assert foo_Mapping_str_float_to_float({b'a':4.0}, b"a") == 4.0
def test_KeysView_to_Sequence_not_OK(): with expected(tc.InputParameterError("v: dict_keys\(.*3.*")): assert foo_KeysView_to_Sequence({b'A':11, b'B':12, 3:13}.keys()) == [b'A', b'B', 13]
def test_SupportsAbs_not_OK(): with expected(tc.InputParameterError("")): foo_SupportsAbs("-4")
def test_Optional_not_OK(): with expected(tc.InputParameterError("u: wrong")): foo_Optional_Union_int_SequenceFloat("wrong") with expected(tc.InputParameterError("u: [4]")): foo_Optional_Union_int_SequenceFloat([4])
def test_TypeVar_bound_violated(): with (expected(tc.InputParameterError(""))): foo_with_bound(1, 2) # both same type, but not below the bound with (expected(tc.InputParameterError(""))): foo_with_bound(object(), object()) # above the bound
def test_Iterator_totally_not_OK(): with expected(tc.InputParameterError("")): foo_Iterator((dt.date.today(), dt.date.today())) # lacks .__next__()