Skip to content

Commit 2d67784

Browse files
daborossilevkivskyi
authored andcommitted
Support exported names starting with an underscore in __all__ (#3746)
Fixes #3745
1 parent c4b4949 commit 2d67784

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

mypy/semanal.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,9 @@ def visit_import_all(self, i: ImportAll) -> None:
14831483
self.add_submodules_to_parent_modules(i_id, True)
14841484
for name, node in m.names.items():
14851485
node = self.normalize_type_alias(node, i)
1486-
if not name.startswith('_') and node.module_public:
1486+
# if '__all__' exists, all nodes not included have had module_public set to
1487+
# False, and we can skip checking '_' because it's been explicitly included.
1488+
if node.module_public and (not name.startswith('_') or '__all__' in m.names):
14871489
existing_symbol = self.globals.get(name)
14881490
if existing_symbol:
14891491
# Import can redefine a variable. They get special treatment.

test-data/unit/check-modules.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,25 @@ __all__ = [u'a', u'b', u'c']
427427

428428
[out]
429429

430+
[case testUnderscoreExportedValuesInImportAll]
431+
import typing
432+
from m import *
433+
_ = a
434+
_ = _b
435+
_ = __c__
436+
_ = ___d
437+
_ = e
438+
_ = f # E: Name 'f' is not defined
439+
_ = _g # E: Name '_g' is not defined
440+
[file m.py]
441+
__all__ = ['a']
442+
__all__ += ('_b',)
443+
__all__.append('__c__')
444+
__all__.extend(('___d', 'e'))
445+
446+
a = _b = __c__ = ___d = e = f = _g = 1
447+
[builtins fixtures/module_all.pyi]
448+
430449
[case testEllipsisInitializerInStubFileWithType]
431450
import m
432451
m.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")

0 commit comments

Comments
 (0)