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

chore: bump validate-pyproject to 0.9.0 #265

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
chore: bump to 0.9.0rc1
Signed-off-by: Henry Schreiner <[email protected]>
henryiii committed Oct 21, 2024

Verified

This commit was signed with the committer’s verified signature.
henryiii Henry Schreiner
commit 0da6c3ae5c68ab78ad05d74642cfc14cb1b2da24
34 changes: 15 additions & 19 deletions src/pdm/backend/_vendor/pyproject_metadata/__init__.py
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@
import pdm.backend._vendor.packaging.utils
import pdm.backend._vendor.packaging.version

__version__ = "0.9.0b7"
__version__ = "0.9.0rc1"

__all__ = [
"ConfigurationError",
@@ -127,7 +127,6 @@ class _SmartMessageSetter:
reduce boilerplate.
If a value is None, do nothing.
If a value contains a newline, indent it (may produce a warning in the future).
"""

message: email.message.Message
@@ -253,23 +252,10 @@ class StandardMetadata:
"""
If True, all errors will be collected and raised in an ExceptionGroup.
"""
_locked_metadata: bool = False
"""
Internal flag to prevent setting non-dynamic fields after initialization.
"""

def __post_init__(self) -> None:
self.validate()

def __setattr__(self, name: str, value: Any) -> None:
if self._locked_metadata:
metadata_name = name.replace("_", "-")
locked_fields = constants.KNOWN_METADATA_FIELDS - set(self.dynamic)
if metadata_name in locked_fields:
msg = f"Field {name!r} is not dynamic"
raise AttributeError(msg)
super().__setattr__(name, value)

@property
def auto_metadata_version(self) -> str:
"""
@@ -443,7 +429,6 @@ def from_pyproject( # noqa: C901
metadata_version=metadata_version,
all_errors=all_errors,
)
self._locked_metadata = True

pyproject.finalize("Failed to parse pyproject.toml")
assert self is not None
@@ -482,6 +467,7 @@ def validate(self, *, warn: bool = True) -> None: # noqa: C901
- License classifiers deprecated for metadata_version >= 2.4 (warning)
- ``license`` is an SPDX license expression if metadata_version >= 2.4
- ``license_files`` is supported only for metadata_version >= 2.4
- ``project_url`` can't contain keys over 32 characters
"""
errors = ErrorCollector(collect_errors=self.all_errors)

@@ -545,6 +531,11 @@ def validate(self, *, warn: bool = True) -> None: # noqa: C901
msg = "{key} is supported only when emitting metadata version >= 2.4"
errors.config_error(msg, key="project.license-files")

for name in self.urls:
if len(name) > 32:
msg = "{key} names cannot be more than 32 characters long"
errors.config_error(msg, key="project.urls", got=name)

errors.finalize("Metadata validation failed")

def _write_metadata( # noqa: C901
@@ -566,8 +557,7 @@ def _write_metadata( # noqa: C901
if self.description:
smart_message["Summary"] = self.description
smart_message["Keywords"] = ",".join(self.keywords) or None
if "homepage" in self.urls:
smart_message["Home-page"] = self.urls["homepage"]
# skip 'Home-page'
# skip 'Download-URL'
smart_message["Author"] = _name_list(self.authors)
smart_message["Author-Email"] = _email_list(self.authors)
@@ -582,14 +572,20 @@ def _write_metadata( # noqa: C901
if self.license_files is not None:
for license_file in sorted(set(self.license_files)):
smart_message["License-File"] = os.fspath(license_file.as_posix())
elif (
self.auto_metadata_version not in constants.PRE_SPDX_METADATA_VERSIONS
and isinstance(self.license, License)
and self.license.file
):
smart_message["License-File"] = os.fspath(self.license.file.as_posix())

for classifier in self.classifiers:
smart_message["Classifier"] = classifier
# skip 'Provides-Dist'
# skip 'Obsoletes-Dist'
# skip 'Requires-External'
for name, url in self.urls.items():
smart_message["Project-URL"] = f"{name.capitalize()}, {url}"
smart_message["Project-URL"] = f"{name}, {url}"
if self.requires_python:
smart_message["Requires-Python"] = str(self.requires_python)
for dep in self.dependencies:
6 changes: 3 additions & 3 deletions src/pdm/backend/_vendor/pyproject_metadata/constants.py
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ def __dir__() -> list[str]:
"version": frozenset(["Version"]),
}

KNOWN_TOPLEVEL_FIELDS = {"build-system", "project", "tool"}
KNOWN_TOPLEVEL_FIELDS = {"build-system", "project", "tool", "dependency-groups"}
KNOWN_BUILD_SYSTEM_FIELDS = {"backend-path", "build-backend", "requires"}
KNOWN_PROJECT_FIELDS = set(PROJECT_TO_METADATA)

@@ -58,9 +58,9 @@ def __dir__() -> list[str]:
"classifier",
"description",
"description-content-type",
"download-url", # Not specified via pyproject standards
"download-url", # Not specified via pyproject standards, deprecated by PEP 753
"dynamic", # Can't be in dynamic
"home-page", # Not specified via pyproject standards
"home-page", # Not specified via pyproject standards, deprecated by PEP 753
"keywords",
"license",
"license-expression",
34 changes: 34 additions & 0 deletions src/pdm/backend/_vendor/pyproject_metadata/project_table.py
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
from __future__ import annotations

import sys
import typing
from typing import Any, Dict, List, Union

if sys.version_info < (3, 11):
@@ -28,6 +29,7 @@
"BuildSystemTable",
"ContactTable",
"Dynamic",
"IncludeGroupTable",
"LicenseTable",
"ProjectTable",
"PyProjectTable",
@@ -107,12 +109,44 @@ class LicenseTable(TypedDict, total=False):
total=False,
)

# total=False here because this could be
# extended in the future
IncludeGroupTable = TypedDict(
"IncludeGroupTable",
{"include-group": str},
total=False,
)

PyProjectTable = TypedDict(
"PyProjectTable",
{
"build-system": BuildSystemTable,
"project": ProjectTable,
"tool": Dict[str, Any],
"dependency-groups": Dict[str, List[Union[str, IncludeGroupTable]]],
},
total=False,
)

# Tests for type checking
if typing.TYPE_CHECKING:
PyProjectTable(
{
"build-system": BuildSystemTable(
{"build-backend": "one", "requires": ["two"]}
),
"project": ProjectTable(
{
"name": "one",
"version": "0.1.0",
}
),
"tool": {"thing": object()},
"dependency-groups": {
"one": [
"one",
IncludeGroupTable({"include-group": "two"}),
]
},
}
)
2 changes: 1 addition & 1 deletion src/pdm/backend/_vendor/vendor.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
packaging==24.1
tomli==2.0.1
tomli_w==1.0.0
pyproject-metadata==0.9.0b7
pyproject-metadata==0.9.0rc1
editables==0.5