def test_union_protocols(self): class U1: @untypy.patch def meth(self) -> str: return "s" class U2: @untypy.patch def meth(self) -> int: return 42 @untypy.patch def meth2(self) -> int: return 42 # when wrapping order matters UnionFactory() \ .create_from(Union[U1, U2], DummyDefaultCreationContext()) \ .check_and_wrap(U1(), DummyExecutionContext()) \ .meth() UnionFactory() \ .create_from(Union[U1, U2], DummyDefaultCreationContext()) \ .check_and_wrap(U2(), DummyExecutionContext()) \ .meth() UnionFactory() \ .create_from(Union[U2, U1], DummyDefaultCreationContext()) \ .check_and_wrap(U1(), DummyExecutionContext()) \ .meth() UnionFactory() \ .create_from(Union[U2, U1], DummyDefaultCreationContext()) \ .check_and_wrap(U2(), DummyExecutionContext()) \ .meth()
def setUp(self) -> None: self.checker = CallableFactory().create_from( Callable[[int, int], str], DummyDefaultCreationContext()) self.fn1 = self.checker.check_and_wrap(lambda x, y: str(x // y), DummyExecutionContext()) self.fn2 = self.checker.check_and_wrap(lambda x, y: x // y, DummyExecutionContext())
def test_wrap(self): checker = UnionFactory().create_from(Union[int, str], DummyDefaultCreationContext()) res = checker.check_and_wrap(1, DummyExecutionContext()) self.assertEqual(1, res) res = checker.check_and_wrap("2", DummyExecutionContext()) self.assertEqual("2", res)
def test_wrap(self): checker = OptionalFactory().create_from(Optional[int], DummyDefaultCreationContext()) res = checker.check_and_wrap(1, DummyExecutionContext()) self.assertEqual(1, res) res = checker.check_and_wrap(None, DummyExecutionContext()) self.assertEqual(None, res)
def test_wrap(self): checker = SimpleFactory().create_from(A, DummyDefaultCreationContext()) a = A() child_a = ChildOfA() res = checker.check_and_wrap(a, DummyExecutionContext()) self.assertIs(a, res) res = checker.check_and_wrap(child_a, DummyExecutionContext()) self.assertIsNot(child_a, res) # Wrapped with AWrapper
def setUp(self) -> None: self.checker = ListFactory() \ .create_from(list[int], DummyDefaultCreationContext()) self.normal_list = [0, 1, 2, 3] self.wrapped_list = self.checker \ .check_and_wrap(self.normal_list, DummyExecutionContext()) self.faulty_normal_list = [0, 1, "2", 3] self.faulty_wrapped_list = self.checker \ .check_and_wrap(self.faulty_normal_list, DummyExecutionContext())
def check22(self, f): l1 = [1, 4, 2, 1] l2 = [1, 4, 1] refRes12 = f(l1.copy(), l2.copy()) checker = ListFactory().create_from(list[int], DummyDefaultCreationContext()) wrapped1 = checker.check_and_wrap(l1, DummyExecutionContext()) wrapped2 = checker.check_and_wrap(l2, DummyExecutionContext()) res12 = f(wrapped1, wrapped2) self.assertEqual(l1, wrapped1) self.assertEqual(l2, wrapped2) self.assertEqual(refRes12, res12)
def test_wrap(self): checker = AnyChecker() a = [1, 2, 3] res = checker.check_and_wrap(a, DummyExecutionContext()) self.assertIs(a, res)
def test_untyped_match(self): checker = ProtocolFactory().create_from(UntypedProtocol, DummyDefaultCreationContext()) class U1: @untypy.patch def meth(self, a, b): # matches return 42 self.assertEqual(checker.check_and_wrap(U1(), DummyExecutionContext()).meth("a", "b"), 42)
def test_wrap_inheritance(self): checker = SimpleFactory().create_from(SomeParent, DummyDefaultCreationContext()) res = checker.check_and_wrap(ChildOfSomeParent(), DummyExecutionContext()) with self.assertRaises(UntypyTypeError): res.meth()
def check(self, f): l = [1, 4, 2, 1] refRes = f(l.copy()) checker = ListFactory().create_from(list[int], DummyDefaultCreationContext()) wrapped = checker.check_and_wrap(l, DummyExecutionContext()) res = f(wrapped) self.assertEqual(l, wrapped) self.assertEqual(refRes, res)
def test_untyped_no_match(self): checker = ProtocolFactory().create_from(UntypedProtocol, DummyDefaultCreationContext()) class U0: @untypy.patch def notmeth(self, a, b): return 42 with self.assertRaises(UntypyTypeError) as cm: checker.check_and_wrap(U0(), DummyExecutionContext()) self.assertEqual(cm.exception.expected, "UntypedProtocol")
def test_untyped_nomatch_signature(self): checker = ProtocolFactory().create_from(UntypedProtocol, DummyDefaultCreationContext()) class U2: @untypy.patch def meth(self, a): # does not match pass with self.assertRaises(UntypyTypeError) as cm: checker.check_and_wrap(U2(), DummyExecutionContext()).meth("a", 42) self.assertEqual(cm.exception.expected, "UntypedProtocol")
def test_not_a_list(self): with self.assertRaises(UntypyTypeError) as cm: self.checker.check_and_wrap("Hello", DummyExecutionContext()) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "list[int]") self.assertEqual(i, "^^^^^^^^^") self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_neg_checking(self): with self.assertRaises(UntypyTypeError) as cm: self.checker.check_and_wrap(4, DummyExecutionContext()) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Literal[1, 2, '3']") self.assertEqual(i, "^^^^^^^^^^^^^^^^^^") # This DummyExecutionContext is responsable self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_not_a_generator(self): checker = create_checker(Generator[int, str, bool]) with self.assertRaises(UntypyTypeError) as cm: checker.check_and_wrap(42, DummyExecutionContext()) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Generator[int, str, bool]") self.assertEqual(i, "^^^^^^^^^^^^^^^^^^^^^^^^^") # This DummyExecutionContext is responsable self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_wrap_negative(self): checker = UnionFactory().create_from(Union[int, str], DummyDefaultCreationContext()) with self.assertRaises(UntypyTypeError) as cm: res = checker.check_and_wrap(23.5, DummyExecutionContext()) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Union[int, str]") self.assertEqual(i, "^^^^^^^^^^^^^^^") # This DummyExecutionContext is responsable self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_not_implementing_methods(self): class NoMeth: def foo(self) -> None: pass with self.assertRaises(UntypyTypeError) as cm: self.checker_return.check_and_wrap(NoMeth(), DummyExecutionContext()) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, self.ProtoReturnBName) self.assertEqual(i, "^" * len(self.ProtoReturnBName)) self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_untyped_narrow_signature(self): checker = ProtocolFactory().create_from(UntypedProtocol, DummyDefaultCreationContext()) class U3: @untypy.patch def meth(self, a : int, b : int) -> int: # matches, but to specific return a + b wrapped = checker.check_and_wrap(U3(), DummyExecutionContext()) self.assertEqual(wrapped.meth(10, 20), 30) with self.assertRaises(UntypyTypeError) as cm: wrapped.meth("a", 20) self.assertEqual(cm.exception.previous_chain.expected, "UntypedProtocol")
def test_protocol_type_repr(self): T = TypeVar("T") # There was a bug, causing T to be listet multiple Times. @untypy.patch class Proto(Generic[T]): @untypy.patch def do_it(self, a: T, b: T) -> None: return fac = GenericFactory().create_from(Proto[int], DummyDefaultCreationContext()) with self.assertRaises(UntypyTypeError) as cm: fac.check_and_wrap(42, DummyExecutionContext()) self.assertEqual(cm.exception.expected, "Proto[~T=int]")
def test_yield_error(self): # annotation incorrect V checker = create_checker(Generator[str, str, bool]) wrapped = checker.check_and_wrap(gen_normal(), DummyExecutionContext()) with self.assertRaises(UntypyTypeError) as cm: next(wrapped) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Generator[str, str, bool]") self.assertEqual(i, " ^^^") self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_return_wrong_arguments(self): class Concrete: @untypy.patch def meth(self) -> B: return A() instance = self.checker_return.check_and_wrap(Concrete(), DummyExecutionContext()) with self.assertRaises(UntypyTypeError) as cm: instance.meth() (t, i) = cm.exception.next_type_and_indicator() self.assertEqual(t, f"meth(self: Self) -> B") self.assertEqual(cm.exception.last_responsable().file, __file__) self.assertEqual(cm.exception.last_declared(), location_of(Concrete.meth))
def test_negative_delayed(self): checker = TupleFactory().create_from(tuple[int, DummyDelayedType], DummyDefaultCreationContext()) res = checker.check_and_wrap((1, 2), DummyExecutionContext()) with self.assertRaises(UntypyTypeError) as cm: res[1].use() (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Tuple[int, DummyDelayedType]") self.assertEqual(i, " ^^^^^^^^^^^^^^^^") # This DummyExecutionContext is responsable self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_yield_error_delayed(self): checker = create_checker(Generator[DummyDelayedType, str, bool]) wrapped = checker.check_and_wrap(gen_normal(), DummyExecutionContext()) res = next(wrapped) with self.assertRaises(UntypyTypeError) as cm: res.use() (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Generator[DummyDelayedType, str, bool]") self.assertEqual(i, " ^^^^^^^^^^^^^^^^") self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_concrete_wrong_return_signature(self): class Concrete: @untypy.patch def meth(self) -> A: return A() instance = self.checker_return.check_and_wrap(Concrete(), DummyExecutionContext()) with self.assertRaises(UntypyTypeError) as cm: instance.meth() (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, f"meth(self: Self) -> {self.sig_b}") self.assertEqual(cm.exception.last_responsable(), location_of(Concrete.meth)) self.assertEqual(cm.exception.last_declared(), location_of(self.ProtoReturnB.meth))
def test_receiving_wrong_arguments(self): class Concrete: @untypy.patch def meth(self, b: ParrentB) -> None: pass instance = self.checker_arg.check_and_wrap(Concrete(), DummyExecutionContext()) with self.assertRaises(UntypyTypeError) as cm: instance.meth(A()) (t, i) = cm.exception.next_type_and_indicator() self.assertEqual(t, f"meth(self: Self, b: {self.sig_b}) -> None") self.assertEqual(cm.exception.last_responsable().file, __file__) self.assertEqual(cm.exception.last_declared(), location_of(self.ProtoReceiveB.meth))
def test_send_error_delayed(self): checker = create_checker(Generator[None, DummyDelayedType, None]) wrapped = checker.check_and_wrap(gen_use_sent(), DummyExecutionContext()) wrapped.send(None) with self.assertRaises(UntypyTypeError) as cm: wrapped.send(42) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Generator[None, DummyDelayedType, None]") self.assertEqual(i, " ^^^^^^^^^^^^^^^^") self.assertEqual(cm.exception.last_responsable().file, __file__)
def test_concrete_wrong_argument_signature(self): class Concrete: @untypy.patch def meth(self, b: A) -> NoReturn: pass instance = self.checker_arg.check_and_wrap(Concrete(), DummyExecutionContext()) with self.assertRaises(UntypyTypeError) as cm: instance.meth(B()) (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "meth(self: Self, b: A) -> None") self.assertEqual(i, " ^") self.assertEqual(cm.exception.last_responsable(), location_of(Concrete.meth)) self.assertEqual(cm.exception.last_declared(), location_of(self.ProtoReceiveB.meth))
def test_error_delayed(self): self.checker = CallableFactory().create_from( Callable[[int, int], DummyDelayedType], DummyDefaultCreationContext()) fn = self.checker.check_and_wrap(lambda x, y: x // y, DummyExecutionContext()) res = fn(1, 2) with self.assertRaises(UntypyTypeError) as cm: res.use() (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "Callable[[int, int], DummyDelayedType]") self.assertEqual(i, " ^^^^^^^^^^^^^^^^") self.assertEqual(cm.exception.last_responsable().file, "dummy")
def test_error_delayed(self): checker = ListFactory() \ .create_from(list[DummyDelayedType], DummyDefaultCreationContext()) lst = checker \ .check_and_wrap([1], DummyExecutionContext()) res = lst[0] with self.assertRaises(UntypyTypeError) as cm: res.use() (t, i) = cm.exception.next_type_and_indicator() i = i.rstrip() self.assertEqual(t, "list[DummyDelayedType]") self.assertEqual(i, " ^^^^^^^^^^^^^^^^") self.assertEqual(cm.exception.last_responsable().file, "dummy")