Skip to content
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

Allow custom subpackage names in built wheels #672

Merged
merged 9 commits into from
Dec 18, 2023
4 changes: 4 additions & 0 deletions src/poetry/core/json/schemas/poetry-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
},
"format": {
"$ref": "#/definitions/package-formats"
},
"to": {
"type": "string",
"description": "Where the package should be installed in the final distribution."
}
}
}
Expand Down
35 changes: 27 additions & 8 deletions src/poetry/core/masonry/builders/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,23 @@ def find_files_to_add(self, exclude_build: bool = True) -> set[BuildIncludeFile]
else:
source_root = self._path

if (
isinstance(include, PackageInclude)
and include.target
and self.format == "wheel"
):
target_dir = include.target
else:
target_dir = None

if file.is_dir():
if self.format in formats:
for current_file in file.glob("**/*"):
include_file = BuildIncludeFile(
path=current_file,
project_root=self._path,
source_root=source_root,
target_dir=target_dir,
)

if not (
Expand All @@ -199,7 +209,10 @@ def find_files_to_add(self, exclude_build: bool = True) -> set[BuildIncludeFile]
continue

include_file = BuildIncludeFile(
path=file, project_root=self._path, source_root=source_root
path=file,
project_root=self._path,
source_root=source_root,
target_dir=target_dir,
radoering marked this conversation as resolved.
Show resolved Hide resolved
)

if self.is_excluded(
Expand Down Expand Up @@ -367,17 +380,20 @@ def __init__(
self,
path: Path | str,
project_root: Path | str,
source_root: Path | str | None = None,
source_root: Path | str,
target_dir: Path | str | None = None,
) -> None:
"""
:param project_root: the full path of the project's root
:param path: a full path to the file to be included
:param source_root: the root path to resolve to
:param source_root: the full root path to resolve to
:param target_dir: the relative target root to resolve to
"""
self.path = Path(path)
self.project_root = Path(project_root).resolve()
self.source_root = None if not source_root else Path(source_root).resolve()
if not self.path.is_absolute() and self.source_root:
self.source_root = Path(source_root).resolve()
self.target_dir = None if not target_dir else Path(target_dir)
if not self.path.is_absolute():
self.path = self.source_root / self.path
else:
self.path = self.path
Expand All @@ -400,7 +416,10 @@ def relative_to_project_root(self) -> Path:
return self.path.relative_to(self.project_root)

def relative_to_source_root(self) -> Path:
if self.source_root is not None:
return self.path.relative_to(self.source_root)
return self.path.relative_to(self.source_root)

return self.path
def relative_to_target_root(self) -> Path:
path = self.relative_to_source_root()
if self.target_dir is not None:
return self.target_dir / path
return path
2 changes: 1 addition & 1 deletion src/poetry/core/masonry/builders/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def _copy_module(self, wheel: zipfile.ZipFile) -> None:
# Walk the files and compress them,
# sorting everything so the order is stable.
for file in sorted(to_add, key=lambda x: x.path):
self._add_file(wheel, file.path, file.relative_to_source_root())
self._add_file(wheel, file.path, file.relative_to_target_root())

def prepare_metadata(self, metadata_directory: Path) -> Path:
dist_info = metadata_directory / self.dist_info
Expand Down
1 change: 1 addition & 0 deletions src/poetry/core/masonry/utils/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def __init__(
package["include"],
formats=formats,
source=package.get("from"),
target=package.get("to"),
)
)

Expand Down
6 changes: 6 additions & 0 deletions src/poetry/core/masonry/utils/package_include.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ def __init__(
include: str,
formats: list[str] | None = None,
source: str | None = None,
target: str | None = None,
) -> None:
self._package: str
self._is_package = False
self._is_module = False
self._source = source
self._target = target

if source is not None:
base = base / source
Expand All @@ -36,6 +38,10 @@ def package(self) -> str:
def source(self) -> str | None:
return self._source

@property
def target(self) -> str | None:
return self._target

def is_package(self) -> bool:
return self._is_package

Expand Down
Empty file.
Empty file.
2 changes: 2 additions & 0 deletions tests/masonry/builders/fixtures/with-include/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ packages = [
{ include = "tests", format = "sdist" },
{ include = "for_wheel_only", format = ["wheel"] },
{ include = "src_package", from = "src"},
{ include = "from_to", from = "etc", "to" = "target_from_to"},
{ include = "my_module_to.py", "to" = "target_module"},
]

include = [
Expand Down
3 changes: 3 additions & 0 deletions tests/masonry/builders/test_complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ def test_package_with_include(mocker: MockerFixture) -> None:
assert "with_include-1.2.3/PKG-INFO" in names
assert "with_include-1.2.3/for_wheel_only/__init__.py" not in names
assert "with_include-1.2.3/src/src_package/__init__.py" in names
assert "with_include-1.2.3/etc/from_to/__init__.py" in names

whl = module_path / "dist" / "with_include-1.2.3-py3-none-any.whl"

Expand All @@ -340,6 +341,8 @@ def test_package_with_include(mocker: MockerFixture) -> None:
assert "package_with_include/__init__.py" in names
assert "tests/__init__.py" not in names
assert "src_package/__init__.py" in names
assert "target_from_to/from_to/__init__.py" in names
assert "target_module/my_module_to.py" in names


def test_respect_format_for_explicit_included_files() -> None:
Expand Down
2 changes: 2 additions & 0 deletions tests/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ def test_create_poetry_with_packages_and_includes() -> None:
{"include": "tests", "format": "sdist"},
{"include": "for_wheel_only", "format": ["wheel"]},
{"include": "src_package", "from": "src"},
{"include": "from_to", "from": "etc", "to": "target_from_to"},
{"include": "my_module_to.py", "to": "target_module"},
]

assert package.include == [
Expand Down