Skip to content

Commit 0bc9ab6

Browse files
author
Tom Dyas
committed
add support for __path__ attribute on modules
Fixes python#1422
1 parent e05f6f3 commit 0bc9ab6

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

mypy/nodes.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ def get_column(self) -> int: pass
7575
implicit_module_attrs = {'__name__': '__builtins__.str',
7676
'__doc__': None, # depends on Python version, see semanal.py
7777
'__file__': '__builtins__.str',
78-
'__package__': '__builtins__.str'}
78+
'__package__': '__builtins__.str',
79+
'__path__': '__builtins__.str', } # only present in __init__.py files
7980

8081

8182
type_aliases = {

mypy/semanal.py

+9
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
traverse the entire AST.
4444
"""
4545

46+
import os.path
4647
from collections import OrderedDict
4748
from contextlib import contextmanager
4849

@@ -270,6 +271,9 @@ def visit_file(self, file_node: MypyFile, fnam: str, options: Options) -> None:
270271
MODULE_REF, self.modules['builtins'], self.cur_mod_id)
271272

272273
for name in implicit_module_attrs:
274+
if name == '__path__' and not os.path.basename(fnam) == '__init__.py':
275+
continue
276+
273277
v = self.globals[name].node
274278
if isinstance(v, Var):
275279
v.type = self.anal_type(v.type)
@@ -3546,6 +3550,11 @@ def visit_file(self, file: MypyFile, fnam: str, mod_id: str, options: Options) -
35463550
else:
35473551
typ = UnionType([UnboundType('__builtins__.str'),
35483552
UnboundType('__builtins__.unicode')])
3553+
elif name == '__path__':
3554+
# __path__ is only defined on __init__.py files
3555+
if not os.path.basename(fnam).lower() == '__init__.py':
3556+
continue
3557+
typ = UnboundType(t)
35493558
else:
35503559
assert t is not None, 'type should be specified for {}'.format(name)
35513560
typ = UnboundType(t)

test-data/unit/check-modules.test

+12
Original file line numberDiff line numberDiff line change
@@ -1640,3 +1640,15 @@ m = n # E: Cannot assign multiple modules to name 'm' without explicit 'types.M
16401640
[file n.py]
16411641

16421642
[builtins fixtures/module.pyi]
1643+
1644+
[case testPathAttributePresence]
1645+
import m
1646+
import m.m
1647+
x = m.__path__
1648+
# x.append('xyzzy')
1649+
y = m.m.__path__ # E: Module has no attribute "__path__"
1650+
[file m/__init__.py]
1651+
pass
1652+
[file m/m.py]
1653+
pass
1654+
[builtins fixtures/module_all.pyi]

0 commit comments

Comments
 (0)