Skip to content

Commit 8c69124

Browse files
authored
Preserve (some) implicitly exported types (#13967)
Fixes some of #13965, fixes #12749 We also need to modify attribute access logic (this is the TODO in the PR), which is a little trickier. But cases like #13933 convinced me it's worth making this change, even before I get around to figuring that out.
1 parent 7569d88 commit 8c69124

File tree

3 files changed

+30
-13
lines changed

3 files changed

+30
-13
lines changed

mypy/semanal.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,10 +2303,20 @@ def visit_import_from(self, imp: ImportFrom) -> None:
23032303
)
23042304
continue
23052305

2306-
if node and not node.module_hidden:
2306+
if node:
23072307
self.process_imported_symbol(
23082308
node, module_id, id, imported_id, fullname, module_public, context=imp
23092309
)
2310+
if node.module_hidden:
2311+
self.report_missing_module_attribute(
2312+
module_id,
2313+
id,
2314+
imported_id,
2315+
module_public=module_public,
2316+
module_hidden=not module_public,
2317+
context=imp,
2318+
add_unknown_imported_symbol=False,
2319+
)
23102320
elif module and not missing_submodule:
23112321
# Target module exists but the imported name is missing or hidden.
23122322
self.report_missing_module_attribute(
@@ -2394,6 +2404,7 @@ def report_missing_module_attribute(
23942404
module_public: bool,
23952405
module_hidden: bool,
23962406
context: Node,
2407+
add_unknown_imported_symbol: bool = True,
23972408
) -> None:
23982409
# Missing attribute.
23992410
if self.is_incomplete_namespace(import_id):
@@ -2418,13 +2429,14 @@ def report_missing_module_attribute(
24182429
suggestion = f"; maybe {pretty_seq(matches, 'or')}?"
24192430
message += f"{suggestion}"
24202431
self.fail(message, context, code=codes.ATTR_DEFINED)
2421-
self.add_unknown_imported_symbol(
2422-
imported_id,
2423-
context,
2424-
target_name=None,
2425-
module_public=module_public,
2426-
module_hidden=not module_public,
2427-
)
2432+
if add_unknown_imported_symbol:
2433+
self.add_unknown_imported_symbol(
2434+
imported_id,
2435+
context,
2436+
target_name=None,
2437+
module_public=module_public,
2438+
module_hidden=not module_public,
2439+
)
24282440

24292441
if import_id == "typing":
24302442
# The user probably has a missing definition in a test fixture. Let's verify.

test-data/unit/check-flags.test

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,14 +1606,19 @@ strict_equality = false
16061606

16071607

16081608
[case testNoImplicitReexport]
1609-
# flags: --no-implicit-reexport
1610-
from other_module_2 import a
1609+
# flags: --no-implicit-reexport --show-error-codes
1610+
from other_module_2 import a # E: Module "other_module_2" does not explicitly export attribute "a" [attr-defined]
1611+
reveal_type(a) # N: Revealed type is "builtins.int"
1612+
1613+
import other_module_2
1614+
# TODO: this should also reveal builtins.int, see #13965
1615+
reveal_type(other_module_2.a) # E: "object" does not explicitly export attribute "a" [attr-defined] \
1616+
# N: Revealed type is "Any"
1617+
16111618
[file other_module_1.py]
16121619
a = 5
16131620
[file other_module_2.py]
16141621
from other_module_1 import a
1615-
[out]
1616-
main:2: error: Module "other_module_2" does not explicitly export attribute "a"
16171622

16181623
[case testNoImplicitReexportRespectsAll]
16191624
# flags: --no-implicit-reexport

test-data/unit/check-modules.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1794,7 +1794,7 @@ from stub import C
17941794
c = C()
17951795
reveal_type(c.x) # N: Revealed type is "builtins.int"
17961796
it: Iterable[int]
1797-
reveal_type(it) # N: Revealed type is "Any"
1797+
reveal_type(it) # N: Revealed type is "typing.Iterable[builtins.int]"
17981798

17991799
[file stub.pyi]
18001800
from typing import Iterable

0 commit comments

Comments
 (0)