Skip to content

Commit ceed6cb

Browse files
committed
feat: PEP 794 support
Signed-off-by: Henry Schreiner <[email protected]>
1 parent 17a364b commit ceed6cb

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

pyproject_metadata/__init__.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ class StandardMetadata:
271271
keywords: list[str] = dataclasses.field(default_factory=list)
272272
scripts: dict[str, str] = dataclasses.field(default_factory=dict)
273273
gui_scripts: dict[str, str] = dataclasses.field(default_factory=dict)
274+
import_names: list[str] = dataclasses.field(default_factor=list)
275+
import_namespaces: list[str] = dataclasses.field(default_factory=list)
274276
dynamic: list[Dynamic] = dataclasses.field(default_factory=list)
275277
"""
276278
This field is used to track dynamic fields. You can't set a field not in this list.
@@ -460,6 +462,14 @@ def from_pyproject( # noqa: C901
460462
project.get("gui-scripts", {}), "project.gui-scripts"
461463
)
462464
or {},
465+
import_names=pyproject.ensure_list(
466+
project.get("import-names", []), "project.import-names"
467+
)
468+
or [],
469+
import_namespaces=pyproject.ensure_list(
470+
project.get("import-namespaces", []), "project.import-namespaces"
471+
)
472+
or [],
463473
dynamic=dynamic,
464474
dynamic_metadata=dynamic_metadata or [],
465475
metadata_version=metadata_version,
@@ -504,6 +514,7 @@ def validate(self, *, warn: bool = True) -> None: # noqa: C901
504514
- ``license`` is an SPDX license expression if metadata_version >= 2.4
505515
- ``license_files`` is supported only for metadata_version >= 2.4
506516
- ``project_url`` can't contain keys over 32 characters
517+
- ``import-names(paces)`` is only supported on metadata_version >= 2.5
507518
"""
508519
errors = ErrorCollector(collect_errors=self.all_errors)
509520

@@ -570,6 +581,20 @@ def validate(self, *, warn: bool = True) -> None: # noqa: C901
570581
msg = "{key} names cannot be more than 32 characters long"
571582
errors.config_error(msg, key="project.urls", got=name)
572583

584+
if (
585+
self.import_names
586+
and self.auto_metadata_version in constants.PRE_2_5_METADATA_VERSIONS
587+
):
588+
msg = "{key} is only supported when emitting metadata version >= 2.5"
589+
errors.config_error(msg, key="project.import_names")
590+
591+
if (
592+
self.import_namespaces
593+
and self.auto_metadata_version in constants.PRE_2_5_METADATA_VERSIONS
594+
):
595+
msg = "{key} is only supported when emitting metadata version >= 2.5"
596+
errors.config_error(msg, key="project.import_namespaces")
597+
573598
errors.finalize("Metadata validation failed")
574599

575600
def _write_metadata( # noqa: C901
@@ -637,6 +662,10 @@ def _write_metadata( # noqa: C901
637662
if self.readme.content_type:
638663
smart_message["Description-Content-Type"] = self.readme.content_type
639664
smart_message.set_payload(self.readme.text)
665+
for import_name in self.import_names:
666+
smart_message["Import-Name"] = import_name
667+
for import_namespace in self.import_namespaces:
668+
smart_message["Import-Namespace"] = import_namespace
640669
# Core Metadata 2.2
641670
if self.auto_metadata_version != "2.1":
642671
for field in self.dynamic_metadata:

pyproject_metadata/constants.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ def __dir__() -> list[str]:
2424
return __all__
2525

2626

27-
KNOWN_METADATA_VERSIONS = {"2.1", "2.2", "2.3", "2.4"}
27+
KNOWN_METADATA_VERSIONS = {"2.1", "2.2", "2.3", "2.4", "2.5"}
2828
PRE_SPDX_METADATA_VERSIONS = {"2.1", "2.2", "2.3"}
29+
PRE_2_5_METADATA_VERSIONS = {"2.1", "2.2", "2.3", "2.4"}
2930

3031
PROJECT_TO_METADATA = {
3132
"authors": frozenset(["Author", "Author-Email"]),
@@ -46,6 +47,8 @@ def __dir__() -> list[str]:
4647
"scripts": frozenset(),
4748
"urls": frozenset(["Project-URL"]),
4849
"version": frozenset(["Version"]),
50+
"import-names": frozenset(["Import-Name"]),
51+
"import-namespaces": frozenset(["Import-Namespaces"]),
4952
}
5053

5154
KNOWN_TOPLEVEL_FIELDS = {"build-system", "project", "tool", "dependency-groups"}
@@ -83,6 +86,8 @@ def __dir__() -> list[str]:
8386
"summary",
8487
"supported-platform", # Not specified via pyproject standards
8588
"version", # Can't be in dynamic
89+
"import-name",
90+
"import-namespace",
8691
}
8792

8893
KNOWN_MULTIUSE = {
@@ -100,4 +105,6 @@ def __dir__() -> list[str]:
100105
"requires", # Deprecated
101106
"obsoletes", # Deprecated
102107
"provides", # Deprecated
108+
"import-name",
109+
"import-namespace",
103110
}

pyproject_metadata/project_table.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class LicenseTable(TypedDict, total=False):
6868
"scripts",
6969
"urls",
7070
"version",
71+
"import-names",
72+
"import-namespaces",
7173
]
7274

7375
ProjectTable = TypedDict(
@@ -90,6 +92,8 @@ class LicenseTable(TypedDict, total=False):
9092
"keywords": List[str],
9193
"scripts": Dict[str, str],
9294
"gui-scripts": Dict[str, str],
95+
"import-names": List[str],
96+
"import-namespaces": List[str],
9397
"dynamic": List[Dynamic],
9498
},
9599
total=False,

0 commit comments

Comments
 (0)