forked from python/mypy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtestsolve.py
More file actions
131 lines (112 loc) · 5.77 KB
/
testsolve.py
File metadata and controls
131 lines (112 loc) · 5.77 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
"""Test cases for the constraint solver used in type inference."""
from typing import List, Union, Tuple, Optional
from mypy.test.helpers import Suite, assert_equal
from mypy.constraints import SUPERTYPE_OF, SUBTYPE_OF, Constraint
from mypy.solve import solve_constraints
from mypy.test.typefixture import TypeFixture
from mypy.types import Type, TypeVarType, TypeVarId
class SolveSuite(Suite):
def setUp(self) -> None:
self.fx = TypeFixture()
def test_empty_input(self) -> None:
self.assert_solve([], [], [])
def test_simple_supertype_constraints(self) -> None:
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.a)],
[(self.fx.a, self.fx.o)])
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.a),
self.supc(self.fx.t, self.fx.b)],
[(self.fx.a, self.fx.o)])
def test_simple_subtype_constraints(self) -> None:
self.assert_solve([self.fx.t.id],
[self.subc(self.fx.t, self.fx.a)],
[self.fx.a])
self.assert_solve([self.fx.t.id],
[self.subc(self.fx.t, self.fx.a),
self.subc(self.fx.t, self.fx.b)],
[self.fx.b])
def test_both_kinds_of_constraints(self) -> None:
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.b),
self.subc(self.fx.t, self.fx.a)],
[(self.fx.b, self.fx.a)])
def test_unsatisfiable_constraints(self) -> None:
# The constraints are impossible to satisfy.
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.a),
self.subc(self.fx.t, self.fx.b)],
[None])
def test_exactly_specified_result(self) -> None:
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.b),
self.subc(self.fx.t, self.fx.b)],
[(self.fx.b, self.fx.b)])
def test_multiple_variables(self) -> None:
self.assert_solve([self.fx.t.id, self.fx.s.id],
[self.supc(self.fx.t, self.fx.b),
self.supc(self.fx.s, self.fx.c),
self.subc(self.fx.t, self.fx.a)],
[(self.fx.b, self.fx.a), (self.fx.c, self.fx.o)])
def test_no_constraints_for_var(self) -> None:
self.assert_solve([self.fx.t.id],
[],
[self.fx.uninhabited])
self.assert_solve([self.fx.t.id, self.fx.s.id],
[],
[self.fx.uninhabited, self.fx.uninhabited])
self.assert_solve([self.fx.t.id, self.fx.s.id],
[self.supc(self.fx.s, self.fx.a)],
[self.fx.uninhabited, (self.fx.a, self.fx.o)])
def test_simple_constraints_with_dynamic_type(self) -> None:
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.anyt)],
[(self.fx.anyt, self.fx.anyt)])
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.anyt),
self.supc(self.fx.t, self.fx.anyt)],
[(self.fx.anyt, self.fx.anyt)])
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.anyt),
self.supc(self.fx.t, self.fx.a)],
[(self.fx.anyt, self.fx.anyt)])
self.assert_solve([self.fx.t.id],
[self.subc(self.fx.t, self.fx.anyt)],
[(self.fx.anyt, self.fx.anyt)])
self.assert_solve([self.fx.t.id],
[self.subc(self.fx.t, self.fx.anyt),
self.subc(self.fx.t, self.fx.anyt)],
[(self.fx.anyt, self.fx.anyt)])
# self.assert_solve([self.fx.t.id],
# [self.subc(self.fx.t, self.fx.anyt),
# self.subc(self.fx.t, self.fx.a)],
# [(self.fx.anyt, self.fx.anyt)])
# TODO: figure out what this should be after changes to meet(any, X)
def test_both_normal_and_any_types_in_results(self) -> None:
# If one of the bounds is any, we promote the other bound to
# any as well, since otherwise the type range does not make sense.
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.a),
self.subc(self.fx.t, self.fx.anyt)],
[(self.fx.anyt, self.fx.anyt)])
self.assert_solve([self.fx.t.id],
[self.supc(self.fx.t, self.fx.anyt),
self.subc(self.fx.t, self.fx.a)],
[(self.fx.anyt, self.fx.anyt)])
def assert_solve(self,
vars: List[TypeVarId],
constraints: List[Constraint],
results: List[Union[None, Type, Tuple[Type, Type]]],
) -> None:
res = [] # type: List[Optional[Type]]
for r in results:
if isinstance(r, tuple):
res.append(r[0])
else:
res.append(r)
actual = solve_constraints(vars, constraints)
assert_equal(str(actual), str(res))
def supc(self, type_var: TypeVarType, bound: Type) -> Constraint:
return Constraint(type_var.id, SUPERTYPE_OF, bound)
def subc(self, type_var: TypeVarType, bound: Type) -> Constraint:
return Constraint(type_var.id, SUBTYPE_OF, bound)