Skip to content

Commit eb61027

Browse files
committed
feat: wip: add import-names and import-namespaces support in wheel metadata
1 parent 314b685 commit eb61027

9 files changed

Lines changed: 123 additions & 9 deletions

File tree

src/poetry/core/masonry/builders/builder.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,20 @@ def get_metadata_content(self) -> str:
290290
if self._meta.description is not None:
291291
content += f"\n{self._meta.description}\n"
292292

293+
if self._meta.import_names is not None:
294+
if len(self._meta.import_names) == 0:
295+
content += "Import-Name: \n"
296+
297+
for import_name in self._meta.import_names:
298+
content += f"Import-Name: {import_name}\n"
299+
300+
if self._meta.import_namespaces is not None:
301+
if len(self._meta.import_namespaces) == 0:
302+
content += "Import-Namespace: \n"
303+
304+
for namespace in self._meta.import_namespaces:
305+
content += f"Import-Namespace: {namespace}\n"
306+
293307
return content
294308

295309
def convert_entry_points(self) -> dict[str, list[str]]:

src/poetry/core/masonry/metadata.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212

1313
from poetry.core.packages.project_package import ProjectPackage
1414

15+
METADATA_VERSION = "2.5"
16+
1517

1618
class Metadata:
17-
metadata_version = "2.4"
19+
metadata_version = METADATA_VERSION
1820
# version 1.0
1921
name: str | None = None
2022
version: str
@@ -51,6 +53,10 @@ class Metadata:
5153
license_expression: str | None = None
5254
license_files: tuple[str, ...] = ()
5355

56+
# Version 2.5
57+
import_names: list[str] | None = None
58+
import_namespaces: list[str] | None = None
59+
5460
@classmethod
5561
def from_package(cls, package: ProjectPackage) -> Metadata:
5662
from poetry.core.version.helpers import format_python_constraint
@@ -128,6 +134,9 @@ def from_package(cls, package: ProjectPackage) -> Metadata:
128134
f"{name}, {url}" for name, url in package.urls.items()
129135
)
130136

137+
meta.import_names = package.import_names
138+
meta.import_namespaces = package.import_namespaces
139+
131140
return meta
132141

133142
@classmethod

tests/masonry/builders/fixtures/with-import-names/another_package/a/__init__.py

Whitespace-only changes.

tests/masonry/builders/fixtures/with-import-names/my_package/b/__init__.py

Whitespace-only changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[project]
2+
name = "with-import-names"
3+
version = "1.2.3"
4+
description = "Some description."
5+
requires-python = ">=3.6,<4.0"
6+
authors = [
7+
{ "name" = "Sébastien Eustace", "email" = "sebastien@eustace.io" }
8+
]
9+
license = "MIT"
10+
11+
keywords = ["packaging", "dependency", "poetry"]
12+
dependencies = []
13+
14+
import-namespaces = ["my_package", "another_package"]
15+
import-names = ["my_package.a", "another_package.b"]
16+
17+
[tool.poetry]
18+
packages = [
19+
{ include = "my_package" },
20+
]

tests/masonry/builders/test_builder.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from poetry.core.factory import Factory
1212
from poetry.core.masonry.builders.builder import Builder
13+
from poetry.core.masonry.metadata import METADATA_VERSION
1314
from poetry.core.utils._compat import tomllib
1415

1516

@@ -116,7 +117,7 @@ def test_get_metadata_content(project: str) -> None:
116117
p = Parser()
117118
parsed = p.parsestr(metadata)
118119

119-
assert parsed["Metadata-Version"] == "2.4"
120+
assert parsed["Metadata-Version"] == METADATA_VERSION
120121
assert parsed["Name"] == "my-package"
121122
assert parsed["Version"] == "1.2.3"
122123
assert parsed["Summary"] == "Some description."
@@ -176,6 +177,12 @@ def test_get_metadata_content(project: str) -> None:
176177
"Repository, https://github.com/python-poetry/poetry",
177178
]
178179

180+
import_names = parsed.get_all("Import-Name", False)
181+
assert import_names is False
182+
183+
import_namespaces = parsed.get_all("Import-Namespace", False)
184+
assert import_namespaces is False
185+
179186

180187
def test_metadata_pretty_name() -> None:
181188
builder = Builder(

tests/masonry/builders/test_complete.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from poetry.core.factory import Factory
1919
from poetry.core.masonry.builders.sdist import SdistBuilder
2020
from poetry.core.masonry.builders.wheel import WheelBuilder
21+
from poetry.core.masonry.metadata import METADATA_VERSION
2122
from tests.masonry.builders.test_wheel import WHEEL_TAG_REGEX
2223

2324

@@ -180,8 +181,8 @@ def test_complete(project: str, no_vcs: bool) -> None:
180181
)
181182

182183
metadata = zipf.read("my_package-1.2.3.dist-info/METADATA").decode()
183-
expected_metadata = """\
184-
Metadata-Version: 2.4
184+
expected_metadata = f"""\
185+
Metadata-Version: {METADATA_VERSION}
185186
Name: my-package
186187
Version: 1.2.3
187188
Summary: Some description.

tests/masonry/test_api.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from poetry.core import __version__
1313
from poetry.core.masonry import api
14+
from poetry.core.masonry.metadata import METADATA_VERSION
1415
from poetry.core.utils.helpers import temporary_directory
1516
from tests.testutils import validate_sdist_contents
1617
from tests.testutils import validate_wheel_contents
@@ -175,8 +176,8 @@ def test_prepare_metadata_for_build_wheel(project: str) -> None:
175176
Root-Is-Purelib: true
176177
Tag: py3-none-any
177178
"""
178-
metadata = """\
179-
Metadata-Version: 2.4
179+
metadata = f"""\
180+
Metadata-Version: {METADATA_VERSION}
180181
Name: my-package
181182
Version: 1.2.3
182183
Summary: Some description.
@@ -262,7 +263,7 @@ def test_prepare_metadata_for_build_wheel_with_local_version() -> None:
262263
Tag: py3-none-any
263264
"""
264265
metadata = f"""\
265-
Metadata-Version: 2.4
266+
Metadata-Version: {METADATA_VERSION}
266267
Name: my-package
267268
Version: 1.2.3+{local_version}
268269
Summary: Some description.
@@ -339,8 +340,8 @@ def test_prepare_metadata_excludes_optional_without_extras() -> None:
339340
with (dist_info / "METADATA").open(encoding="utf-8") as f:
340341
assert (
341342
f.read()
342-
== """\
343-
Metadata-Version: 2.4
343+
== f"""\
344+
Metadata-Version: {METADATA_VERSION}
344345
Name: my-packager
345346
Version: 0.1
346347
Summary: Something
@@ -371,6 +372,46 @@ def test_prepare_metadata_for_build_wheel_with_bad_path_dep_succeeds(
371372
assert "does not exist" in record.message
372373

373374

375+
def test_prepare_metadata_with_import_names() -> None:
376+
with (
377+
temporary_directory() as tmp_dir,
378+
cwd(fixtures / "with-import-names"),
379+
):
380+
dirname = api.prepare_metadata_for_build_wheel(str(tmp_dir))
381+
dist_info = Path(tmp_dir, dirname)
382+
assert (dist_info / "METADATA").exists()
383+
384+
with (dist_info / "METADATA").open(encoding="utf-8") as f:
385+
assert (
386+
f.read()
387+
== f"""\
388+
Metadata-Version: {METADATA_VERSION}
389+
Name: with-import-names
390+
Version: 1.2.3
391+
Summary: Some description.
392+
License-Expression: MIT
393+
Keywords: packaging,dependency,poetry
394+
Author: Sébastien Eustace
395+
Author-email: sebastien@eustace.io
396+
Requires-Python: >=3.6,<4.0
397+
Classifier: Programming Language :: Python :: 3
398+
Classifier: Programming Language :: Python :: 3.6
399+
Classifier: Programming Language :: Python :: 3.7
400+
Classifier: Programming Language :: Python :: 3.8
401+
Classifier: Programming Language :: Python :: 3.9
402+
Classifier: Programming Language :: Python :: 3.10
403+
Classifier: Programming Language :: Python :: 3.11
404+
Classifier: Programming Language :: Python :: 3.12
405+
Classifier: Programming Language :: Python :: 3.13
406+
Classifier: Programming Language :: Python :: 3.14
407+
Import-Name: my_package.a
408+
Import-Name: another_package.b
409+
Import-Namespace: my_package
410+
Import-Namespace: another_package
411+
"""
412+
)
413+
414+
374415
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
375416
def test_build_editable_wheel(project: str) -> None:
376417
pkg_dir = fixtures / project

tests/masonry/test_metadata.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,28 @@ def test_from_package_multiple_readmes(package: ProjectPackage) -> None:
205205
assert metadata.description == "Description 1\nDescription 2"
206206

207207

208+
@pytest.mark.parametrize(
209+
["import_names", "import_namespaces"],
210+
[
211+
(["my_package.a", "my_package.b"], ["my_package"]),
212+
(None, None),
213+
([], []),
214+
],
215+
)
216+
def test_from_package_import_names(
217+
import_names: list[str] | None,
218+
import_namespaces: list[str] | None,
219+
package: ProjectPackage,
220+
) -> None:
221+
package.import_names = import_names
222+
package.import_namespaces = import_namespaces
223+
224+
metadata = Metadata.from_package(package)
225+
226+
assert metadata.import_names == import_names
227+
assert metadata.import_namespaces == import_namespaces
228+
229+
208230
@pytest.mark.parametrize(
209231
("exception", "message"),
210232
[

0 commit comments

Comments
 (0)