From c44446613fcc8ed800fc0bb2ae19883fe34f7ee6 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Sun, 13 Nov 2022 14:33:30 -0800 Subject: [PATCH] =?UTF-8?q?Do=20not=20consider=20=E2=80=98import=20a.b=20a?= =?UTF-8?q?s=20b=E2=80=99=20an=20explicit=20reexport?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The point of the ‘import a as a’ and ‘from a import b as b’ syntax for explicit reexport is that it indicates an intention to do something different from the ordinary ‘import a’ and ‘from a import b’. That is not the case with ‘import a.b as b’. Even mypy’s own code includes ‘import mypy.types as types’, which was not intended to be a reexport; if it were, it would be written ‘from mypy import types as types’. Pyright agrees that ‘import a.b as b’ should not reexport. Signed-off-by: Anders Kaseorg --- mypy/semanal.py | 2 +- test-data/unit/check-modules.test | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index ce88d033e01c..09f2716d09ea 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2230,7 +2230,7 @@ def visit_import(self, i: Import) -> None: if as_id is not None: base_id = id imported_id = as_id - module_public = use_implicit_reexport or id.split(".")[-1] == as_id + module_public = use_implicit_reexport or id == as_id else: base_id = id.split(".")[0] imported_id = base_id diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index b3267f66653d..d2fbecd7c78d 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -1809,6 +1809,8 @@ m = n # E: Cannot assign multiple modules to name "m" without explicit "types.M from stub import Iterable # E: Module "stub" does not explicitly export attribute "Iterable" from stub import D # E: Module "stub" does not explicitly export attribute "D" from stub import C +from stub import foo +from stub import bar # E: Module "stub" does not explicitly export attribute "bar" c = C() reveal_type(c.x) # N: Revealed type is "builtins.int" @@ -1819,6 +1821,8 @@ reveal_type(it) # N: Revealed type is "typing.Iterable[builtins.int]" from typing import Iterable from substub import C as C from substub import C as D +from package import foo as foo +import package.bar as bar def fun(x: Iterable[str]) -> Iterable[int]: pass @@ -1826,6 +1830,10 @@ def fun(x: Iterable[str]) -> Iterable[int]: pass class C: x: int +[file package/foo.pyi] + +[file package/bar.pyi] + [builtins fixtures/module.pyi] [case testNoReExportFromStubsMemberType]