-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathtest_simple.py
More file actions
160 lines (120 loc) · 4.33 KB
/
test_simple.py
File metadata and controls
160 lines (120 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import unittest
from typing import Union, Callable
import untypy
from test.util import DummyExecutionContext, DummyDefaultCreationContext
from untypy.error import UntypyTypeError, UntypyAttributeError
from untypy.impl.simple import SimpleFactory
from untypy.impl.union import UnionFactory
@untypy.patch
class A:
pass
@untypy.patch
class ChildOfA(A):
pass
@untypy.patch
class B:
pass
@untypy.patch
class SomeParent:
@untypy.patch
def meth(self) -> str:
return "Hello"
@untypy.patch
class ChildOfSomeParent(SomeParent):
@untypy.patch
def meth(self) -> int: # Signature does not match.
return 42
class TestSimple(unittest.TestCase):
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 test_attributes(self):
a = ChildOfA()
a.foo = 42
# Note: Attributes are not checked, but they need to be accessible
@untypy.patch
def m(x: A) -> None:
self.assertEqual(x.foo, 42)
x.foo = 43
self.assertEqual(x.foo, 43)
m(a)
self.assertEqual(a.foo, 43)
def test_wrap_negative(self):
checker = SimpleFactory().create_from(A, DummyDefaultCreationContext())
with self.assertRaises(UntypyTypeError) as cm:
res = checker.check_and_wrap(B(), DummyExecutionContext())
(t, i) = cm.exception.next_type_and_indicator()
i = i.rstrip()
self.assertEqual(t, "A")
self.assertEqual(i, "^")
# This DummyExecutionContext is responsable
self.assertEqual(cm.exception.last_responsable().file, "dummy")
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 test_unions_simple_types_negative(self):
class U1:
def meth(self) -> None:
pass
class U2:
def meth(self) -> None:
pass
with self.assertRaises(UntypyAttributeError):
# Should fail because both have the same methods
# Wrapping cannot distinguish
UnionFactory().create_from(Union[U1, U2], DummyDefaultCreationContext())
def test_unions_simple_types_negative(self):
class U3:
def meth(self) -> None:
pass
class U4:
def meth(self) -> None:
pass
def somethingelse(self) -> None:
pass
# this should also be fine. A and B don't have any signatures,
# so protocol like wrapping does not apply
UnionFactory().create_from(Union[A, B], DummyDefaultCreationContext())
# this must be fine: Names of Signatures differ.
UnionFactory().create_from(Union[U3, U4], DummyDefaultCreationContext())
def test_no_inheritance_checking_of_builtins(self):
class SubInt(int):
pass
@untypy.patch
def take_number(number: int) -> None:
# SubInt should not be wrapped.
self.assertEqual(type(number), SubInt)
take_number(SubInt("42"))
def test_int_as_float(self):
@untypy.patch
def f(x: float) -> float:
return x + 1
self.assertEqual(f(1), 2)
self.assertEqual(f(1.1), 2.1)
with self.assertRaises(UntypyTypeError):
f("x")
def test_float_not_as_int(self):
@untypy.patch
def f(x: int) -> int:
return x + 1
self.assertEqual(f(1), 2)
with self.assertRaises(UntypyTypeError):
f("x")
with self.assertRaises(UntypyTypeError):
f(3.14)
def test_callable(self):
@untypy.patch
def f(g: Callable) -> int:
return g(1)
self.assertEqual(f(lambda x: x + 1), 2)
with self.assertRaises(TypeError):
f(lambda x: "x" + x)
with self.assertRaises(UntypyTypeError):
f(lambda x: "x" + str(x))