diff --git a/mypy/semanal.py b/mypy/semanal.py index 311d5d44d44c4..c8317f50f7b1d 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1795,6 +1795,12 @@ def visit_import_from(self, imp: ImportFrom) -> None: missing_submodule = False imported_id = as_id or id + # Modules imported in a stub file without using 'from Y import X as X' will + # not get exported. + # When implicit re-exporting is disabled, we have the same behavior as stubs. + use_implicit_reexport = not self.is_stub_file and self.options.implicit_reexport + module_public = use_implicit_reexport or (as_id is not None and id == as_id) + # If the module does not contain a symbol with the name 'id', # try checking if it's a module instead. if not node: @@ -1812,15 +1818,12 @@ def visit_import_from(self, imp: ImportFrom) -> None: fullname = module_id + '.' + id gvar = self.create_getattr_var(module.names['__getattr__'], imported_id, fullname) if gvar: - self.add_symbol(imported_id, gvar, imp) + self.add_symbol( + imported_id, gvar, imp, module_public=module_public, + module_hidden=not module_public + ) continue - # Modules imported in a stub file without using 'from Y import X as X' will - # not get exported. - # When implicit re-exporting is disabled, we have the same behavior as stubs. - use_implicit_reexport = not self.is_stub_file and self.options.implicit_reexport - module_public = use_implicit_reexport or (as_id is not None and id == as_id) - if node and not node.module_hidden: self.process_imported_symbol( node, module_id, id, imported_id, fullname, module_public, context=imp diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index e0825715db151..21ed20f7bf8b4 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -1525,6 +1525,16 @@ __all__ = ('b',) [out] main:2: error: Module "other_module_2" does not explicitly export attribute "a"; implicit reexport disabled +[case testNoImplicitReexportGetAttr] +# flags: --no-implicit-reexport --python-version 3.7 +from other_module_2 import a # E: Module "other_module_2" does not explicitly export attribute "a"; implicit reexport disabled +[file other_module_1.py] +from typing import Any +def __getattr__(name: str) -> Any: ... +[file other_module_2.py] +from other_module_1 import a +[builtins fixtures/tuple.pyi] + [case textNoImplicitReexportSuggestions] # flags: --no-implicit-reexport from other_module_2 import attr_1 diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test index ed999d1f46b63..4a4eb6d3f5993 100644 --- a/test-data/unit/check-newsemanal.test +++ b/test-data/unit/check-newsemanal.test @@ -2390,7 +2390,8 @@ import p import p reveal_type(p.y) [file p.pyi] -from pp import x as y +from pp import x +y = x [file pp.pyi] def __getattr__(attr): ... [out2]