2
2
from contextlib import contextmanager
3
3
4
4
from mypy .types import Type , AnyType , PartialType , UnionType , TypeOfAny
5
- from mypy .nodes import (Key , Expression , Var , RefExpr )
6
-
7
5
from mypy .subtypes import is_subtype
8
6
from mypy .join import join_simple
9
7
from mypy .sametypes import is_same_type
10
-
8
+ from mypy .nodes import Expression , Var , RefExpr
9
+ from mypy .literals import Key , literal , literal_hash , subkeys
11
10
from mypy .nodes import IndexExpr , MemberExpr , NameExpr
12
11
13
12
@@ -61,7 +60,7 @@ class A:
61
60
62
61
def __init__ (self ) -> None :
63
62
# The stack of frames currently used. These map
64
- # expr. literal_hash -- literals like 'foo.bar' --
63
+ # literal_hash(expr) -- literals like 'foo.bar' --
65
64
# to types. The last element of this list is the
66
65
# top-most, current frame. Each earlier element
67
66
# records the state as of when that frame was last
@@ -75,7 +74,7 @@ def __init__(self) -> None:
75
74
# has no corresponding element in this list.
76
75
self .options_on_return = [] # type: List[List[Frame]]
77
76
78
- # Maps expr. literal_hash to get_declaration(expr)
77
+ # Maps literal_hash(expr) to get_declaration(expr)
79
78
# for every expr stored in the binder
80
79
self .declarations = DeclarationsFrame ()
81
80
# Set of other keys to invalidate if a key is changed, e.g. x -> {x.a, x[0]}
@@ -94,9 +93,8 @@ def _add_dependencies(self, key: Key, value: Optional[Key] = None) -> None:
94
93
value = key
95
94
else :
96
95
self .dependencies .setdefault (key , set ()).add (value )
97
- for elt in key :
98
- if isinstance (elt , Key ):
99
- self ._add_dependencies (elt , value )
96
+ for elt in subkeys (key ):
97
+ self ._add_dependencies (elt , value )
100
98
101
99
def push_frame (self ) -> Frame :
102
100
"""Push a new frame into the binder."""
@@ -119,12 +117,11 @@ def _get(self, key: Key, index: int=-1) -> Optional[Type]:
119
117
def put (self , expr : Expression , typ : Type ) -> None :
120
118
if not isinstance (expr , BindableTypes ):
121
119
return
122
- if not expr . literal :
120
+ if not literal ( expr ) :
123
121
return
124
- key = expr . literal_hash
122
+ key = literal_hash ( expr )
125
123
assert key is not None , 'Internal error: binder tried to put non-literal'
126
124
if key not in self .declarations :
127
- assert isinstance (expr , BindableTypes )
128
125
self .declarations [key ] = get_declaration (expr )
129
126
self ._add_dependencies (key )
130
127
self ._put (key , typ )
@@ -133,8 +130,9 @@ def unreachable(self) -> None:
133
130
self .frames [- 1 ].unreachable = True
134
131
135
132
def get (self , expr : Expression ) -> Optional [Type ]:
136
- assert expr .literal_hash is not None , 'Internal error: binder tried to get non-literal'
137
- return self ._get (expr .literal_hash )
133
+ key = literal_hash (expr )
134
+ assert key is not None , 'Internal error: binder tried to get non-literal'
135
+ return self ._get (key )
138
136
139
137
def is_unreachable (self ) -> bool :
140
138
# TODO: Copy the value of unreachable into new frames to avoid
@@ -143,8 +141,9 @@ def is_unreachable(self) -> bool:
143
141
144
142
def cleanse (self , expr : Expression ) -> None :
145
143
"""Remove all references to a Node from the binder."""
146
- assert expr .literal_hash is not None , 'Internal error: binder tried cleanse non-literal'
147
- self ._cleanse_key (expr .literal_hash )
144
+ key = literal_hash (expr )
145
+ assert key is not None , 'Internal error: binder tried cleanse non-literal'
146
+ self ._cleanse_key (key )
148
147
149
148
def _cleanse_key (self , key : Key ) -> None :
150
149
"""Remove all references to a key from the binder."""
@@ -217,7 +216,7 @@ def assign_type(self, expr: Expression,
217
216
restrict_any : bool = False ) -> None :
218
217
if not isinstance (expr , BindableTypes ):
219
218
return None
220
- if not expr . literal :
219
+ if not literal ( expr ) :
221
220
return
222
221
self .invalidate_dependencies (expr )
223
222
@@ -266,14 +265,15 @@ def invalidate_dependencies(self, expr: BindableExpression) -> None:
266
265
It is overly conservative: it invalidates globally, including
267
266
in code paths unreachable from here.
268
267
"""
269
- assert expr .literal_hash is not None
270
- for dep in self .dependencies .get (expr .literal_hash , set ()):
268
+ key = literal_hash (expr )
269
+ assert key is not None
270
+ for dep in self .dependencies .get (key , set ()):
271
271
self ._cleanse_key (dep )
272
272
273
273
def most_recent_enclosing_type (self , expr : BindableExpression , type : Type ) -> Optional [Type ]:
274
274
if isinstance (type , AnyType ):
275
275
return get_declaration (expr )
276
- key = expr . literal_hash
276
+ key = literal_hash ( expr )
277
277
assert key is not None
278
278
enclosers = ([get_declaration (expr )] +
279
279
[f [key ] for f in self .frames
0 commit comments