diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index a9b1dda6832f..cd304f3a67da 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -429,8 +429,8 @@ of the above sections. ``--no-implicit-reexport`` By default, imported values to a module are treated as exported and mypy allows other modules to import them. This flag changes the behavior to not re-export unless - the item is imported using from-as. Note this is always treated as enabled for - stub files. For example: + the item is imported using from-as or is included in ``__all__``. Note this is + always treated as enabled for stub files. For example: .. code-block:: python @@ -438,6 +438,9 @@ of the above sections. from foo import bar # This will re-export it as bar and allow other modules to import it from foo import bar as bar + # This will also re-export bar + from foo import bar + __all__ = ['bar'] ``--strict-equality`` diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index d01fa4893644..94df11682a84 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -310,8 +310,8 @@ Miscellaneous strictness flags ``implicit_reexport`` (bool, default True) By default, imported values to a module are treated as exported and mypy allows other modules to import them. When false, mypy will not re-export unless - the item is imported using from-as. Note that mypy treats stub files as if this - is always disabled. For example: + the item is imported using from-as or is included in ``__all__``. Note that mypy + treats stub files as if this is always disabled. For example: .. code-block:: python @@ -319,6 +319,9 @@ Miscellaneous strictness flags from foo import bar # This will re-export it as bar and allow other modules to import it from foo import bar as bar + # This will also re-export bar + from foo import bar + __all__ = ['bar'] ``strict_equality`` (bool, default False) Prohibit equality checks, identity checks, and container checks between diff --git a/mypy/semanal.py b/mypy/semanal.py index 2664d40ddb2f..16f5aa79b2d7 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -463,10 +463,16 @@ def add_builtin_aliases(self, tree: MypyFile) -> None: del tree.names[name] def adjust_public_exports(self) -> None: - """Make variables not in __all__ not be public""" + """Adjust the module visibility of globals due to __all__.""" if '__all__' in self.globals: for name, g in self.globals.items(): - if name not in self.all_exports: + # Being included in __all__ explicitly exports and makes public. + if name in self.all_exports: + g.module_public = True + g.module_hidden = False + # But when __all__ is defined, and a symbol is not included in it, + # it cannot be public. + else: g.module_public = False @contextmanager diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index 7e8cf53c8c89..7b7bbb992977 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -1145,6 +1145,19 @@ from other_module_1 import a [out] main:2: error: Module 'other_module_2' has no attribute 'a' +[case testNoImplicitReexportRespectsAll] +# flags: --no-implicit-reexport +from other_module_2 import a +from other_module_2 import b +[file other_module_1.py] +a = 5 +b = 6 +[file other_module_2.py] +from other_module_1 import a, b +__all__ = ('b',) +[out] +main:2: error: Module 'other_module_2' has no attribute 'a' + [case testNoImplicitReexportMypyIni] # flags: --config-file tmp/mypy.ini from other_module_2 import a