From 2449f565b7b6986c2fda579e02d8ea73e7ee4cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sat, 5 Oct 2024 10:37:25 +0200 Subject: [PATCH 1/3] make default formats of `include` consistent ("sdist" and "wheel") and refactor code for better maintainability --- src/poetry/core/factory.py | 16 ++--- src/poetry/core/masonry/builders/builder.py | 68 +++++++------------ src/poetry/core/masonry/utils/include.py | 6 +- src/poetry/core/masonry/utils/module.py | 46 ++++++------- .../core/masonry/utils/package_include.py | 2 +- .../both.txt | 0 .../with-include-formats/both/file.txt | 1 + .../with-include-formats/both/sub/file.txt | 1 + .../default.txt} | 0 .../with-include-formats/default/file.txt | 1 + .../with-include-formats/default/sub/file.txt | 1 + .../with-include-formats/pyproject.toml | 64 +++++++++++++++++ .../sdist_only.txt} | 0 .../with-include-formats/sdist_only/file.txt | 1 + .../sdist_only/sub/file.txt | 1 + .../src/mod_both.py} | 0 .../src/mod_default.py} | 0 .../src/mod_sdist_only.py | 0 .../src/mod_wheel_only.py | 0 .../src/pkg_both/__init__.py | 0 .../src/pkg_both/sub/__init__.py | 0 .../src/pkg_default/__init__.py | 0 .../src/pkg_default/sub/__init__.py | 0 .../src/pkg_sdist_only/__init__.py | 0 .../src/pkg_sdist_only/sub/__init__.py | 0 .../src/pkg_wheel_only/__init__.py | 0 .../src/pkg_wheel_only/sub/__init__.py | 0 .../with-include-formats/wheel_only.txt | 0 .../with-include-formats/wheel_only/file.txt | 1 + .../wheel_only/sub/file.txt | 1 + .../with_include_inline_table/pyproject.toml | 48 ------------- tests/masonry/builders/test_sdist.py | 46 +++++++++---- tests/masonry/builders/test_wheel.py | 31 +++++++-- tests/masonry/utils/test_package_include.py | 22 +++--- tests/test_factory.py | 4 +- 35 files changed, 204 insertions(+), 157 deletions(-) rename tests/masonry/builders/fixtures/{with_include_inline_table => with-include-formats}/both.txt (100%) create mode 100644 tests/masonry/builders/fixtures/with-include-formats/both/file.txt create mode 100644 tests/masonry/builders/fixtures/with-include-formats/both/sub/file.txt rename tests/masonry/builders/fixtures/{with_include_inline_table/src/src_package/__init__.py => with-include-formats/default.txt} (100%) create mode 100644 tests/masonry/builders/fixtures/with-include-formats/default/file.txt create mode 100644 tests/masonry/builders/fixtures/with-include-formats/default/sub/file.txt create mode 100644 tests/masonry/builders/fixtures/with-include-formats/pyproject.toml rename tests/masonry/builders/fixtures/{with_include_inline_table/tests/__init__.py => with-include-formats/sdist_only.txt} (100%) create mode 100644 tests/masonry/builders/fixtures/with-include-formats/sdist_only/file.txt create mode 100644 tests/masonry/builders/fixtures/with-include-formats/sdist_only/sub/file.txt rename tests/masonry/builders/fixtures/{with_include_inline_table/tests/test_foo/test.py => with-include-formats/src/mod_both.py} (100%) rename tests/masonry/builders/fixtures/{with_include_inline_table/wheel_only.txt => with-include-formats/src/mod_default.py} (100%) create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/mod_sdist_only.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/mod_wheel_only.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_both/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_both/sub/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_default/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_default/sub/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_sdist_only/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_sdist_only/sub/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_wheel_only/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/src/pkg_wheel_only/sub/__init__.py create mode 100644 tests/masonry/builders/fixtures/with-include-formats/wheel_only.txt create mode 100644 tests/masonry/builders/fixtures/with-include-formats/wheel_only/file.txt create mode 100644 tests/masonry/builders/fixtures/with-include-formats/wheel_only/sub/file.txt delete mode 100644 tests/masonry/builders/fixtures/with_include_inline_table/pyproject.toml diff --git a/src/poetry/core/factory.py b/src/poetry/core/factory.py index 070976a32..c58059a0c 100644 --- a/src/poetry/core/factory.py +++ b/src/poetry/core/factory.py @@ -368,18 +368,10 @@ def _configure_package_poetry_specifics( package.build_config = build or {} if includes := tool_poetry.get("include"): - package.include = [] - - for include in includes: - if not isinstance(include, dict): - include = {"path": include} - - formats = include.get("format", []) - if formats and not isinstance(formats, list): - formats = [formats] - include["format"] = formats - - package.include.append(include) + package.include = [ + include if isinstance(include, dict) else {"path": include} + for include in includes + ] if exclude := tool_poetry.get("exclude"): package.exclude = exclude diff --git a/src/poetry/core/masonry/builders/builder.py b/src/poetry/core/masonry/builders/builder.py index de1038522..8fcc9ad3a 100644 --- a/src/poetry/core/masonry/builders/builder.py +++ b/src/poetry/core/masonry/builders/builder.py @@ -7,6 +7,7 @@ from functools import cached_property from pathlib import Path from typing import TYPE_CHECKING +from typing import Any if TYPE_CHECKING: @@ -52,41 +53,27 @@ def __init__( def _module(self) -> Module: from poetry.core.masonry.utils.module import Module - packages = [] - for p in self._package.packages: - formats = p.get("format") or None + packages: list[dict[str, Any]] = [] + includes: list[dict[str, Any]] = [] + for source_list, target_list in [ + (self._package.packages, packages), + (self._package.include, includes), + ]: + for item in source_list: + # Default to including in both sdist & wheel + # if the `format` key is not provided. + formats = item.get("format", ["sdist", "wheel"]) + if not isinstance(formats, list): + formats = [formats] - # Default to including the package in both sdist & wheel - # if the `format` key is not provided in the inline include table. - if formats is None: - formats = ["sdist", "wheel"] - - if not isinstance(formats, list): - formats = [formats] - - if ( - formats - and self.format - and self.format not in formats - and not self._ignore_packages_formats - ): - continue - - packages.append(p) - - includes = [] - for include in self._package.include: - formats = include.get("format", []) - - if ( - formats - and self.format - and self.format not in formats - and not self._ignore_packages_formats - ): - continue + if ( + self.format + and self.format not in formats + and not self._ignore_packages_formats + ): + continue - includes.append(include) + target_list.append({**item, "format": formats}) return Module( self._package.name, @@ -122,15 +109,12 @@ def find_excluded_files(self, fmt: str | None = None) -> set[str]: ) explicitly_included = set() - for inc in self._package.include: - if fmt and inc["format"] and fmt not in inc["format"]: + for inc in self._module.explicit_includes: + if fmt and fmt not in inc.formats: continue - included_glob = inc["path"] - for included in self._path.glob(str(included_glob)): - explicitly_included.add( - Path(included).relative_to(self._path).as_posix() - ) + for included in inc.elements: + explicitly_included.add(included.relative_to(self._path).as_posix()) ignored = (vcs_ignored_files | explicitly_excluded) - explicitly_included for ignored_file in ignored: @@ -164,7 +148,7 @@ def find_files_to_add(self, exclude_build: bool = True) -> set[BuildIncludeFile] for include in self._module.includes: include.refresh() - formats = include.formats or ["sdist"] + formats = include.formats for file in include.elements: if "__pycache__" in str(file): @@ -201,7 +185,7 @@ def find_files_to_add(self, exclude_build: bool = True) -> set[BuildIncludeFile] if not ( current_file.is_dir() or self.is_excluded( - include_file.relative_to_source_root() + include_file.relative_to_project_root() ) ): to_add.add(include_file) diff --git a/src/poetry/core/masonry/utils/include.py b/src/poetry/core/masonry/utils/include.py index f183aa6c8..e75c74fbb 100644 --- a/src/poetry/core/masonry/utils/include.py +++ b/src/poetry/core/masonry/utils/include.py @@ -21,9 +21,7 @@ class Include: - a directory """ - def __init__( - self, base: Path, include: str, formats: list[str] | None = None - ) -> None: + def __init__(self, base: Path, include: str, formats: list[str]) -> None: self._base = base self._include = str(include) self._formats = formats @@ -39,7 +37,7 @@ def elements(self) -> list[Path]: return self._elements @property - def formats(self) -> list[str] | None: + def formats(self) -> list[str]: return self._formats def is_empty(self) -> bool: diff --git a/src/poetry/core/masonry/utils/module.py b/src/poetry/core/masonry/utils/module.py index 6053790e6..d338463d5 100644 --- a/src/poetry/core/masonry/utils/module.py +++ b/src/poetry/core/masonry/utils/module.py @@ -31,18 +31,20 @@ def __init__( self._in_src = False self._is_package = False self._path = Path(directory) - self._includes: list[Include] = [] + self._package_includes: list[PackageInclude] = [] + self._explicit_includes: list[Include] = [] if not packages: # It must exist either as a .py file or a directory, but not both pkg_dir = Path(directory, self._name) py_file = Path(directory, self._name + ".py") + default_package: dict[str, Any] if pkg_dir.is_dir() and py_file.is_file(): raise ValueError(f"Both {pkg_dir} and {py_file} exist") elif pkg_dir.is_dir(): - packages = [{"include": str(pkg_dir.relative_to(self._path))}] + default_package = {"include": str(pkg_dir.relative_to(self._path))} elif py_file.is_file(): - packages = [{"include": str(py_file.relative_to(self._path))}] + default_package = {"include": str(py_file.relative_to(self._path))} else: # Searching for a src module src = Path(directory, "src") @@ -52,41 +54,35 @@ def __init__( if src_pkg_dir.is_dir() and src_py_file.is_file(): raise ValueError(f"Both {pkg_dir} and {py_file} exist") elif src_pkg_dir.is_dir(): - packages = [ - { - "include": str(src_pkg_dir.relative_to(src)), - "from": str(src.relative_to(self._path)), - } - ] + default_package = { + "include": str(src_pkg_dir.relative_to(src)), + "from": str(src.relative_to(self._path)), + } elif src_py_file.is_file(): - packages = [ - { - "include": str(src_py_file.relative_to(src)), - "from": str(src.relative_to(self._path)), - } - ] + default_package = { + "include": str(src_py_file.relative_to(src)), + "from": str(src.relative_to(self._path)), + } else: raise ModuleOrPackageNotFoundError( f"No file/folder found for package {name}" ) + default_package["format"] = ["sdist", "wheel"] + packages = [default_package] for package in packages: - formats = package.get("format") - if formats and not isinstance(formats, list): - formats = [formats] - - self._includes.append( + self._package_includes.append( PackageInclude( self._path, package["include"], - formats=formats, + formats=package["format"], source=package.get("from"), target=package.get("to"), ) ) for include in includes: - self._includes.append( + self._explicit_includes.append( Include(self._path, include["path"], formats=include["format"]) ) @@ -107,7 +103,11 @@ def file(self) -> Path: @property def includes(self) -> list[Include]: - return self._includes + return [*self._package_includes, *self._explicit_includes] + + @property + def explicit_includes(self) -> list[Include]: + return self._explicit_includes def is_package(self) -> bool: return self._is_package diff --git a/src/poetry/core/masonry/utils/package_include.py b/src/poetry/core/masonry/utils/package_include.py index 5fa659aee..b68779ff8 100644 --- a/src/poetry/core/masonry/utils/package_include.py +++ b/src/poetry/core/masonry/utils/package_include.py @@ -14,7 +14,7 @@ def __init__( self, base: Path, include: str, - formats: list[str] | None = None, + formats: list[str], source: str | None = None, target: str | None = None, ) -> None: diff --git a/tests/masonry/builders/fixtures/with_include_inline_table/both.txt b/tests/masonry/builders/fixtures/with-include-formats/both.txt similarity index 100% rename from tests/masonry/builders/fixtures/with_include_inline_table/both.txt rename to tests/masonry/builders/fixtures/with-include-formats/both.txt diff --git a/tests/masonry/builders/fixtures/with-include-formats/both/file.txt b/tests/masonry/builders/fixtures/with-include-formats/both/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/both/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with-include-formats/both/sub/file.txt b/tests/masonry/builders/fixtures/with-include-formats/both/sub/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/both/sub/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with_include_inline_table/src/src_package/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/default.txt similarity index 100% rename from tests/masonry/builders/fixtures/with_include_inline_table/src/src_package/__init__.py rename to tests/masonry/builders/fixtures/with-include-formats/default.txt diff --git a/tests/masonry/builders/fixtures/with-include-formats/default/file.txt b/tests/masonry/builders/fixtures/with-include-formats/default/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/default/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with-include-formats/default/sub/file.txt b/tests/masonry/builders/fixtures/with-include-formats/default/sub/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/default/sub/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with-include-formats/pyproject.toml b/tests/masonry/builders/fixtures/with-include-formats/pyproject.toml new file mode 100644 index 000000000..9c7556304 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/pyproject.toml @@ -0,0 +1,64 @@ +[tool.poetry] +name = "with-include" +version = "1.2.3" +description = "Some description." +authors = [ + "Sébastien Eustace " +] +license = "MIT" + +homepage = "https://python-poetry.org/" +repository = "https://github.com/python-poetry/poetry" +documentation = "https://python-poetry.org/docs" + +keywords = ["packaging", "dependency", "poetry"] + +classifiers = [ + "Topic :: Software Development :: Build Tools", + "Topic :: Software Development :: Libraries :: Python Modules" +] + +packages = [ + # modules + { include = "mod_default.py", from = "src" }, + { include = "mod_sdist_only.py", from = "src", format = "sdist" }, + { include = "mod_wheel_only.py", from = "src", format = "wheel" }, + { include = "mod_both.py", from = "src", format = [ "sdist", "wheel" ]}, + # packages + { include = "pkg_default", from = "src" }, + { include = "pkg_sdist_only", from = "src", format = "sdist" }, + { include = "pkg_wheel_only", from = "src", format = "wheel" }, + { include = "pkg_both", from = "src", format = [ "sdist", "wheel" ]}, +] + +include = [ + # files + { path = "default.txt" }, + { path = "sdist_only.txt", format = "sdist" }, + { path = "wheel_only.txt", format = "wheel" }, + { path = "both.txt", format = [ "sdist", "wheel" ] }, + # directories + { path = "default" }, + { path = "sdist_only", format = "sdist" }, + { path = "wheel_only", format = "wheel" }, + { path = "both", format = [ "sdist", "wheel" ] }, +] + + +# Requirements +[tool.poetry.dependencies] +python = "^3.6" +cleo = "^0.6" +cachy = { version = "^0.2.0", extras = ["msgpack"] } + +pendulum = { version = "^1.4", optional = true } + +[tool.poetry.group.dev.dependencies] +pytest = "~3.4" + +[tool.poetry.extras] +time = ["pendulum"] + +[tool.poetry.scripts] +my-script = "my_package:main" +my-2nd-script = "my_package:main2" diff --git a/tests/masonry/builders/fixtures/with_include_inline_table/tests/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/sdist_only.txt similarity index 100% rename from tests/masonry/builders/fixtures/with_include_inline_table/tests/__init__.py rename to tests/masonry/builders/fixtures/with-include-formats/sdist_only.txt diff --git a/tests/masonry/builders/fixtures/with-include-formats/sdist_only/file.txt b/tests/masonry/builders/fixtures/with-include-formats/sdist_only/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/sdist_only/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with-include-formats/sdist_only/sub/file.txt b/tests/masonry/builders/fixtures/with-include-formats/sdist_only/sub/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/sdist_only/sub/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with_include_inline_table/tests/test_foo/test.py b/tests/masonry/builders/fixtures/with-include-formats/src/mod_both.py similarity index 100% rename from tests/masonry/builders/fixtures/with_include_inline_table/tests/test_foo/test.py rename to tests/masonry/builders/fixtures/with-include-formats/src/mod_both.py diff --git a/tests/masonry/builders/fixtures/with_include_inline_table/wheel_only.txt b/tests/masonry/builders/fixtures/with-include-formats/src/mod_default.py similarity index 100% rename from tests/masonry/builders/fixtures/with_include_inline_table/wheel_only.txt rename to tests/masonry/builders/fixtures/with-include-formats/src/mod_default.py diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/mod_sdist_only.py b/tests/masonry/builders/fixtures/with-include-formats/src/mod_sdist_only.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/mod_wheel_only.py b/tests/masonry/builders/fixtures/with-include-formats/src/mod_wheel_only.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_both/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_both/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_both/sub/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_both/sub/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_default/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_default/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_default/sub/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_default/sub/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_sdist_only/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_sdist_only/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_sdist_only/sub/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_sdist_only/sub/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_wheel_only/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_wheel_only/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/src/pkg_wheel_only/sub/__init__.py b/tests/masonry/builders/fixtures/with-include-formats/src/pkg_wheel_only/sub/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/wheel_only.txt b/tests/masonry/builders/fixtures/with-include-formats/wheel_only.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/with-include-formats/wheel_only/file.txt b/tests/masonry/builders/fixtures/with-include-formats/wheel_only/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/wheel_only/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with-include-formats/wheel_only/sub/file.txt b/tests/masonry/builders/fixtures/with-include-formats/wheel_only/sub/file.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/masonry/builders/fixtures/with-include-formats/wheel_only/sub/file.txt @@ -0,0 +1 @@ + diff --git a/tests/masonry/builders/fixtures/with_include_inline_table/pyproject.toml b/tests/masonry/builders/fixtures/with_include_inline_table/pyproject.toml deleted file mode 100644 index 991b0e8cf..000000000 --- a/tests/masonry/builders/fixtures/with_include_inline_table/pyproject.toml +++ /dev/null @@ -1,48 +0,0 @@ -[tool.poetry] -name = "with-include" -version = "1.2.3" -description = "Some description." -authors = [ - "Sébastien Eustace " -] -license = "MIT" - -homepage = "https://python-poetry.org/" -repository = "https://github.com/python-poetry/poetry" -documentation = "https://python-poetry.org/docs" - -keywords = ["packaging", "dependency", "poetry"] - -classifiers = [ - "Topic :: Software Development :: Build Tools", - "Topic :: Software Development :: Libraries :: Python Modules" -] - -packages = [ - { include = "src_package", from = "src"}, -] - -include = [ - { path = "tests", format = "sdist" }, - { path = "both.txt" }, - { path = "wheel_only.txt", format = "wheel" } -] - - -# Requirements -[tool.poetry.dependencies] -python = "^3.6" -cleo = "^0.6" -cachy = { version = "^0.2.0", extras = ["msgpack"] } - -pendulum = { version = "^1.4", optional = true } - -[tool.poetry.group.dev.dependencies] -pytest = "~3.4" - -[tool.poetry.extras] -time = ["pendulum"] - -[tool.poetry.scripts] -my-script = "my_package:main" -my-2nd-script = "my_package:main2" diff --git a/tests/masonry/builders/test_sdist.py b/tests/masonry/builders/test_sdist.py index df2df2434..5fe34267c 100644 --- a/tests/masonry/builders/test_sdist.py +++ b/tests/masonry/builders/test_sdist.py @@ -244,7 +244,7 @@ def test_find_packages(project_name: str) -> None: builder = SdistBuilder(poetry) base = project(project_name) - include = PackageInclude(base, "my_package") + include = PackageInclude(base, "my_package", formats=["sdist"]) pkg_dir, packages, pkg_data = builder.find_packages(include) @@ -266,7 +266,7 @@ def test_find_packages(project_name: str) -> None: builder = SdistBuilder(poetry) base = project("source_package") - include = PackageInclude(base, "package_src", source="src") + include = PackageInclude(base, "package_src", source="src", formats=["sdist"]) pkg_dir, packages, pkg_data = builder.find_packages(include) @@ -579,27 +579,47 @@ def test_includes() -> None: assert "with_include-1.2.3/notes.txt" in tar.getnames() -def test_includes_with_inline_table() -> None: - poetry = Factory().create_poetry(project("with_include_inline_table")) +def test_include_formats() -> None: + poetry = Factory().create_poetry(project("with-include-formats")) builder = SdistBuilder(poetry) builder.build() - sdist = ( - fixtures_dir - / "with_include_inline_table" - / "dist" - / "with_include-1.2.3.tar.gz" - ) + sdist = fixtures_dir / "with-include-formats" / "dist" / "with_include-1.2.3.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: - assert "with_include-1.2.3/both.txt" in tar.getnames() + # packages + assert "with_include-1.2.3/src/mod_default.py" in tar.getnames() + assert "with_include-1.2.3/src/mod_sdist_only.py" in tar.getnames() + assert "with_include-1.2.3/src/mod_wheel_only.py" not in tar.getnames() + assert "with_include-1.2.3/src/mod_both.py" in tar.getnames() + assert "with_include-1.2.3/src/pkg_default/__init__.py" in tar.getnames() + assert "with_include-1.2.3/src/pkg_default/sub/__init__.py" in tar.getnames() + assert "with_include-1.2.3/src/pkg_sdist_only/__init__.py" in tar.getnames() + assert "with_include-1.2.3/src/pkg_sdist_only/sub/__init__.py" in tar.getnames() + assert "with_include-1.2.3/src/pkg_wheel_only/__init__.py" not in tar.getnames() + assert ( + "with_include-1.2.3/src/pkg_wheel_only/sub/__init__.py" + not in tar.getnames() + ) + assert "with_include-1.2.3/src/pkg_both/__init__.py" in tar.getnames() + assert "with_include-1.2.3/src/pkg_both/sub/__init__.py" in tar.getnames() + # other includes + assert "with_include-1.2.3/default.txt" in tar.getnames() + assert "with_include-1.2.3/sdist_only.txt" in tar.getnames() assert "with_include-1.2.3/wheel_only.txt" not in tar.getnames() - assert "with_include-1.2.3/tests/__init__.py" in tar.getnames() - assert "with_include-1.2.3/tests/test_foo/test.py" in tar.getnames() + assert "with_include-1.2.3/both.txt" in tar.getnames() + assert "with_include-1.2.3/default/file.txt" in tar.getnames() + assert "with_include-1.2.3/default/sub/file.txt" in tar.getnames() + assert "with_include-1.2.3/sdist_only/file.txt" in tar.getnames() + assert "with_include-1.2.3/sdist_only/sub/file.txt" in tar.getnames() + assert "with_include-1.2.3/wheel_only/file.txt" not in tar.getnames() + assert "with_include-1.2.3/wheel_only/sub/file.txt" not in tar.getnames() + assert "with_include-1.2.3/both/file.txt" in tar.getnames() + assert "with_include-1.2.3/both/sub/file.txt" in tar.getnames() def test_excluded_subpackage() -> None: diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index b837eacf4..9ec0978be 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -256,8 +256,8 @@ def test_dist_info_file_permissions(project: str) -> None: ) -def test_wheel_includes_inline_table() -> None: - module_path = fixtures_dir / "with_include_inline_table" +def test_wheel_include_formats() -> None: + module_path = fixtures_dir / "with-include-formats" WheelBuilder.make(Factory().create_poetry(module_path)) whl = module_path / "dist" / "with_include-1.2.3-py3-none-any.whl" @@ -265,9 +265,32 @@ def test_wheel_includes_inline_table() -> None: assert whl.exists() with zipfile.ZipFile(str(whl)) as z: - assert "both.txt" in z.namelist() + # packages + assert "mod_default.py" in z.namelist() + assert "mod_sdist_only.py" not in z.namelist() + assert "mod_wheel_only.py" in z.namelist() + assert "mod_both.py" in z.namelist() + assert "pkg_default/__init__.py" in z.namelist() + assert "pkg_default/sub/__init__.py" in z.namelist() + assert "pkg_sdist_only/__init__.py" not in z.namelist() + assert "pkg_sdist_only/sub/__init__.py" not in z.namelist() + assert "pkg_wheel_only/__init__.py" in z.namelist() + assert "pkg_wheel_only/sub/__init__.py" in z.namelist() + assert "pkg_both/__init__.py" in z.namelist() + assert "pkg_both/sub/__init__.py" in z.namelist() + # other includes + assert "default.txt" in z.namelist() + assert "sdist_only.txt" not in z.namelist() assert "wheel_only.txt" in z.namelist() - assert "notes.txt" not in z.namelist() + assert "both.txt" in z.namelist() + assert "default/file.txt" in z.namelist() + assert "default/sub/file.txt" in z.namelist() + assert "sdist_only/file.txt" not in z.namelist() + assert "sdist_only/sub/file.txt" not in z.namelist() + assert "wheel_only/file.txt" in z.namelist() + assert "wheel_only/sub/file.txt" in z.namelist() + assert "both/file.txt" in z.namelist() + assert "both/sub/file.txt" in z.namelist() @pytest.mark.parametrize( diff --git a/tests/masonry/utils/test_package_include.py b/tests/masonry/utils/test_package_include.py index 913a40576..07e9283fa 100644 --- a/tests/masonry/utils/test_package_include.py +++ b/tests/masonry/utils/test_package_include.py @@ -12,7 +12,7 @@ def test_package_include_with_multiple_dirs() -> None: - pkg_include = PackageInclude(base=fixtures_dir, include="with_includes") + pkg_include = PackageInclude(base=fixtures_dir, include="with_includes", formats=[]) assert pkg_include.elements == [ with_includes / "__init__.py", with_includes / "bar", @@ -27,12 +27,14 @@ def test_package_include_with_multiple_dirs() -> None: def test_package_include_with_simple_dir() -> None: - pkg_include = PackageInclude(base=with_includes, include="bar") + pkg_include = PackageInclude(base=with_includes, include="bar", formats=[]) assert pkg_include.elements == [with_includes / "bar/baz.py"] def test_package_include_with_nested_dir() -> None: - pkg_include = PackageInclude(base=with_includes, include="extra_package/**/*.py") + pkg_include = PackageInclude( + base=with_includes, include="extra_package/**/*.py", formats=[] + ) assert pkg_include.elements == [ with_includes / "extra_package/some_dir/foo.py", with_includes / "extra_package/some_dir/quux.py", @@ -41,14 +43,14 @@ def test_package_include_with_nested_dir() -> None: def test_package_include_with_no_python_files_in_dir() -> None: with pytest.raises(ValueError) as e: - PackageInclude(base=with_includes, include="not_a_python_pkg") + PackageInclude(base=with_includes, include="not_a_python_pkg", formats=[]) assert str(e.value) == "not_a_python_pkg is not a package." def test_package_include_with_non_existent_directory() -> None: with pytest.raises(ValueError) as e: - PackageInclude(base=with_includes, include="not_a_dir") + PackageInclude(base=with_includes, include="not_a_dir", formats=[]) err_str = str(with_includes / "not_a_dir") + " does not contain any element" @@ -57,7 +59,7 @@ def test_package_include_with_non_existent_directory() -> None: def test_pep_561_stub_only_package_good_name_suffix() -> None: pkg_include = PackageInclude( - base=fixtures_dir / "pep_561_stub_only", include="good-stubs" + base=fixtures_dir / "pep_561_stub_only", include="good-stubs", formats=[] ) assert pkg_include.elements == [ fixtures_dir / "pep_561_stub_only/good-stubs/__init__.pyi", @@ -67,7 +69,9 @@ 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" + base=fixtures_dir / "pep_561_stub_only_partial_namespace", + include="good-stubs", + formats=[], ) assert pkg_include.elements == [ fixtures_dir / "pep_561_stub_only_partial_namespace/good-stubs/module.pyi", @@ -80,6 +84,8 @@ def test_pep_561_stub_only_partial_namespace_package_good_name_suffix() -> None: 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") + PackageInclude( + base=fixtures_dir / "pep_561_stub_only", include="bad", formats=[] + ) assert str(e.value) == "bad is not a package." diff --git a/tests/test_factory.py b/tests/test_factory.py index 98be739d2..d4ca3d262 100644 --- a/tests/test_factory.py +++ b/tests/test_factory.py @@ -366,8 +366,8 @@ def test_create_poetry_with_packages_and_includes() -> None: ] assert package.include == [ - {"path": "extra_dir/vcs_excluded.py", "format": []}, - {"path": "notes.txt", "format": []}, + {"path": "extra_dir/vcs_excluded.py"}, + {"path": "notes.txt"}, ] From 8cec614e7cd84436871f18452b01946fda328929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:24:54 +0200 Subject: [PATCH 2/3] default to sdist only --- src/poetry/core/masonry/builders/builder.py | 8 ++++---- .../fixtures/exclude_nested_data_toml/pyproject.toml | 2 +- .../fixtures/include_excluded_code/pyproject.toml | 2 +- .../masonry/builders/fixtures/with-include/pyproject.toml | 4 ++-- tests/masonry/builders/test_complete.py | 2 +- tests/masonry/builders/test_wheel.py | 6 +++--- tests/test_factory.py | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/poetry/core/masonry/builders/builder.py b/src/poetry/core/masonry/builders/builder.py index 8fcc9ad3a..129a4c422 100644 --- a/src/poetry/core/masonry/builders/builder.py +++ b/src/poetry/core/masonry/builders/builder.py @@ -55,14 +55,14 @@ def _module(self) -> Module: packages: list[dict[str, Any]] = [] includes: list[dict[str, Any]] = [] - for source_list, target_list in [ - (self._package.packages, packages), - (self._package.include, includes), + for source_list, target_list, default in [ + (self._package.packages, packages, ["sdist", "wheel"]), + (self._package.include, includes, ["sdist"]), ]: for item in source_list: # Default to including in both sdist & wheel # if the `format` key is not provided. - formats = item.get("format", ["sdist", "wheel"]) + formats = item.get("format", default) if not isinstance(formats, list): formats = [formats] diff --git a/tests/masonry/builders/fixtures/exclude_nested_data_toml/pyproject.toml b/tests/masonry/builders/fixtures/exclude_nested_data_toml/pyproject.toml index 0747ae636..f18231f2c 100644 --- a/tests/masonry/builders/fixtures/exclude_nested_data_toml/pyproject.toml +++ b/tests/masonry/builders/fixtures/exclude_nested_data_toml/pyproject.toml @@ -10,7 +10,7 @@ license = "MIT" readme = "README.rst" exclude = ["**/data/", "**/*/item*"] -include = ["my_package/data/data2.txt"] +include = [{path = "my_package/data/data2.txt", format = ["sdist", "wheel"]}] homepage = "https://python-poetry.org/" repository = "https://github.com/python-poetry/poetry" diff --git a/tests/masonry/builders/fixtures/include_excluded_code/pyproject.toml b/tests/masonry/builders/fixtures/include_excluded_code/pyproject.toml index a69ea1808..0b6bf8e8f 100644 --- a/tests/masonry/builders/fixtures/include_excluded_code/pyproject.toml +++ b/tests/masonry/builders/fixtures/include_excluded_code/pyproject.toml @@ -8,7 +8,7 @@ packages = [{include='my_package', from='lib'}] # Simulate excluding due to .gitignore exclude = ['lib/my_package/generated.py'] # Include again -include = ['lib/my_package/generated.py'] +include = [{ path = 'lib/my_package/generated.py', format = ["sdist", "wheel"] }] [tool.poetry.dependencies] python = "^3.8" diff --git a/tests/masonry/builders/fixtures/with-include/pyproject.toml b/tests/masonry/builders/fixtures/with-include/pyproject.toml index 8650f524d..ad94f6467 100644 --- a/tests/masonry/builders/fixtures/with-include/pyproject.toml +++ b/tests/masonry/builders/fixtures/with-include/pyproject.toml @@ -33,8 +33,8 @@ packages = [ ] include = [ - "extra_dir/vcs_excluded.py", - "notes.txt" + { path = "extra_dir/vcs_excluded.py", format = ["sdist", "wheel"] }, + "notes.txt", # default is sdist only ] diff --git a/tests/masonry/builders/test_complete.py b/tests/masonry/builders/test_complete.py index 26d167caf..86a604175 100644 --- a/tests/masonry/builders/test_complete.py +++ b/tests/masonry/builders/test_complete.py @@ -347,7 +347,7 @@ def test_package_with_include(mocker: MockerFixture) -> None: assert "extra_dir/sub_pkg/vcs_excluded.py" not in names assert "for_wheel_only/__init__.py" in names assert "my_module.py" in names - assert "notes.txt" in names + assert "notes.txt" not in names assert "package_with_include/__init__.py" in names assert "tests/__init__.py" not in names assert "src_package/__init__.py" in names diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index 9ec0978be..6351b2f14 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -279,12 +279,12 @@ def test_wheel_include_formats() -> None: assert "pkg_both/__init__.py" in z.namelist() assert "pkg_both/sub/__init__.py" in z.namelist() # other includes - assert "default.txt" in z.namelist() + assert "default.txt" not in z.namelist() assert "sdist_only.txt" not in z.namelist() assert "wheel_only.txt" in z.namelist() assert "both.txt" in z.namelist() - assert "default/file.txt" in z.namelist() - assert "default/sub/file.txt" in z.namelist() + assert "default/file.txt" not in z.namelist() + assert "default/sub/file.txt" not in z.namelist() assert "sdist_only/file.txt" not in z.namelist() assert "sdist_only/sub/file.txt" not in z.namelist() assert "wheel_only/file.txt" in z.namelist() diff --git a/tests/test_factory.py b/tests/test_factory.py index d4ca3d262..b6d9cc34c 100644 --- a/tests/test_factory.py +++ b/tests/test_factory.py @@ -366,7 +366,7 @@ def test_create_poetry_with_packages_and_includes() -> None: ] assert package.include == [ - {"path": "extra_dir/vcs_excluded.py"}, + {"path": "extra_dir/vcs_excluded.py", "format": ["sdist", "wheel"]}, {"path": "notes.txt"}, ] From ad6554bb39ff7c079b5d96e8ad83fd6a27c1bfe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sat, 12 Oct 2024 18:41:43 +0200 Subject: [PATCH 3/3] apply review feedback --- src/poetry/core/masonry/builders/builder.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/poetry/core/masonry/builders/builder.py b/src/poetry/core/masonry/builders/builder.py index 129a4c422..431da9b72 100644 --- a/src/poetry/core/masonry/builders/builder.py +++ b/src/poetry/core/masonry/builders/builder.py @@ -7,7 +7,6 @@ from functools import cached_property from pathlib import Path from typing import TYPE_CHECKING -from typing import Any if TYPE_CHECKING: @@ -28,12 +27,7 @@ class Builder: format: str | None = None - def __init__( - self, - poetry: Poetry, - ignore_packages_formats: bool = False, - executable: Path | None = None, - ) -> None: + def __init__(self, poetry: Poetry, executable: Path | None = None) -> None: from poetry.core.masonry.metadata import Metadata if not poetry.is_package_mode: @@ -44,7 +38,6 @@ def __init__( self._poetry = poetry self._package = poetry.package self._path: Path = poetry.pyproject_path.parent - self._ignore_packages_formats = ignore_packages_formats self._excluded_files: set[str] | None = None self._executable = Path(executable or sys.executable) self._meta = Metadata.from_package(self._package) @@ -53,8 +46,8 @@ def __init__( def _module(self) -> Module: from poetry.core.masonry.utils.module import Module - packages: list[dict[str, Any]] = [] - includes: list[dict[str, Any]] = [] + packages: list[dict[str, str | dict[str, str]]] = [] + includes: list[dict[str, str | dict[str, str]]] = [] for source_list, target_list, default in [ (self._package.packages, packages, ["sdist", "wheel"]), (self._package.include, includes, ["sdist"]), @@ -66,11 +59,7 @@ def _module(self) -> Module: if not isinstance(formats, list): formats = [formats] - if ( - self.format - and self.format not in formats - and not self._ignore_packages_formats - ): + if self.format and self.format not in formats: continue target_list.append({**item, "format": formats})