Skip to content

Commit 066da4d

Browse files
authored
Add Pep561 tests for stub-only package with namespace packages (#11141)
This only adds tests that show the current behavior when we provide a stub-only package for a subpackage of a namespace package Proposals for behavior changes exist in python/typeshed#5800 Real world example is the `protobuf` package which installs to `google.protobuf` and the `types-protobuf` package which installs to `google-stubs/protobuf` (where `google` is a namespace package)
1 parent df827c9 commit 066da4d

File tree

19 files changed

+88
-17
lines changed

19 files changed

+88
-17
lines changed

Diff for: mypy/test/testmodulefinder.py

+14
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ def test__packages_with_ns(self) -> None:
184184
("ns_pkg_untyped.b.c", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
185185
("ns_pkg_untyped.a.a_var", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
186186

187+
# Namespace package without stub package
188+
("ns_pkg_w_stubs", self.path("ns_pkg_w_stubs")),
189+
("ns_pkg_w_stubs.typed", self.path("ns_pkg_w_stubs-stubs", "typed", "__init__.pyi")),
190+
("ns_pkg_w_stubs.typed_inline",
191+
self.path("ns_pkg_w_stubs", "typed_inline", "__init__.py")),
192+
("ns_pkg_w_stubs.untyped", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
193+
187194
# Regular package with py.typed
188195
("pkg_typed", self.path("pkg_typed", "__init__.py")),
189196
("pkg_typed.a", self.path("pkg_typed", "a.py")),
@@ -239,6 +246,13 @@ def test__packages_without_ns(self) -> None:
239246
("ns_pkg_untyped.b.c", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
240247
("ns_pkg_untyped.a.a_var", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
241248

249+
# Namespace package without stub package
250+
("ns_pkg_w_stubs", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
251+
("ns_pkg_w_stubs.typed", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
252+
("ns_pkg_w_stubs.typed_inline",
253+
self.path("ns_pkg_w_stubs", "typed_inline", "__init__.py")),
254+
("ns_pkg_w_stubs.untyped", ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS),
255+
242256
# Regular package with py.typed
243257
("pkg_typed", self.path("pkg_typed", "__init__.py")),
244258
("pkg_typed.a", self.path("pkg_typed", "a.py")),

Diff for: test-data/packages/modulefinder-site-packages/ns_pkg_w_stubs/typed_inline/__init__.py

Whitespace-only changes.

Diff for: test-data/packages/modulefinder-site-packages/ns_pkg_w_stubs/typed_inline/py.typed

Whitespace-only changes.

Diff for: test-data/packages/modulefinder-site-packages/ns_pkg_w_stubs/untyped/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from setuptools import setup, find_packages
1+
from setuptools import setup
22

33
setup(
44
name='typedpkg_namespace.alpha',
55
version='1.0.0',
6-
packages=find_packages(),
76
namespace_packages=['typedpkg_ns'],
87
zip_safe=False,
9-
package_data={'typedpkg_ns.ns': ['py.typed']}
8+
package_data={'typedpkg_ns.a': ['py.typed']},
9+
packages=['typedpkg_ns.a'],
1010
)

Diff for: test-data/packages/typedpkg_ns_a/typedpkg_ns/a/__init__.py

Whitespace-only changes.

Diff for: test-data/packages/typedpkg_ns_a/typedpkg_ns/a/py.typed

Whitespace-only changes.

Diff for: test-data/packages/typedpkg_ns_b-stubs/setup.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"""
2+
This setup file installs packages to test mypy's PEP 561 implementation
3+
"""
4+
5+
from distutils.core import setup
6+
7+
setup(
8+
name='typedpkg_ns_b-stubs',
9+
author="The mypy team",
10+
version='0.1',
11+
namespace_packages=['typedpkg_ns-stubs'],
12+
package_data={'typedpkg_ns-stubs.b': ['__init__.pyi', 'bbb.pyi']},
13+
packages=['typedpkg_ns-stubs.b'],
14+
)

Diff for: test-data/packages/typedpkg_ns_b-stubs/typedpkg_ns-stubs/b/__init__.pyi

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def bf(a: bool) -> bool: ...

Diff for: test-data/packages/typedpkg_ns_b/setup.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name='typedpkg_namespace.beta',
5+
version='1.0.0',
6+
namespace_packages=['typedpkg_ns'],
7+
zip_safe=False,
8+
package_data={'typedpkg_ns.b': []},
9+
packages=['typedpkg_ns.b'],
10+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# namespace pkg
2+
__import__("pkg_resources").declare_namespace(__name__)

Diff for: test-data/packages/typedpkg_ns_b/typedpkg_ns/b/__init__.py

Whitespace-only changes.
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def bf(a):
2+
return not a

Diff for: test-data/unit/pep561.test

+42-14
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,10 @@ reveal_type(a)
119119
testTypedPkgSimpleEditableEgg.py:5: note: Revealed type is "builtins.tuple[builtins.str]"
120120

121121
[case testTypedPkgNamespaceImportFrom]
122-
# pkgs: typedpkg, typedpkg_ns
122+
# pkgs: typedpkg, typedpkg_ns_a
123123
from typedpkg.pkg.aaa import af
124-
from typedpkg_ns.ns.bbb import bf
125-
from typedpkg_ns.ns.dne import dne
124+
from typedpkg_ns.a.bbb import bf
125+
from typedpkg_ns.a.dne import dne
126126

127127
af("abc")
128128
bf(False)
@@ -132,16 +132,16 @@ af(False)
132132
bf(2)
133133
dne("abc")
134134
[out]
135-
testTypedPkgNamespaceImportFrom.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.ns.dne"
135+
testTypedPkgNamespaceImportFrom.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.a.dne"
136136
testTypedPkgNamespaceImportFrom.py:4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
137137
testTypedPkgNamespaceImportFrom.py:10: error: Argument 1 to "af" has incompatible type "bool"; expected "str"
138138
testTypedPkgNamespaceImportFrom.py:11: error: Argument 1 to "bf" has incompatible type "int"; expected "bool"
139139

140140
[case testTypedPkgNamespaceImportAs]
141-
# pkgs: typedpkg, typedpkg_ns
141+
# pkgs: typedpkg, typedpkg_ns_a
142142
import typedpkg.pkg.aaa as nm; af = nm.af
143-
import typedpkg_ns.ns.bbb as am; bf = am.bf
144-
from typedpkg_ns.ns.dne import dne
143+
import typedpkg_ns.a.bbb as am; bf = am.bf
144+
from typedpkg_ns.a.dne import dne
145145

146146
af("abc")
147147
bf(False)
@@ -151,16 +151,16 @@ af(False)
151151
bf(2)
152152
dne("abc")
153153
[out]
154-
testTypedPkgNamespaceImportAs.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.ns.dne"
154+
testTypedPkgNamespaceImportAs.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.a.dne"
155155
testTypedPkgNamespaceImportAs.py:4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
156156
testTypedPkgNamespaceImportAs.py:10: error: Argument 1 has incompatible type "bool"; expected "str"
157157
testTypedPkgNamespaceImportAs.py:11: error: Argument 1 has incompatible type "int"; expected "bool"
158158

159159
[case testTypedPkgNamespaceRegImport]
160-
# pkgs: typedpkg, typedpkg_ns
160+
# pkgs: typedpkg, typedpkg_ns_a
161161
import typedpkg.pkg.aaa; af = typedpkg.pkg.aaa.af
162-
import typedpkg_ns.ns.bbb; bf = typedpkg_ns.ns.bbb.bf
163-
from typedpkg_ns.ns.dne import dne
162+
import typedpkg_ns.a.bbb; bf = typedpkg_ns.a.bbb.bf
163+
from typedpkg_ns.a.dne import dne
164164

165165
af("abc")
166166
bf(False)
@@ -171,7 +171,7 @@ bf(2)
171171
dne("abc")
172172

173173
[out]
174-
testTypedPkgNamespaceRegImport.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.ns.dne"
174+
testTypedPkgNamespaceRegImport.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.a.dne"
175175
testTypedPkgNamespaceRegImport.py:4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
176176
testTypedPkgNamespaceRegImport.py:10: error: Argument 1 has incompatible type "bool"; expected "str"
177177
testTypedPkgNamespaceRegImport.py:11: error: Argument 1 has incompatible type "int"; expected "bool"
@@ -188,9 +188,37 @@ import a
188188
a.py:1: error: Unsupported operand types for + ("int" and "str")
189189

190190
[case testTypedPkgNamespaceRegFromImportTwice]
191-
# pkgs: typedpkg_ns
192-
from typedpkg_ns import ns
191+
# pkgs: typedpkg_ns_a
192+
from typedpkg_ns import a
193193
-- dummy should trigger a second iteration
194194
[file dummy.py.2]
195195
[out]
196196
[out2]
197+
198+
[case testNamespacePkgWStubs]
199+
# pkgs: typedpkg_ns_a, typedpkg_ns_b, typedpkg_ns_b-stubs
200+
# flags: --no-namespace-packages
201+
import typedpkg_ns.a.bbb as a
202+
import typedpkg_ns.b.bbb as b
203+
a.bf(False)
204+
b.bf(False)
205+
a.bf(1)
206+
b.bf(1)
207+
[out]
208+
testNamespacePkgWStubs.py:4: error: Skipping analyzing "typedpkg_ns.b.bbb": found module but no type hints or library stubs
209+
testNamespacePkgWStubs.py:4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
210+
testNamespacePkgWStubs.py:4: error: Skipping analyzing "typedpkg_ns.b": found module but no type hints or library stubs
211+
testNamespacePkgWStubs.py:7: error: Argument 1 to "bf" has incompatible type "int"; expected "bool"
212+
213+
[case testNamespacePkgWStubsWithNamespacePackagesFlag]
214+
# pkgs: typedpkg_ns_a, typedpkg_ns_b, typedpkg_ns_b-stubs
215+
# flags: --namespace-packages
216+
import typedpkg_ns.a.bbb as a
217+
import typedpkg_ns.b.bbb as b
218+
a.bf(False)
219+
b.bf(False)
220+
a.bf(1)
221+
b.bf(1)
222+
[out]
223+
testNamespacePkgWStubsWithNamespacePackagesFlag.py:7: error: Argument 1 to "bf" has incompatible type "int"; expected "bool"
224+
testNamespacePkgWStubsWithNamespacePackagesFlag.py:8: error: Argument 1 to "bf" has incompatible type "int"; expected "bool"

0 commit comments

Comments
 (0)