1
1
"""Calculation of the least upper bound types (joins)."""
2
2
3
3
from mypy .backports import OrderedDict
4
- from typing import List , Optional
4
+ from typing import List , Optional , Tuple
5
5
6
6
from mypy .types import (
7
7
Type , AnyType , NoneType , TypeVisitor , Instance , UnboundType , TypeVarType , CallableType ,
14
14
is_subtype , is_equivalent , is_subtype_ignoring_tvars , is_proper_subtype ,
15
15
is_protocol_implementation , find_member
16
16
)
17
- from mypy .nodes import ARG_NAMED , ARG_NAMED_OPT
17
+ from mypy .nodes import ARG_NAMED , ARG_NAMED_OPT , INVARIANT , COVARIANT , CONTRAVARIANT
18
18
import mypy .typeops
19
19
from mypy import state
20
+ from mypy import meet
21
+
22
+
23
+ class InstanceJoiner :
24
+ def __init__ (self ) -> None :
25
+ self .seen_instances = [] # type: List[Tuple[Instance, Instance]]
26
+
27
+ def join_instances (self , t : Instance , s : Instance ) -> ProperType :
28
+ if (t , s ) in self .seen_instances or (s , t ) in self .seen_instances :
29
+ return object_from_instance (t )
30
+
31
+ self .seen_instances .append ((t , s ))
32
+
33
+ """Calculate the join of two instance types."""
34
+ if t .type == s .type :
35
+ # Simplest case: join two types with the same base type (but
36
+ # potentially different arguments).
37
+
38
+ # Combine type arguments.
39
+ args = [] # type: List[Type]
40
+ # N.B: We use zip instead of indexing because the lengths might have
41
+ # mismatches during daemon reprocessing.
42
+ for ta , sa , type_var in zip (t .args , s .args , t .type .defn .type_vars ):
43
+ ta_proper = get_proper_type (ta )
44
+ sa_proper = get_proper_type (sa )
45
+ new_type = None # type: Optional[Type]
46
+ if isinstance (ta_proper , AnyType ):
47
+ new_type = AnyType (TypeOfAny .from_another_any , ta_proper )
48
+ elif isinstance (sa_proper , AnyType ):
49
+ new_type = AnyType (TypeOfAny .from_another_any , sa_proper )
50
+ elif type_var .variance == COVARIANT :
51
+ new_type = join_types (ta , sa , self )
52
+ if len (type_var .values ) != 0 and new_type not in type_var .values :
53
+ self .seen_instances .pop ()
54
+ return object_from_instance (t )
55
+ if not is_subtype (new_type , type_var .upper_bound ):
56
+ self .seen_instances .pop ()
57
+ return object_from_instance (t )
58
+ elif type_var .variance == CONTRAVARIANT :
59
+ new_type = meet .meet_types (ta , sa )
60
+ if len (type_var .values ) != 0 and new_type not in type_var .values :
61
+ self .seen_instances .pop ()
62
+ return object_from_instance (t )
63
+ # No need to check subtype, as ta and sa already have to be subtypes of
64
+ # upper_bound
65
+ elif type_var .variance == INVARIANT :
66
+ new_type = join_types (ta , sa )
67
+ if not is_equivalent (ta , sa ):
68
+ self .seen_instances .pop ()
69
+ return object_from_instance (t )
70
+ assert new_type is not None
71
+ args .append (new_type )
72
+ result = Instance (t .type , args ) # type: ProperType
73
+ elif t .type .bases and is_subtype_ignoring_tvars (t , s ):
74
+ result = self .join_instances_via_supertype (t , s )
75
+ else :
76
+ # Now t is not a subtype of s, and t != s. Now s could be a subtype
77
+ # of t; alternatively, we need to find a common supertype. This works
78
+ # in of the both cases.
79
+ result = self .join_instances_via_supertype (s , t )
80
+
81
+ self .seen_instances .pop ()
82
+ return result
83
+
84
+ def join_instances_via_supertype (self , t : Instance , s : Instance ) -> ProperType :
85
+ # Give preference to joins via duck typing relationship, so that
86
+ # join(int, float) == float, for example.
87
+ if t .type ._promote and is_subtype (t .type ._promote , s ):
88
+ return join_types (t .type ._promote , s , self )
89
+ elif s .type ._promote and is_subtype (s .type ._promote , t ):
90
+ return join_types (t , s .type ._promote , self )
91
+ # Compute the "best" supertype of t when joined with s.
92
+ # The definition of "best" may evolve; for now it is the one with
93
+ # the longest MRO. Ties are broken by using the earlier base.
94
+ best = None # type: Optional[ProperType]
95
+ for base in t .type .bases :
96
+ mapped = map_instance_to_supertype (t , base .type )
97
+ res = self .join_instances (mapped , s )
98
+ if best is None or is_better (res , best ):
99
+ best = res
100
+ assert best is not None
101
+ promote = get_proper_type (t .type ._promote )
102
+ if isinstance (promote , Instance ):
103
+ res = self .join_instances (promote , s )
104
+ if is_better (res , best ):
105
+ best = res
106
+ return best
20
107
21
108
22
109
def join_simple (declaration : Optional [Type ], s : Type , t : Type ) -> ProperType :
@@ -69,7 +156,7 @@ def trivial_join(s: Type, t: Type) -> ProperType:
69
156
return object_or_any_from_type (get_proper_type (t ))
70
157
71
158
72
- def join_types (s : Type , t : Type ) -> ProperType :
159
+ def join_types (s : Type , t : Type , instance_joiner : Optional [ InstanceJoiner ] = None ) -> ProperType :
73
160
"""Return the least upper bound of s and t.
74
161
75
162
For example, the join of 'int' and 'object' is 'object'.
@@ -110,7 +197,7 @@ def join_types(s: Type, t: Type) -> ProperType:
110
197
return AnyType (TypeOfAny .from_error )
111
198
112
199
# Use a visitor to handle non-trivial cases.
113
- return t .accept (TypeJoinVisitor (s ))
200
+ return t .accept (TypeJoinVisitor (s , instance_joiner ))
114
201
115
202
116
203
class TypeJoinVisitor (TypeVisitor [ProperType ]):
@@ -120,8 +207,9 @@ class TypeJoinVisitor(TypeVisitor[ProperType]):
120
207
s: The other (left) type operand.
121
208
"""
122
209
123
- def __init__ (self , s : ProperType ) -> None :
210
+ def __init__ (self , s : ProperType , instance_joiner : Optional [ InstanceJoiner ] = None ) -> None :
124
211
self .s = s
212
+ self .instance_joiner = instance_joiner
125
213
126
214
def visit_unbound_type (self , t : UnboundType ) -> ProperType :
127
215
return AnyType (TypeOfAny .special_form )
@@ -163,7 +251,9 @@ def visit_type_var(self, t: TypeVarType) -> ProperType:
163
251
164
252
def visit_instance (self , t : Instance ) -> ProperType :
165
253
if isinstance (self .s , Instance ):
166
- nominal = join_instances (t , self .s )
254
+ if self .instance_joiner is None :
255
+ self .instance_joiner = InstanceJoiner ()
256
+ nominal = self .instance_joiner .join_instances (t , self .s )
167
257
structural = None # type: Optional[Instance]
168
258
if t .type .is_protocol and is_protocol_implementation (self .s , t ):
169
259
structural = t
@@ -282,8 +372,10 @@ def visit_tuple_type(self, t: TupleType) -> ProperType:
282
372
# * Joining with any Sequence also returns a Sequence:
283
373
# Tuple[int, bool] + List[bool] becomes Sequence[int]
284
374
if isinstance (self .s , TupleType ) and self .s .length () == t .length ():
285
- fallback = join_instances (mypy .typeops .tuple_fallback (self .s ),
286
- mypy .typeops .tuple_fallback (t ))
375
+ if self .instance_joiner is None :
376
+ self .instance_joiner = InstanceJoiner ()
377
+ fallback = self .instance_joiner .join_instances (mypy .typeops .tuple_fallback (self .s ),
378
+ mypy .typeops .tuple_fallback (t ))
287
379
assert isinstance (fallback , Instance )
288
380
if self .s .length () == t .length ():
289
381
items = [] # type: List[Type]
@@ -364,56 +456,6 @@ def default(self, typ: Type) -> ProperType:
364
456
return AnyType (TypeOfAny .special_form )
365
457
366
458
367
- def join_instances (t : Instance , s : Instance ) -> ProperType :
368
- """Calculate the join of two instance types."""
369
- if t .type == s .type :
370
- # Simplest case: join two types with the same base type (but
371
- # potentially different arguments).
372
- if is_subtype (t , s ) or is_subtype (s , t ):
373
- # Compatible; combine type arguments.
374
- args = [] # type: List[Type]
375
- # N.B: We use zip instead of indexing because the lengths might have
376
- # mismatches during daemon reprocessing.
377
- for ta , sa in zip (t .args , s .args ):
378
- args .append (join_types (ta , sa ))
379
- return Instance (t .type , args )
380
- else :
381
- # Incompatible; return trivial result object.
382
- return object_from_instance (t )
383
- elif t .type .bases and is_subtype_ignoring_tvars (t , s ):
384
- return join_instances_via_supertype (t , s )
385
- else :
386
- # Now t is not a subtype of s, and t != s. Now s could be a subtype
387
- # of t; alternatively, we need to find a common supertype. This works
388
- # in of the both cases.
389
- return join_instances_via_supertype (s , t )
390
-
391
-
392
- def join_instances_via_supertype (t : Instance , s : Instance ) -> ProperType :
393
- # Give preference to joins via duck typing relationship, so that
394
- # join(int, float) == float, for example.
395
- if t .type ._promote and is_subtype (t .type ._promote , s ):
396
- return join_types (t .type ._promote , s )
397
- elif s .type ._promote and is_subtype (s .type ._promote , t ):
398
- return join_types (t , s .type ._promote )
399
- # Compute the "best" supertype of t when joined with s.
400
- # The definition of "best" may evolve; for now it is the one with
401
- # the longest MRO. Ties are broken by using the earlier base.
402
- best = None # type: Optional[ProperType]
403
- for base in t .type .bases :
404
- mapped = map_instance_to_supertype (t , base .type )
405
- res = join_instances (mapped , s )
406
- if best is None or is_better (res , best ):
407
- best = res
408
- assert best is not None
409
- promote = get_proper_type (t .type ._promote )
410
- if isinstance (promote , Instance ):
411
- res = join_instances (promote , s )
412
- if is_better (res , best ):
413
- best = res
414
- return best
415
-
416
-
417
459
def is_better (t : Type , s : Type ) -> bool :
418
460
# Given two possible results from join_instances_via_supertype(),
419
461
# indicate whether t is the better one.
0 commit comments