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:
1634
1634
import_id = self .correct_relative_import (imp )
1635
1635
module = self .modules .get (import_id )
1636
1636
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 )
1638
1649
1639
1650
missing = False
1640
- possible_module_id = import_id + '.' + id
1641
1651
imported_id = as_id or id
1642
1652
1643
1653
# 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: ...
2516
2516
import typing
2517
2517
t = typing.typevar('t') # E: Module has no attribute "typevar"
2518
2518
[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