Repository: python/mypy

Issue:
New semantic analyzer: __all__
It's not clear whether `__all__` works with the new semantic analyzer.


Discussion:

Resolving patch:
diff --git a/mypy/newsemanal/semanal.py b/mypy/newsemanal/semanal.py
--- a/mypy/newsemanal/semanal.py
+++ b/mypy/newsemanal/semanal.py
@@ -413,6 +413,14 @@ def refresh_top_level(self, file_node: MypyFile) -> None:
             self.accept(d)
         if file_node.fullname() == 'typing':
             self.add_builtin_aliases(file_node)
+        self.adjust_public_exports()
+
+    def adjust_public_exports(self) -> None:
+        """Make variables not in __all__ not be public"""
+        if '__all__' in self.globals:
+            for name, g in self.globals.items():
+                if name not in self.all_exports:
+                    g.module_public = False
 
     @contextmanager
     def file_context(self, file_node: MypyFile, fnam: str, options: Options,


Test patch:
diff --git a/mypy/test/hacks.py b/mypy/test/hacks.py
--- a/mypy/test/hacks.py
+++ b/mypy/test/hacks.py
@@ -13,7 +13,6 @@
     'check-functions.test',
     'check-incremental.test',
     'check-literal.test',
-    'check-modules.test',
     'check-overloading.test',
     'check-python2.test',
     'check-statements.test',
diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test
--- a/test-data/unit/check-modules.test
+++ b/test-data/unit/check-modules.test
@@ -323,11 +323,10 @@ main:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missin
 main:2: error: Name 'y' is not defined
 
 [case testUnknownModuleRedefinition]
-import xab
-def xab(): pass
-[out]
-main:1: error: Cannot find module named 'xab'
-main:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
+# Error messages differ with the new analyzer
+# flags: --new-semantic-analyzer
+import xab  # E: Cannot find module named 'xab'  # N: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
+def xab(): pass  # E: Name 'xab' already defined (possibly by an import)
 
 [case testAccessingUnknownModuleFromOtherModule]
 import x
@@ -520,9 +519,13 @@ x = 1
 x = 1
 
 [case testAssignToFuncDefViaImport]
-from m import *  # E: Incompatible import of "x" (imported name has type "int", local name has type "str")
-f = None
-x = ''
+# Errors differ with the new analyzer. (Old analyzer gave error on the
+# input, which is maybe better, but no error about f, which seems
+# wrong)
+# flags: --new-semantic-analyzer
+from m import *
+f = None  # E: Incompatible types in assignment (expression has type "None", variable has type "Callable[[], Any]")
+x = ''  # E: Incompatible types in assignment (expression has type "str", variable has type "int")
 [file m.py]
 def f(): pass
 x = 1+0
@@ -2027,19 +2030,16 @@ def __getattr__(name: str) -> Any: ...
 [builtins fixtures/module.pyi]
 
 [case testModuleLevelGetattrImportFromAs]
+# FIXME: #6314
+# flags: --no-new-semantic-analyzer
 from has_attr import name as n
-reveal_type(name)
-reveal_type(n)
+reveal_type(name)  # E: Revealed type is 'Any'  # E: Name 'name' is not defined
+reveal_type(n)  # E: Revealed type is 'Any'
 
 [file has_attr.pyi]
 from typing import Any
 def __getattr__(name: str) -> Any: ...
 
-[out]
-main:2: error: Revealed type is 'Any'
-main:2: error: Name 'name' is not defined
-main:3: error: Revealed type is 'Any'
-
 [builtins fixtures/module.pyi]
 
 [case testModuleLevelGetattrAssignedGood]
@@ -2221,6 +2221,8 @@ def __getattr__(attr: str) -> Any: ...
 [out]
 
 [case testModuleGetattrInit2]
+# FIXME: #6314
+# flags: --no-new-semantic-analyzer
 import a.b
 
 x = a.b.f()
@@ -2243,6 +2245,8 @@ main:1: error: Cannot find module named 'a.b'
 main:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
 
 [case testModuleGetattrInit4]
+# FIXME: #6314
+# flags: --no-new-semantic-analyzer
 import a.b.c
 
 x = a.b.c.f()
@@ -2253,6 +2257,8 @@ def __getattr__(attr: str) -> Any: ...
 [out]
 
 [case testModuleGetattrInit5]
+# FIXME: #6314
+# flags: --no-new-semantic-analyzer
 from a.b import f
 
 x = f()
@@ -2263,6 +2269,8 @@ def __getattr__(attr: str) -> Any: ...
 [out]
 
 [case testModuleGetattrInit5a]
+# FIXME: #6314
+# flags: --no-new-semantic-analyzer
 from a.b import f
 
 x = f()
@@ -2300,7 +2308,9 @@ main:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missin
 main:1: error: Cannot find module named 'a.b.c'
 
 [case testModuleGetattrInit8a]
-import a.b.c  # Error
+# FIXME: #6314
+# flags: --no-new-semantic-analyzer
+import a.b.c  # E: Cannot find module named 'a.b.c'  # N: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
 import a.d  # OK
 [file a/__init__.pyi]
 from typing import Any
@@ -2308,9 +2318,6 @@ def __getattr__(attr: str) -> Any: ...
 [file a/b/__init__.pyi]
 # empty (i.e. complete subpackage)
 [builtins fixtures/module.pyi]
-[out]
-main:1: error: Cannot find module named 'a.b.c'
-main:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
 
 [case testModuleGetattrInit10]
 # flags: --config-file tmp/mypy.ini
diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test
--- a/test-data/unit/check-newsemanal.test
+++ b/test-data/unit/check-newsemanal.test
@@ -79,6 +79,29 @@ from b import bad
 [file b.py]
 from a import bad # E: Module 'a' has no attribute 'bad'
 
+[case testNewAnalyzerExportedValuesInImportAll]
+from m import *
+_ = a
+_ = b
+_ = c
+_ = d
+_e = e
+_f = f # E: Name 'f' is not defined
+_ = _g # E: Name '_g' is not defined
+reveal_type(_e)  # E: Revealed type is 'm.A'
+[file m.py]
+__all__ = ['a']
+__all__ += ('b',)
+__all__.append('c')
+__all__.extend(('d', 'e'))
+
+a = b = c = d = _g = 1
+e: 'A'
+f: 'A'
+
+class A: ...
+[builtins fixtures/module_all.pyi]
+
 [case testNewAnalyzerSimpleFunction]
 def f(x: int) -> str:
     return 'x'