@@ -16,9 +16,9 @@ def f(x: int) -> int:
16
16
from typing import (
17
17
TypeVar , Callable , Dict , List , Tuple , Optional , Union , Sequence , Set , Any , cast
18
18
)
19
- from typing_extensions import overload , ClassVar , NoReturn
19
+ from typing_extensions import overload , NoReturn
20
+ from collections import OrderedDict
20
21
from abc import abstractmethod
21
- import sys
22
22
import importlib .util
23
23
import itertools
24
24
@@ -192,7 +192,7 @@ def build_ir(modules: List[MypyFile],
192
192
builder = IRBuilder (types , graph , errors , mapper , module_names , pbv , options )
193
193
builder .visit_mypy_file (module )
194
194
module_ir = ModuleIR (
195
- builder .imports ,
195
+ list ( builder .imports ) ,
196
196
builder .functions ,
197
197
builder .classes ,
198
198
builder .final_names
@@ -1050,7 +1050,9 @@ def __init__(self,
1050
1050
1051
1051
self .errors = errors
1052
1052
self .mapper = mapper
1053
- self .imports = [] # type: List[str]
1053
+ # We use an OrderedDict for this so we can maintain insertion order
1054
+ # and do quick lookups
1055
+ self .imports = OrderedDict () # type: OrderedDict[str, None]
1054
1056
1055
1057
def visit_mypy_file (self , mypyfile : MypyFile ) -> None :
1056
1058
if mypyfile .fullname () in ('typing' , 'abc' ):
@@ -1518,29 +1520,8 @@ def allocate_class(self, cdef: ClassDef) -> None:
1518
1520
[self .load_globals_dict (), self .load_static_unicode (cdef .name ),
1519
1521
tp ], cdef .line )
1520
1522
1521
- # An unfortunate hack: for some stdlib modules, pull in modules
1522
- # that the stubs reexport things from. This works around #393
1523
- # in these cases.
1524
- import_maps = {
1525
- 'os' : tuple (['os.path' ] + ([] if sys .platform == 'win32' else ['posix' ])),
1526
- 'os.path' : ('os' ,),
1527
- 'tokenize' : ('token' ,),
1528
- 'weakref' : ('_weakref' ,),
1529
- 'asyncio' : ('asyncio.events' , 'asyncio.tasks' ,),
1530
- 'click' : ('click.core' , 'click.termui' , 'click.decorators' ,
1531
- 'click.exceptions' , 'click.types' ),
1532
- 'ast' : ('_ast' ,),
1533
- } # type: ClassVar[Dict[str, Sequence[str]]]
1534
-
1535
1523
def gen_import (self , id : str , line : int ) -> None :
1536
- if id in IRBuilder .import_maps :
1537
- for dep in IRBuilder .import_maps [id ]:
1538
- self ._gen_import (dep , line )
1539
-
1540
- self ._gen_import (id , line )
1541
-
1542
- def _gen_import (self , id : str , line : int ) -> None :
1543
- self .imports .append (id )
1524
+ self .imports [id ] = None
1544
1525
1545
1526
needs_import , out = BasicBlock (), BasicBlock ()
1546
1527
first_load = self .add (LoadStatic (object_rprimitive , 'module' , id ))
@@ -2817,7 +2798,7 @@ def visit_name_expr(self, expr: NameExpr) -> Value:
2817
2798
if value is not None :
2818
2799
return value
2819
2800
2820
- if isinstance (expr .node , MypyFile ):
2801
+ if isinstance (expr .node , MypyFile ) and expr . node . fullname () in self . imports :
2821
2802
return self .load_module (expr .node .fullname ())
2822
2803
2823
2804
# If the expression is locally defined, then read the result from the corresponding
@@ -2853,11 +2834,11 @@ def visit_member_expr(self, expr: MemberExpr) -> Value:
2853
2834
if value is not None :
2854
2835
return value
2855
2836
2856
- if self . is_module_member_expr (expr ) :
2857
- return self .load_module_attr (expr )
2858
- else :
2859
- obj = self .accept (expr .expr )
2860
- return self .get_attr (obj , expr .name , self .node_type (expr ), expr .line )
2837
+ if isinstance (expr . node , MypyFile ) and expr . node . fullname () in self . imports :
2838
+ return self .load_module (expr . node . fullname () )
2839
+
2840
+ obj = self .accept (expr .expr )
2841
+ return self .get_attr (obj , expr .name , self .node_type (expr ), expr .line )
2861
2842
2862
2843
def get_attr (self , obj : Value , attr : str , result_type : RType , line : int ) -> Value :
2863
2844
if (isinstance (obj .type , RInstance ) and obj .type .class_ir .is_ext_class
@@ -5210,7 +5191,8 @@ def load_global(self, expr: NameExpr) -> Value:
5210
5191
"""
5211
5192
# If the global is from 'builtins', turn it into a module attr load instead
5212
5193
if self .is_builtin_ref_expr (expr ):
5213
- return self .load_module_attr (expr )
5194
+ assert expr .node , "RefExpr not resolved"
5195
+ return self .load_module_attr_by_fullname (expr .node .fullname (), expr .line )
5214
5196
if (self .is_native_module_ref_expr (expr ) and isinstance (expr .node , TypeInfo )
5215
5197
and not self .is_synthetic_type (expr .node )):
5216
5198
assert expr .fullname is not None
@@ -5257,10 +5239,6 @@ def load_static_unicode(self, value: str) -> Value:
5257
5239
def load_module (self , name : str ) -> Value :
5258
5240
return self .add (LoadStatic (object_rprimitive , 'module' , name ))
5259
5241
5260
- def load_module_attr (self , expr : RefExpr ) -> Value :
5261
- assert expr .node , "RefExpr not resolved"
5262
- return self .load_module_attr_by_fullname (expr .node .fullname (), expr .line )
5263
-
5264
5242
def load_module_attr_by_fullname (self , fullname : str , line : int ) -> Value :
5265
5243
module , _ , name = fullname .rpartition ('.' )
5266
5244
left = self .load_module (module )
0 commit comments