Skip to content

Commit 7a603c4

Browse files
committed
chore: bump to 0.9.0rc1
Signed-off-by: Henry Schreiner <[email protected]>
1 parent 3894430 commit 7a603c4

File tree

4 files changed

+74
-43
lines changed

4 files changed

+74
-43
lines changed

src/scikit_build_core/_vendor/pyproject_metadata/__init__.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
import packaging.utils
6969
import packaging.version
7070

71-
__version__ = "0.9.0b7"
71+
__version__ = "0.9.0rc1"
7272

7373
__all__ = [
7474
"ConfigurationError",
@@ -126,7 +126,6 @@ class _SmartMessageSetter:
126126
reduce boilerplate.
127127
128128
If a value is None, do nothing.
129-
If a value contains a newline, indent it (may produce a warning in the future).
130129
"""
131130

132131
message: email.message.Message
@@ -252,23 +251,10 @@ class StandardMetadata:
252251
"""
253252
If True, all errors will be collected and raised in an ExceptionGroup.
254253
"""
255-
_locked_metadata: bool = False
256-
"""
257-
Internal flag to prevent setting non-dynamic fields after initialization.
258-
"""
259254

260255
def __post_init__(self) -> None:
261256
self.validate()
262257

263-
def __setattr__(self, name: str, value: Any) -> None:
264-
if self._locked_metadata:
265-
metadata_name = name.replace("_", "-")
266-
locked_fields = constants.KNOWN_METADATA_FIELDS - set(self.dynamic)
267-
if metadata_name in locked_fields:
268-
msg = f"Field {name!r} is not dynamic"
269-
raise AttributeError(msg)
270-
super().__setattr__(name, value)
271-
272258
@property
273259
def auto_metadata_version(self) -> str:
274260
"""
@@ -442,7 +428,6 @@ def from_pyproject( # noqa: C901
442428
metadata_version=metadata_version,
443429
all_errors=all_errors,
444430
)
445-
self._locked_metadata = True
446431

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

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

533+
for name in self.urls:
534+
if len(name) > 32:
535+
msg = "{key} names cannot be more than 32 characters long"
536+
errors.config_error(msg, key="project.urls", got=name)
537+
547538
errors.finalize("Metadata validation failed")
548539

549540
def _write_metadata( # noqa: C901
@@ -565,8 +556,7 @@ def _write_metadata( # noqa: C901
565556
if self.description:
566557
smart_message["Summary"] = self.description
567558
smart_message["Keywords"] = ",".join(self.keywords) or None
568-
if "homepage" in self.urls:
569-
smart_message["Home-page"] = self.urls["homepage"]
559+
# skip 'Home-page'
570560
# skip 'Download-URL'
571561
smart_message["Author"] = _name_list(self.authors)
572562
smart_message["Author-Email"] = _email_list(self.authors)
@@ -581,14 +571,20 @@ def _write_metadata( # noqa: C901
581571
if self.license_files is not None:
582572
for license_file in sorted(set(self.license_files)):
583573
smart_message["License-File"] = os.fspath(license_file.as_posix())
574+
elif (
575+
self.auto_metadata_version not in constants.PRE_SPDX_METADATA_VERSIONS
576+
and isinstance(self.license, License)
577+
and self.license.file
578+
):
579+
smart_message["License-File"] = os.fspath(self.license.file.as_posix())
584580

585581
for classifier in self.classifiers:
586582
smart_message["Classifier"] = classifier
587583
# skip 'Provides-Dist'
588584
# skip 'Obsoletes-Dist'
589585
# skip 'Requires-External'
590586
for name, url in self.urls.items():
591-
smart_message["Project-URL"] = f"{name.capitalize()}, {url}"
587+
smart_message["Project-URL"] = f"{name}, {url}"
592588
if self.requires_python:
593589
smart_message["Requires-Python"] = str(self.requires_python)
594590
for dep in self.dependencies:

src/scikit_build_core/_vendor/pyproject_metadata/constants.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __dir__() -> list[str]:
4848
"version": frozenset(["Version"]),
4949
}
5050

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

@@ -58,9 +58,9 @@ def __dir__() -> list[str]:
5858
"classifier",
5959
"description",
6060
"description-content-type",
61-
"download-url", # Not specified via pyproject standards
61+
"download-url", # Not specified via pyproject standards, deprecated by PEP 753
6262
"dynamic", # Can't be in dynamic
63-
"home-page", # Not specified via pyproject standards
63+
"home-page", # Not specified via pyproject standards, deprecated by PEP 753
6464
"keywords",
6565
"license",
6666
"license-expression",

src/scikit_build_core/_vendor/pyproject_metadata/project_table.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from __future__ import annotations
1212

1313
import sys
14+
import typing
1415
from typing import Any, Dict, List, Union
1516

1617
if sys.version_info < (3, 11):
@@ -28,6 +29,7 @@
2829
"BuildSystemTable",
2930
"ContactTable",
3031
"Dynamic",
32+
"IncludeGroupTable",
3133
"LicenseTable",
3234
"ProjectTable",
3335
"PyProjectTable",
@@ -107,12 +109,44 @@ class LicenseTable(TypedDict, total=False):
107109
total=False,
108110
)
109111

112+
# total=False here because this could be
113+
# extended in the future
114+
IncludeGroupTable = TypedDict(
115+
"IncludeGroupTable",
116+
{"include-group": str},
117+
total=False,
118+
)
119+
110120
PyProjectTable = TypedDict(
111121
"PyProjectTable",
112122
{
113123
"build-system": BuildSystemTable,
114124
"project": ProjectTable,
115125
"tool": Dict[str, Any],
126+
"dependency-groups": Dict[str, List[Union[str, IncludeGroupTable]]],
116127
},
117128
total=False,
118129
)
130+
131+
# Tests for type checking
132+
if typing.TYPE_CHECKING:
133+
PyProjectTable(
134+
{
135+
"build-system": BuildSystemTable(
136+
{"build-backend": "one", "requires": ["two"]}
137+
),
138+
"project": ProjectTable(
139+
{
140+
"name": "one",
141+
"version": "0.1.0",
142+
}
143+
),
144+
"tool": {"thing": object()},
145+
"dependency-groups": {
146+
"one": [
147+
"one",
148+
IncludeGroupTable({"include-group": "two"}),
149+
]
150+
},
151+
}
152+
)

src/scikit_build_core/build/metadata.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from __future__ import annotations
22

33
import copy
4-
import dataclasses
54
import sys
65
from typing import TYPE_CHECKING, Any
76

87
from packaging.version import Version
98

9+
from .._logging import logger
1010
from .._vendor.pyproject_metadata import (
1111
StandardMetadata,
1212
errors,
@@ -52,34 +52,35 @@ def get_standard_metadata(
5252
new_pyproject_dict["project"][field] = provider.dynamic_metadata(field, config)
5353
new_pyproject_dict["project"]["dynamic"].remove(field)
5454

55+
if settings.strict_config:
56+
extra_keys_top = extras_top_level(new_pyproject_dict)
57+
if extra_keys_top:
58+
logger.warning(
59+
f"Unknown keys in top-level of pyproject.toml: {', '.join(extra_keys_top)}"
60+
)
61+
extra_keys_build = extras_build_system(new_pyproject_dict)
62+
if extra_keys_build:
63+
logger.warning(
64+
f"Unknown keys in build-system of pyproject.toml: {', '.join(extra_keys_build)}"
65+
)
66+
5567
extra_validate = (
5668
settings.minimum_version is None or settings.minimum_version >= Version("0.10")
5769
)
58-
try:
59-
metadata = StandardMetadata.from_pyproject(
60-
new_pyproject_dict, all_errors=True, allow_extra_keys=not extra_validate
61-
)
62-
except ExceptionGroup as e:
63-
if extra_validate:
64-
extra_keys_top = extras_top_level(new_pyproject_dict)
65-
if extra_keys_top:
66-
msg = f"Unknown keys in top-level of pyproject.toml: {', '.join(extra_keys_top)}"
67-
e = ExceptionGroup(
68-
e.message, (*e.exceptions, errors.ConfigurationError(msg))
69-
)
70-
extra_keys_build = extras_build_system(new_pyproject_dict)
71-
if extra_keys_build:
72-
msg = f"Unknown keys in build-system of pyproject.toml: {', '.join(extra_keys_build)}"
73-
e = ExceptionGroup(
74-
e.message, (*e.exceptions, errors.ConfigurationError(msg))
75-
)
76-
raise e from None
70+
if extra_validate:
71+
allow_extra_keys: bool | None = not settings.strict_config
72+
else:
73+
allow_extra_keys = None if settings.strict_config else False
74+
75+
metadata = StandardMetadata.from_pyproject(
76+
new_pyproject_dict, all_errors=True, allow_extra_keys=allow_extra_keys
77+
)
7778

7879
# For scikit-build-core < 0.5, we keep the normalized name for back-compat
7980
if settings.minimum_version is not None and settings.minimum_version < Version(
8081
"0.5"
8182
):
82-
metadata = dataclasses.replace(metadata, name=metadata.canonical_name)
83+
metadata.name = metadata.canonical_name
8384

8485
# The description field is required to be one line. Instead of merging it
8586
# or cutting off subsequent lines (setuptools), we throw a nice error.

0 commit comments

Comments
 (0)