Skip to content

Add __path__ to package __init__ #9454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,11 @@ def get_column(self) -> int:


implicit_module_attrs: Final = {
"__name__": "__builtins__.str",
"__doc__": None, # depends on Python version, see semanal.py
"__file__": "__builtins__.str",
"__package__": "__builtins__.str",
'__name__': '__builtins__.str',
'__doc__': None, # depends on Python version, see semanal.py
'__path__': None, # depends on if the module is a package
'__file__': '__builtins__.str',
'__package__': '__builtins__.str'
}


Expand Down
11 changes: 11 additions & 0 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,17 @@ def add_implicit_module_attrs(self, file_node: MypyFile) -> None:
else:
typ = UnionType([UnboundType('__builtins__.str'),
UnboundType('__builtins__.unicode')])
elif name == '__path__':
if not file_node.is_package_init_file():
continue
# Need to construct the type ourselves, to avoid issues with __builtins__.list
# not being subscriptable or typing.List not getting bound
sym = self.lookup_qualified("__builtins__.list", Context())
if not sym:
continue
node = sym.node
assert isinstance(node, TypeInfo)
typ = Instance(node, [self.str_type()])
else:
assert t is not None, 'type should be specified for {}'.format(name)
typ = UnboundType(t)
Expand Down
8 changes: 0 additions & 8 deletions test-data/unit/check-incomplete-fixture.test
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ import m
m.x # E: "object" has no attribute "x"
[file m.py]

[case testListMissingFromStubs]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you delete this test? The behavior it's testing (error messages tailored to bad fixtures) seems useful.

Copy link
Collaborator Author

@hauntsaninja hauntsaninja Sep 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The quickest way to resolve the many test failures was to add list to the builtin stubs (I expect this might be controversial), which of course broke this test.
We have tests for tailored error messages for several other specific fixtures, so I figured this wouldn't be the worst test to remove, especially since I anticipate pushback on adding list to builtin stubs.

from typing import List
def f(x: List[int]) -> None: pass
[out]
main:1: error: Module "typing" has no attribute "List"
main:1: note: Maybe your test fixture does not define "builtins.list"?
main:1: note: Consider adding [builtins fixtures/list.pyi] to your test description

[case testDictMissingFromStubs]
from typing import Dict
def f(x: Dict[int]) -> None: pass
Expand Down
12 changes: 11 additions & 1 deletion test-data/unit/check-modules.test
Original file line number Diff line number Diff line change
Expand Up @@ -2888,6 +2888,16 @@ from mystery import a, b as b, c as d
tmp/stub.pyi:1: error: Cannot find implementation or library stub for module named "mystery"
tmp/stub.pyi:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports

[case testPackagePath]
import p
reveal_type(p.__path__) # N: Revealed type is "builtins.list[builtins.str]"
p.m.__path__ # E: "object" has no attribute "__path__"

[file p/__init__.py]
from . import m as m
[file p/m.py]
[builtins fixtures/list.pyi]

[case testReExportAllInStub]
from m1 import C
from m1 import D # E: Module "m1" has no attribute "D"
Expand Down Expand Up @@ -3121,4 +3131,4 @@ main:2: error: Cannot find implementation or library stub for module named "blea
# flags: --ignore-missing-imports
import bleach.xyz
from bleach.abc import fgh
[file bleach/__init__.pyi]
[file bleach/__init__.pyi]
2 changes: 1 addition & 1 deletion test-data/unit/fine-grained-modules.test
Original file line number Diff line number Diff line change
Expand Up @@ -1437,7 +1437,7 @@ x = 1
[file b/foo.py]
[file b/__init__.py.2]
# Dummy change
[builtins fixtures/bool.pyi]
[builtins fixtures/primitives.pyi]
[out]
==

Expand Down
4 changes: 3 additions & 1 deletion test-data/unit/fixtures/args.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Builtins stub used to support *args, **kwargs.

from typing import TypeVar, Generic, Iterable, Tuple, Dict, Any, overload, Mapping
from typing import TypeVar, Generic, Iterable, Sequence, Tuple, Dict, Any, overload, Mapping

Tco = TypeVar('Tco', covariant=True)
T = TypeVar('T')
Expand All @@ -22,6 +22,8 @@ class tuple(Iterable[Tco], Generic[Tco]): pass

class dict(Iterable[T], Mapping[T, S], Generic[T, S]): pass

class list(Generic[T], Sequence[T]): pass

class int:
def __eq__(self, o: object) -> bool: pass
class str: pass
Expand Down
4 changes: 4 additions & 0 deletions test-data/unit/lib-stub/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ class bytes: pass
class function: pass
class ellipsis: pass

from typing import Generic, Sequence, TypeVar
_T = TypeVar('_T')
class list(Generic[_T], Sequence[_T]): pass

# Definition of None is implicit