File tree Expand file tree Collapse file tree 2 files changed +81
-2
lines changed Expand file tree Collapse file tree 2 files changed +81
-2
lines changed Original file line number Diff line number Diff line change @@ -1634,10 +1634,20 @@ def visit_import_from(self, imp: ImportFrom) -> None:
16341634 import_id = self .correct_relative_import (imp )
16351635 module = self .modules .get (import_id )
16361636 for id , as_id in imp .names :
1637- node = module .names .get (id ) if module else None
1637+ possible_module_id = import_id + '.' + id
1638+ if module is None :
1639+ node = None
1640+ elif import_id == self .cur_mod_id and possible_module_id in self .modules :
1641+ # Submodule takes precedence over definition in surround package, for
1642+ # compatibility with runtime semantics in typical use cases. This
1643+ # could more precisely model runtime semantics by taking into account
1644+ # the line number beyond which the local definition should take
1645+ # precedence, but doesn't seem to be important in most use cases.
1646+ node = SymbolTableNode (GDEF , self .modules [possible_module_id ])
1647+ else :
1648+ node = module .names .get (id )
16381649
16391650 missing = False
1640- possible_module_id = import_id + '.' + id
16411651 imported_id = as_id or id
16421652
16431653 # If the module does not contain a symbol with the name 'id',
Original file line number Diff line number Diff line change @@ -2516,3 +2516,72 @@ def get() -> int: ...
25162516import typing
25172517t = typing.typevar('t') # E: Module has no attribute "typevar"
25182518[builtins fixtures/module.pyi]
2519+
2520+ [case testNewAnalyzerImportFromTopLevelFunction]
2521+ import a.b # This works at runtime
2522+ reveal_type(a.b) # N
2523+ [file a/__init__.py]
2524+ from .b import B
2525+ from . import b as c
2526+ def b() -> None: pass
2527+ reveal_type(b) # N
2528+ reveal_type(c.B()) # N
2529+ x: Forward
2530+ class Forward:
2531+ ...
2532+
2533+ [file a/b.py]
2534+ class B: ...
2535+ [builtins fixtures/module.pyi]
2536+
2537+ [out]
2538+ tmp/a/__init__.py:4: note: Revealed type is 'def ()'
2539+ tmp/a/__init__.py:5: note: Revealed type is 'a.b.B'
2540+ main:2: note: Revealed type is 'def ()'
2541+
2542+ [case testNewAnalyzerImportFromTopLevelAlias]
2543+ import a.b # This works at runtime
2544+ reveal_type(a.b) # N
2545+ [file a/__init__.py]
2546+ from .b import B
2547+ from . import b as c
2548+ b = int
2549+ y: b
2550+ reveal_type(y) # N
2551+ reveal_type(c.B) # N
2552+ x: Forward
2553+ class Forward:
2554+ ...
2555+
2556+ [file a/b.py]
2557+ class B: ...
2558+ [builtins fixtures/module.pyi]
2559+
2560+ [out]
2561+ tmp/a/__init__.py:5: note: Revealed type is 'builtins.int'
2562+ tmp/a/__init__.py:6: note: Revealed type is 'def () -> a.b.B'
2563+ main:2: note: Revealed type is 'def () -> builtins.int'
2564+
2565+ [case testNewAnalyzerImportAmbiguousWithTopLevelFunction]
2566+ import a.b # This works at runtime
2567+ x: a.b.B # E
2568+ reveal_type(a.b) # N
2569+ [file a/__init__.py]
2570+ import a.b
2571+ import a.b as c
2572+ def b() -> None: pass
2573+ reveal_type(b) # N
2574+ reveal_type(c.B()) # N
2575+ x: Forward
2576+ class Forward:
2577+ ...
2578+
2579+ [file a/b.py]
2580+ class B: ...
2581+ [builtins fixtures/module.pyi]
2582+
2583+ [out]
2584+ tmp/a/__init__.py:4: note: Revealed type is 'def ()'
2585+ tmp/a/__init__.py:5: note: Revealed type is 'a.b.B'
2586+ main:2: error: Name 'a.b.B' is not defined
2587+ main:3: note: Revealed type is 'def ()'
You can’t perform that action at this time.
0 commit comments