From a435116ed0928318d8d6cb91fc740373782f0695 Mon Sep 17 00:00:00 2001 From: henribru <6639509+henribru@users.noreply.github.com> Date: Sat, 7 May 2022 19:00:40 +0200 Subject: [PATCH] Fix stub-only partial namespace packages not recognized as packages (#221) --- src/poetry/core/masonry/utils/package_include.py | 3 +-- .../pkg-stubs/module.pyi | 4 ++++ .../pkg-stubs/subpkg/__init__.pyi | 0 .../pkg-stubs/subpkg/py.typed | 1 + .../pyproject.toml | 14 ++++++++++++++ tests/masonry/builders/test_wheel.py | 14 ++++++++++++++ .../good-stubs/module.pyi | 4 ++++ .../good-stubs/subpkg/__init__.pyi | 0 .../good-stubs/subpkg/py.typed | 1 + tests/masonry/utils/test_package_include.py | 13 +++++++++++++ 10 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/module.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/subpkg/__init__.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/subpkg/py.typed create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pyproject.toml create mode 100644 tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/module.pyi create mode 100644 tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/subpkg/__init__.pyi create mode 100644 tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/subpkg/py.typed diff --git a/src/poetry/core/masonry/utils/package_include.py b/src/poetry/core/masonry/utils/package_include.py index e843d1627..1b52b7de2 100644 --- a/src/poetry/core/masonry/utils/package_include.py +++ b/src/poetry/core/masonry/utils/package_include.py @@ -51,8 +51,7 @@ def is_stub_only(self) -> bool: # returns `True` if this a PEP 561 stub-only package, # see [PEP 561](https://www.python.org/dev/peps/pep-0561/#stub-only-packages) return (self.package or "").endswith("-stubs") and all( - el.suffix == ".pyi" - or (el.parent.name == self.package and el.name == "py.typed") + el.suffix == ".pyi" or el.name == "py.typed" for el in self.elements if el.is_file() ) diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/module.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/module.pyi new file mode 100644 index 000000000..d79e6e39e --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/module.pyi @@ -0,0 +1,4 @@ +"""Example module""" +from typing import Tuple + +version_info = Tuple[int, int, int] diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/subpkg/__init__.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/subpkg/__init__.pyi new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/subpkg/py.typed b/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/subpkg/py.typed new file mode 100644 index 000000000..b648ac923 --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pkg-stubs/subpkg/py.typed @@ -0,0 +1 @@ +partial diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pyproject.toml b/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pyproject.toml new file mode 100644 index 000000000..265effd0f --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_partial_namespace/pyproject.toml @@ -0,0 +1,14 @@ +[tool.poetry] +name = "pep-561-stubs" +version = "0.1" +description = "PEP 561 stub namespace package example with the py.typed marker file" +authors = [ + "Henrik BruÄsdal " +] +license = "MIT" +packages = [ + {include = "pkg-stubs"} +] + +[tool.poetry.dependencies] +python = "^3.6" diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index 8e620cb40..bde27857b 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -215,6 +215,20 @@ def test_wheel_package_pep_561_stub_only(package: str) -> None: assert "pkg-stubs/subpkg/__init__.pyi" in z.namelist() +def test_wheel_package_pep_561_stub_only_partial_namespace() -> None: + root = fixtures_dir / "pep_561_stub_only_partial_namespace" + WheelBuilder.make(Factory().create_poetry(root)) + + whl = root / "dist" / "pep_561_stubs-0.1-py3-none-any.whl" + + assert whl.exists() + + with zipfile.ZipFile(str(whl)) as z: + assert "pkg-stubs/module.pyi" in z.namelist() + assert "pkg-stubs/subpkg/__init__.pyi" in z.namelist() + assert "pkg-stubs/subpkg/py.typed" in z.namelist() + + def test_wheel_package_pep_561_stub_only_includes_typed_marker() -> None: root = fixtures_dir / "pep_561_stub_only_partial" WheelBuilder.make(Factory().create_poetry(root)) diff --git a/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/module.pyi b/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/module.pyi new file mode 100644 index 000000000..d79e6e39e --- /dev/null +++ b/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/module.pyi @@ -0,0 +1,4 @@ +"""Example module""" +from typing import Tuple + +version_info = Tuple[int, int, int] diff --git a/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/subpkg/__init__.pyi b/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/subpkg/__init__.pyi new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/subpkg/py.typed b/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/subpkg/py.typed new file mode 100644 index 000000000..b648ac923 --- /dev/null +++ b/tests/masonry/utils/fixtures/pep_561_stub_only_partial_namespace/good-stubs/subpkg/py.typed @@ -0,0 +1 @@ +partial diff --git a/tests/masonry/utils/test_package_include.py b/tests/masonry/utils/test_package_include.py index f9924443b..913a40576 100644 --- a/tests/masonry/utils/test_package_include.py +++ b/tests/masonry/utils/test_package_include.py @@ -65,6 +65,19 @@ def test_pep_561_stub_only_package_good_name_suffix() -> None: ] +def test_pep_561_stub_only_partial_namespace_package_good_name_suffix() -> None: + pkg_include = PackageInclude( + base=fixtures_dir / "pep_561_stub_only_partial_namespace", include="good-stubs" + ) + assert pkg_include.elements == [ + fixtures_dir / "pep_561_stub_only_partial_namespace/good-stubs/module.pyi", + fixtures_dir / "pep_561_stub_only_partial_namespace/good-stubs/subpkg/", + fixtures_dir + / "pep_561_stub_only_partial_namespace/good-stubs/subpkg/__init__.pyi", + fixtures_dir / "pep_561_stub_only_partial_namespace/good-stubs/subpkg/py.typed", + ] + + def test_pep_561_stub_only_package_bad_name_suffix() -> None: with pytest.raises(ValueError) as e: PackageInclude(base=fixtures_dir / "pep_561_stub_only", include="bad")