Skip to content

Commit 6c48d72

Browse files
authored
feat: update pyproject-metadata to support latest version of PEP 639 (#259)
* fix: update pyproject-metadata to 0.9.0 Signed-off-by: Frost Ming <me@frostming.com> * feat: update pyproject-metadata to support latest version of PEP 639 Signed-off-by: Frost Ming <me@frostming.com> * fix tests Signed-off-by: Frost Ming <me@frostming.com>
1 parent 708aa3f commit 6c48d72

File tree

52 files changed

+941
-744
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+941
-744
lines changed

docs/hooks.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pdm-build-mypyc
137137
version = "0.1.0"
138138
description = "A pdm build hook to compile Python code with mypyc"
139139
authors = [{name = "...", email = "..."}]
140-
license = {text = "MIT"}
140+
license = "MIT"
141141
readme = "README.md"
142142

143143
[project.entry-points."pdm.build.hook"]
@@ -156,7 +156,6 @@ pdm-build-mypyc
156156
mypyc_build(context.build_dir)
157157
```
158158

159-
160159
The plugin must be distributed with an entry point under `pdm.build.hook` group. The entry point value can be any of the following:
161160

162161
- A module containing hook functions

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ authors = [{name = "John Doe", email="me@johndoe.org"}]
4040
dependencies = ["requests"]
4141
requires-python = ">=3.8"
4242
readme = "README.md"
43-
license = {text = "MIT"}
43+
license = "MIT"
4444
```
4545

4646
Then run the build command to build the project as wheel and sdist:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description = "The build backend used by PDM that supports latest packaging stan
66
authors = [
77
{ name = "Frost Ming", email = "me@frostming.com" }
88
]
9-
license = {text = "MIT"}
9+
license = "MIT"
1010
requires-python = ">=3.8"
1111
readme = "README.md"
1212
keywords = ["packaging", "PEP 517", "build"]
Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
diff --git a/src/pdm/backend/_vendor/pyproject_metadata/__init__.py b/src/pdm/backend/_vendor/pyproject_metadata/__init__.py
2-
index df826f8..7f69f3a 100644
2+
index 52289dc..7ef9fc9 100644
33
--- a/src/pdm/backend/_vendor/pyproject_metadata/__init__.py
44
+++ b/src/pdm/backend/_vendor/pyproject_metadata/__init__.py
5-
@@ -24,11 +24,11 @@ if typing.TYPE_CHECKING:
5+
@@ -20,18 +20,18 @@ if typing.TYPE_CHECKING:
6+
from collections.abc import Generator, Iterable, Mapping
7+
from typing import Any
8+
9+
- from packaging.requirements import Requirement
10+
+ from pdm.backend._vendor.packaging.requirements import Requirement
11+
12+
if sys.version_info < (3, 11):
13+
from typing_extensions import Self
614
else:
715
from typing import Self
816

@@ -18,22 +26,46 @@ index df826f8..7f69f3a 100644
1826
+import pdm.backend._vendor.packaging.version as pkg_version
1927

2028

21-
__version__ = '0.8.0'
22-
@@ -175,11 +175,11 @@ class Readme(typing.NamedTuple):
29+
__version__ = '0.9.0b3'
30+
@@ -351,8 +351,8 @@ class ProjectFetcher(DataFetcher):
31+
requirements: list[Requirement] = []
32+
for req in requirement_strings:
33+
try:
34+
- requirements.append(packaging.requirements.Requirement(req))
35+
- except packaging.requirements.InvalidRequirement as e:
36+
+ requirements.append(pkg_requirements.Requirement(req))
37+
+ except pkg_requirements.InvalidRequirement as e:
38+
msg = (
39+
'Field "project.dependencies" contains an invalid PEP 508 '
40+
f'requirement string "{req}" ("{e}")'
41+
@@ -393,9 +393,9 @@ class ProjectFetcher(DataFetcher):
42+
raise ConfigurationError(msg)
43+
try:
44+
requirements_dict[extra].append(
45+
- packaging.requirements.Requirement(req)
46+
+ pkg_requirements.Requirement(req)
47+
)
48+
- except packaging.requirements.InvalidRequirement as e:
49+
+ except pkg_requirements.InvalidRequirement as e:
50+
msg = (
51+
f'Field "project.optional-dependencies.{extra}" contains '
52+
f'an invalid PEP 508 requirement string "{req}" ("{e}")'
53+
@@ -453,12 +453,12 @@ class Readme(typing.NamedTuple):
2354
@dataclasses.dataclass
2455
class StandardMetadata:
2556
name: str
2657
- version: packaging.version.Version | None = None
2758
+ version: pkg_version.Version | None = None
2859
description: str | None = None
29-
license: License | None = None
60+
license: License | str | None = None
61+
license_files: list[pathlib.Path] | None = None
3062
readme: Readme | None = None
3163
- requires_python: packaging.specifiers.SpecifierSet | None = None
3264
+ requires_python: pkg_specifiers.SpecifierSet | None = None
3365
dependencies: list[Requirement] = dataclasses.field(default_factory=list)
34-
optional_dependencies: dict[str, list[Requirement]] = dataclasses.field(default_factory=dict)
35-
entrypoints: dict[str, dict[str, str]] = dataclasses.field(default_factory=dict)
36-
@@ -202,7 +202,7 @@ class StandardMetadata:
66+
optional_dependencies: dict[str, list[Requirement]] = dataclasses.field(
67+
default_factory=dict
68+
@@ -547,7 +547,7 @@ class StandardMetadata:
3769

3870
@property
3971
def canonical_name(self) -> str:
@@ -42,7 +74,7 @@ index df826f8..7f69f3a 100644
4274

4375
@classmethod
4476
def from_pyproject(
45-
@@ -235,7 +235,7 @@ class StandardMetadata:
77+
@@ -590,7 +590,7 @@ class StandardMetadata:
4678

4779
version_string = fetcher.get_str('project.version')
4880
requires_python_string = fetcher.get_str('project.requires-python')
@@ -51,16 +83,16 @@ index df826f8..7f69f3a 100644
5183

5284
if version is None and 'version' not in dynamic:
5385
msg = 'Field "project.version" missing and "version" not specified in "project.dynamic"'
54-
@@ -256,7 +256,7 @@ class StandardMetadata:
55-
description,
56-
cls._get_license(fetcher, project_dir),
57-
cls._get_readme(fetcher, project_dir),
58-
- packaging.specifiers.SpecifierSet(requires_python_string) if requires_python_string else None,
59-
+ pkg_specifiers.SpecifierSet(requires_python_string) if requires_python_string else None,
60-
cls._get_dependencies(fetcher),
61-
cls._get_optional_dependencies(fetcher),
62-
cls._get_entrypoints(fetcher),
63-
@@ -358,15 +358,15 @@ class StandardMetadata:
86+
@@ -608,7 +608,7 @@ class StandardMetadata:
87+
fetcher.get_license(project_dir),
88+
fetcher.get_license_files(project_dir),
89+
fetcher.get_readme(project_dir),
90+
- packaging.specifiers.SpecifierSet(requires_python_string)
91+
+ pkg_specifiers.SpecifierSet(requires_python_string)
92+
if requires_python_string
93+
else None,
94+
fetcher.get_dependencies(),
95+
@@ -720,15 +720,15 @@ class StandardMetadata:
6496
requirement = copy.copy(requirement)
6597
if requirement.marker:
6698
if 'or' in requirement.marker._markers:
@@ -78,26 +110,4 @@ index df826f8..7f69f3a 100644
78110
+ requirement.marker = pkg_markers.Marker(f'extra == "{extra}"')
79111
return requirement
80112

81-
@staticmethod
82-
@@ -462,8 +462,8 @@ class StandardMetadata:
83-
requirements: list[Requirement] = []
84-
for req in requirement_strings:
85-
try:
86-
- requirements.append(packaging.requirements.Requirement(req))
87-
- except packaging.requirements.InvalidRequirement as e:
88-
+ requirements.append(pkg_requirements.Requirement(req))
89-
+ except pkg_requirements.InvalidRequirement as e:
90-
msg = (
91-
'Field "project.dependencies" contains an invalid PEP 508 '
92-
f'requirement string "{req}" ("{e}")'
93-
@@ -502,8 +502,8 @@ class StandardMetadata:
94-
)
95-
raise ConfigurationError(msg)
96-
try:
97-
- requirements_dict[extra].append(packaging.requirements.Requirement(req))
98-
- except packaging.requirements.InvalidRequirement as e:
99-
+ requirements_dict[extra].append(pkg_requirements.Requirement(req))
100-
+ except pkg_requirements.InvalidRequirement as e:
101-
msg = (
102-
f'Field "project.optional-dependencies.{extra}" contains '
103-
f'an invalid PEP 508 requirement string "{req}" ("{e}")'
113+

src/pdm/backend/_vendor/packaging/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
__summary__ = "Core utilities for Python packages"
77
__uri__ = "https://github.com/pypa/packaging"
88

9-
__version__ = "24.0"
9+
__version__ = "24.1"
1010

1111
__author__ = "Donald Stufft and individual contributors"
1212
__email__ = "donald@stufft.io"

src/pdm/backend/_vendor/packaging/_elffile.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html
99
"""
1010

11+
from __future__ import annotations
12+
1113
import enum
1214
import os
1315
import struct
14-
from typing import IO, Optional, Tuple
16+
from typing import IO
1517

1618

1719
class ELFInvalid(ValueError):
@@ -87,11 +89,11 @@ def __init__(self, f: IO[bytes]) -> None:
8789
except struct.error as e:
8890
raise ELFInvalid("unable to parse machine and section information") from e
8991

90-
def _read(self, fmt: str) -> Tuple[int, ...]:
92+
def _read(self, fmt: str) -> tuple[int, ...]:
9193
return struct.unpack(fmt, self._f.read(struct.calcsize(fmt)))
9294

9395
@property
94-
def interpreter(self) -> Optional[str]:
96+
def interpreter(self) -> str | None:
9597
"""
9698
The path recorded in the ``PT_INTERP`` section header.
9799
"""

src/pdm/backend/_vendor/packaging/_manylinux.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
from __future__ import annotations
2+
13
import collections
24
import contextlib
35
import functools
46
import os
57
import re
68
import sys
79
import warnings
8-
from typing import Dict, Generator, Iterator, NamedTuple, Optional, Sequence, Tuple
10+
from typing import Generator, Iterator, NamedTuple, Sequence
911

1012
from ._elffile import EIClass, EIData, ELFFile, EMachine
1113

@@ -17,7 +19,7 @@
1719
# `os.PathLike` not a generic type until Python 3.9, so sticking with `str`
1820
# as the type for `path` until then.
1921
@contextlib.contextmanager
20-
def _parse_elf(path: str) -> Generator[Optional[ELFFile], None, None]:
22+
def _parse_elf(path: str) -> Generator[ELFFile | None, None, None]:
2123
try:
2224
with open(path, "rb") as f:
2325
yield ELFFile(f)
@@ -72,15 +74,15 @@ def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool:
7274
# For now, guess what the highest minor version might be, assume it will
7375
# be 50 for testing. Once this actually happens, update the dictionary
7476
# with the actual value.
75-
_LAST_GLIBC_MINOR: Dict[int, int] = collections.defaultdict(lambda: 50)
77+
_LAST_GLIBC_MINOR: dict[int, int] = collections.defaultdict(lambda: 50)
7678

7779

7880
class _GLibCVersion(NamedTuple):
7981
major: int
8082
minor: int
8183

8284

83-
def _glibc_version_string_confstr() -> Optional[str]:
85+
def _glibc_version_string_confstr() -> str | None:
8486
"""
8587
Primary implementation of glibc_version_string using os.confstr.
8688
"""
@@ -90,7 +92,7 @@ def _glibc_version_string_confstr() -> Optional[str]:
9092
# https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
9193
try:
9294
# Should be a string like "glibc 2.17".
93-
version_string: Optional[str] = os.confstr("CS_GNU_LIBC_VERSION")
95+
version_string: str | None = os.confstr("CS_GNU_LIBC_VERSION")
9496
assert version_string is not None
9597
_, version = version_string.rsplit()
9698
except (AssertionError, AttributeError, OSError, ValueError):
@@ -99,7 +101,7 @@ def _glibc_version_string_confstr() -> Optional[str]:
99101
return version
100102

101103

102-
def _glibc_version_string_ctypes() -> Optional[str]:
104+
def _glibc_version_string_ctypes() -> str | None:
103105
"""
104106
Fallback implementation of glibc_version_string using ctypes.
105107
"""
@@ -143,12 +145,12 @@ def _glibc_version_string_ctypes() -> Optional[str]:
143145
return version_str
144146

145147

146-
def _glibc_version_string() -> Optional[str]:
148+
def _glibc_version_string() -> str | None:
147149
"""Returns glibc version string, or None if not using glibc."""
148150
return _glibc_version_string_confstr() or _glibc_version_string_ctypes()
149151

150152

151-
def _parse_glibc_version(version_str: str) -> Tuple[int, int]:
153+
def _parse_glibc_version(version_str: str) -> tuple[int, int]:
152154
"""Parse glibc version.
153155
154156
We use a regexp instead of str.split because we want to discard any
@@ -167,8 +169,8 @@ def _parse_glibc_version(version_str: str) -> Tuple[int, int]:
167169
return int(m.group("major")), int(m.group("minor"))
168170

169171

170-
@functools.lru_cache()
171-
def _get_glibc_version() -> Tuple[int, int]:
172+
@functools.lru_cache
173+
def _get_glibc_version() -> tuple[int, int]:
172174
version_str = _glibc_version_string()
173175
if version_str is None:
174176
return (-1, -1)

src/pdm/backend/_vendor/packaging/_musllinux.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
linked against musl, and what musl version is used.
55
"""
66

7+
from __future__ import annotations
8+
79
import functools
810
import re
911
import subprocess
1012
import sys
11-
from typing import Iterator, NamedTuple, Optional, Sequence
13+
from typing import Iterator, NamedTuple, Sequence
1214

1315
from ._elffile import ELFFile
1416

@@ -18,7 +20,7 @@ class _MuslVersion(NamedTuple):
1820
minor: int
1921

2022

21-
def _parse_musl_version(output: str) -> Optional[_MuslVersion]:
23+
def _parse_musl_version(output: str) -> _MuslVersion | None:
2224
lines = [n for n in (n.strip() for n in output.splitlines()) if n]
2325
if len(lines) < 2 or lines[0][:4] != "musl":
2426
return None
@@ -28,8 +30,8 @@ def _parse_musl_version(output: str) -> Optional[_MuslVersion]:
2830
return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2)))
2931

3032

31-
@functools.lru_cache()
32-
def _get_musl_version(executable: str) -> Optional[_MuslVersion]:
33+
@functools.lru_cache
34+
def _get_musl_version(executable: str) -> _MuslVersion | None:
3335
"""Detect currently-running musl runtime version.
3436
3537
This is done by checking the specified executable's dynamic linking

0 commit comments

Comments
 (0)