Skip to content

Commit 8183604

Browse files
committed
feat(vendor): update packaging to 24.0
Signed-off-by: Frost Ming <me@frostming.com>
1 parent 6b2601e commit 8183604

File tree

16 files changed

+1201
-233
lines changed

16 files changed

+1201
-233
lines changed

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

Lines changed: 0 additions & 26 deletions
This file was deleted.

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

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,14 @@
22
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
33
# for complete details.
44

5-
from .__about__ import (
6-
__author__,
7-
__copyright__,
8-
__email__,
9-
__license__,
10-
__summary__,
11-
__title__,
12-
__uri__,
13-
__version__,
14-
)
5+
__title__ = "packaging"
6+
__summary__ = "Core utilities for Python packages"
7+
__uri__ = "https://github.com/pypa/packaging"
158

16-
__all__ = [
17-
"__title__",
18-
"__summary__",
19-
"__uri__",
20-
"__version__",
21-
"__author__",
22-
"__email__",
23-
"__license__",
24-
"__copyright__",
25-
]
9+
__version__ = "24.0"
10+
11+
__author__ = "Donald Stufft and individual contributors"
12+
__email__ = "donald@stufft.io"
13+
14+
__license__ = "BSD-2-Clause or Apache-2.0"
15+
__copyright__ = "2014 %s" % __author__

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def __init__(self, f: IO[bytes]) -> None:
5353
raise ELFInvalid(f"invalid magic: {magic!r}")
5454

5555
self.capacity = ident[4] # Format for program header (bitness).
56-
self.encoding = ident[5] # Data structure encoding (endianess).
56+
self.encoding = ident[5] # Data structure encoding (endianness).
5757

5858
try:
5959
# e_fmt: Format for program header.

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

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import re
66
import sys
77
import warnings
8-
from typing import Dict, Generator, Iterator, NamedTuple, Optional, Tuple
8+
from typing import Dict, Generator, Iterator, NamedTuple, Optional, Sequence, Tuple
99

1010
from ._elffile import EIClass, EIData, ELFFile, EMachine
1111

@@ -14,6 +14,8 @@
1414
EF_ARM_ABI_FLOAT_HARD = 0x00000400
1515

1616

17+
# `os.PathLike` not a generic type until Python 3.9, so sticking with `str`
18+
# as the type for `path` until then.
1719
@contextlib.contextmanager
1820
def _parse_elf(path: str) -> Generator[Optional[ELFFile], None, None]:
1921
try:
@@ -48,12 +50,21 @@ def _is_linux_i686(executable: str) -> bool:
4850
)
4951

5052

51-
def _have_compatible_abi(executable: str, arch: str) -> bool:
52-
if arch == "armv7l":
53+
def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool:
54+
if "armv7l" in archs:
5355
return _is_linux_armhf(executable)
54-
if arch == "i686":
56+
if "i686" in archs:
5557
return _is_linux_i686(executable)
56-
return arch in {"x86_64", "aarch64", "ppc64", "ppc64le", "s390x"}
58+
allowed_archs = {
59+
"x86_64",
60+
"aarch64",
61+
"ppc64",
62+
"ppc64le",
63+
"s390x",
64+
"loongarch64",
65+
"riscv64",
66+
}
67+
return any(arch in allowed_archs for arch in archs)
5768

5869

5970
# If glibc ever changes its major version, we need to know what the last
@@ -79,7 +90,7 @@ def _glibc_version_string_confstr() -> Optional[str]:
7990
# https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
8091
try:
8192
# Should be a string like "glibc 2.17".
82-
version_string: str = getattr(os, "confstr")("CS_GNU_LIBC_VERSION")
93+
version_string: Optional[str] = os.confstr("CS_GNU_LIBC_VERSION")
8394
assert version_string is not None
8495
_, version = version_string.rsplit()
8596
except (AssertionError, AttributeError, OSError, ValueError):
@@ -165,13 +176,13 @@ def _get_glibc_version() -> Tuple[int, int]:
165176

166177

167178
# From PEP 513, PEP 600
168-
def _is_compatible(name: str, arch: str, version: _GLibCVersion) -> bool:
179+
def _is_compatible(arch: str, version: _GLibCVersion) -> bool:
169180
sys_glibc = _get_glibc_version()
170181
if sys_glibc < version:
171182
return False
172183
# Check for presence of _manylinux module.
173184
try:
174-
import _manylinux # noqa
185+
import _manylinux
175186
except ImportError:
176187
return True
177188
if hasattr(_manylinux, "manylinux_compatible"):
@@ -201,12 +212,22 @@ def _is_compatible(name: str, arch: str, version: _GLibCVersion) -> bool:
201212
}
202213

203214

204-
def platform_tags(linux: str, arch: str) -> Iterator[str]:
205-
if not _have_compatible_abi(sys.executable, arch):
215+
def platform_tags(archs: Sequence[str]) -> Iterator[str]:
216+
"""Generate manylinux tags compatible to the current platform.
217+
218+
:param archs: Sequence of compatible architectures.
219+
The first one shall be the closest to the actual architecture and be the part of
220+
platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
221+
The ``linux_`` prefix is assumed as a prerequisite for the current platform to
222+
be manylinux-compatible.
223+
224+
:returns: An iterator of compatible manylinux tags.
225+
"""
226+
if not _have_compatible_abi(sys.executable, archs):
206227
return
207228
# Oldest glibc to be supported regardless of architecture is (2, 17).
208229
too_old_glibc2 = _GLibCVersion(2, 16)
209-
if arch in {"x86_64", "i686"}:
230+
if set(archs) & {"x86_64", "i686"}:
210231
# On x86/i686 also oldest glibc to be supported is (2, 5).
211232
too_old_glibc2 = _GLibCVersion(2, 4)
212233
current_glibc = _GLibCVersion(*_get_glibc_version())
@@ -220,19 +241,20 @@ def platform_tags(linux: str, arch: str) -> Iterator[str]:
220241
for glibc_major in range(current_glibc.major - 1, 1, -1):
221242
glibc_minor = _LAST_GLIBC_MINOR[glibc_major]
222243
glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor))
223-
for glibc_max in glibc_max_list:
224-
if glibc_max.major == too_old_glibc2.major:
225-
min_minor = too_old_glibc2.minor
226-
else:
227-
# For other glibc major versions oldest supported is (x, 0).
228-
min_minor = -1
229-
for glibc_minor in range(glibc_max.minor, min_minor, -1):
230-
glibc_version = _GLibCVersion(glibc_max.major, glibc_minor)
231-
tag = "manylinux_{}_{}".format(*glibc_version)
232-
if _is_compatible(tag, arch, glibc_version):
233-
yield linux.replace("linux", tag)
234-
# Handle the legacy manylinux1, manylinux2010, manylinux2014 tags.
235-
if glibc_version in _LEGACY_MANYLINUX_MAP:
236-
legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version]
237-
if _is_compatible(legacy_tag, arch, glibc_version):
238-
yield linux.replace("linux", legacy_tag)
244+
for arch in archs:
245+
for glibc_max in glibc_max_list:
246+
if glibc_max.major == too_old_glibc2.major:
247+
min_minor = too_old_glibc2.minor
248+
else:
249+
# For other glibc major versions oldest supported is (x, 0).
250+
min_minor = -1
251+
for glibc_minor in range(glibc_max.minor, min_minor, -1):
252+
glibc_version = _GLibCVersion(glibc_max.major, glibc_minor)
253+
tag = "manylinux_{}_{}".format(*glibc_version)
254+
if _is_compatible(arch, glibc_version):
255+
yield f"{tag}_{arch}"
256+
# Handle the legacy manylinux1, manylinux2010, manylinux2014 tags.
257+
if glibc_version in _LEGACY_MANYLINUX_MAP:
258+
legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version]
259+
if _is_compatible(arch, glibc_version):
260+
yield f"{legacy_tag}_{arch}"

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import re
99
import subprocess
1010
import sys
11-
from typing import Iterator, NamedTuple, Optional
11+
from typing import Iterator, NamedTuple, Optional, Sequence
1212

1313
from ._elffile import ELFFile
1414

@@ -47,24 +47,27 @@ def _get_musl_version(executable: str) -> Optional[_MuslVersion]:
4747
return None
4848
if ld is None or "musl" not in ld:
4949
return None
50-
proc = subprocess.run([ld], stderr=subprocess.PIPE, universal_newlines=True)
50+
proc = subprocess.run([ld], stderr=subprocess.PIPE, text=True)
5151
return _parse_musl_version(proc.stderr)
5252

5353

54-
def platform_tags(arch: str) -> Iterator[str]:
54+
def platform_tags(archs: Sequence[str]) -> Iterator[str]:
5555
"""Generate musllinux tags compatible to the current platform.
5656
57-
:param arch: Should be the part of platform tag after the ``linux_``
58-
prefix, e.g. ``x86_64``. The ``linux_`` prefix is assumed as a
59-
prerequisite for the current platform to be musllinux-compatible.
57+
:param archs: Sequence of compatible architectures.
58+
The first one shall be the closest to the actual architecture and be the part of
59+
platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
60+
The ``linux_`` prefix is assumed as a prerequisite for the current platform to
61+
be musllinux-compatible.
6062
6163
:returns: An iterator of compatible musllinux tags.
6264
"""
6365
sys_musl = _get_musl_version(sys.executable)
6466
if sys_musl is None: # Python not dynamically linked against musl.
6567
return
66-
for minor in range(sys_musl.minor, -1, -1):
67-
yield f"musllinux_{sys_musl.major}_{minor}_{arch}"
68+
for arch in archs:
69+
for minor in range(sys_musl.minor, -1, -1):
70+
yield f"musllinux_{sys_musl.major}_{minor}_{arch}"
6871

6972

7073
if __name__ == "__main__": # pragma: no cover

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

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def serialize(self) -> str:
4343
MarkerItem = Tuple[MarkerVar, Op, MarkerVar]
4444
# MarkerAtom = Union[MarkerItem, List["MarkerAtom"]]
4545
# MarkerList = List[Union["MarkerList", MarkerAtom, str]]
46-
# mypy does not suport recursive type definition
46+
# mypy does not support recursive type definition
4747
# https://github.com/python/mypy/issues/731
4848
MarkerAtom = Any
4949
MarkerList = List[Any]
@@ -89,7 +89,7 @@ def _parse_requirement_details(
8989
tokenizer: Tokenizer,
9090
) -> Tuple[str, str, Optional[MarkerList]]:
9191
"""
92-
requirement_details = AT URL (WS requirement_marker)?
92+
requirement_details = AT URL (WS requirement_marker?)?
9393
| specifier WS? (requirement_marker)?
9494
"""
9595

@@ -108,6 +108,10 @@ def _parse_requirement_details(
108108

109109
tokenizer.expect("WS", expected="whitespace after URL")
110110

111+
# The input might end after whitespace.
112+
if tokenizer.check("END", peek=True):
113+
return (url, specifier, marker)
114+
111115
marker = _parse_requirement_marker(
112116
tokenizer, span_start=url_start, after="URL and whitespace"
113117
)
@@ -144,8 +148,7 @@ def _parse_requirement_marker(
144148
f"Expected end or semicolon (after {after})",
145149
span_start=span_start,
146150
)
147-
else:
148-
tokenizer.read()
151+
tokenizer.read()
149152

150153
marker = _parse_marker(tokenizer)
151154
tokenizer.consume("WS")
@@ -160,7 +163,11 @@ def _parse_extras(tokenizer: Tokenizer) -> List[str]:
160163
if not tokenizer.check("LEFT_BRACKET", peek=True):
161164
return []
162165

163-
with tokenizer.enclosing_tokens("LEFT_BRACKET", "RIGHT_BRACKET"):
166+
with tokenizer.enclosing_tokens(
167+
"LEFT_BRACKET",
168+
"RIGHT_BRACKET",
169+
around="extras",
170+
):
164171
tokenizer.consume("WS")
165172
extras = _parse_extras_list(tokenizer)
166173
tokenizer.consume("WS")
@@ -200,7 +207,11 @@ def _parse_specifier(tokenizer: Tokenizer) -> str:
200207
specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS
201208
| WS? version_many WS?
202209
"""
203-
with tokenizer.enclosing_tokens("LEFT_PARENTHESIS", "RIGHT_PARENTHESIS"):
210+
with tokenizer.enclosing_tokens(
211+
"LEFT_PARENTHESIS",
212+
"RIGHT_PARENTHESIS",
213+
around="version specifier",
214+
):
204215
tokenizer.consume("WS")
205216
parsed_specifiers = _parse_version_many(tokenizer)
206217
tokenizer.consume("WS")
@@ -210,20 +221,25 @@ def _parse_specifier(tokenizer: Tokenizer) -> str:
210221

211222
def _parse_version_many(tokenizer: Tokenizer) -> str:
212223
"""
213-
version_many = (OP VERSION (COMMA OP VERSION)*)?
224+
version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)?
214225
"""
215226
parsed_specifiers = ""
216-
while tokenizer.check("OP"):
227+
while tokenizer.check("SPECIFIER"):
228+
span_start = tokenizer.position
217229
parsed_specifiers += tokenizer.read().text
218-
219-
# We intentionally do not consume whitespace here, since the regular expression
220-
# for `VERSION` uses a lookback for the operator, to determine what
221-
# corresponding syntax is permitted.
222-
223-
version_token = tokenizer.expect("VERSION", expected="version after operator")
224-
parsed_specifiers += version_token.text
230+
if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True):
231+
tokenizer.raise_syntax_error(
232+
".* suffix can only be used with `==` or `!=` operators",
233+
span_start=span_start,
234+
span_end=tokenizer.position + 1,
235+
)
236+
if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True):
237+
tokenizer.raise_syntax_error(
238+
"Local version label can only be used with `==` or `!=` operators",
239+
span_start=span_start,
240+
span_end=tokenizer.position,
241+
)
225242
tokenizer.consume("WS")
226-
227243
if not tokenizer.check("COMMA"):
228244
break
229245
parsed_specifiers += tokenizer.read().text
@@ -236,7 +252,13 @@ def _parse_version_many(tokenizer: Tokenizer) -> str:
236252
# Recursive descent parser for marker expression
237253
# --------------------------------------------------------------------------------------
238254
def parse_marker(source: str) -> MarkerList:
239-
return _parse_marker(Tokenizer(source, rules=DEFAULT_RULES))
255+
return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES))
256+
257+
258+
def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList:
259+
retval = _parse_marker(tokenizer)
260+
tokenizer.expect("END", expected="end of marker expression")
261+
return retval
240262

241263

242264
def _parse_marker(tokenizer: Tokenizer) -> MarkerList:
@@ -259,7 +281,11 @@ def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom:
259281

260282
tokenizer.consume("WS")
261283
if tokenizer.check("LEFT_PARENTHESIS", peek=True):
262-
with tokenizer.enclosing_tokens("LEFT_PARENTHESIS", "RIGHT_PARENTHESIS"):
284+
with tokenizer.enclosing_tokens(
285+
"LEFT_PARENTHESIS",
286+
"RIGHT_PARENTHESIS",
287+
around="marker expression",
288+
):
263289
tokenizer.consume("WS")
264290
marker: MarkerAtom = _parse_marker(tokenizer)
265291
tokenizer.consume("WS")
@@ -298,10 +324,7 @@ def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar:
298324

299325

300326
def process_env_var(env_var: str) -> Variable:
301-
if (
302-
env_var == "platform_python_implementation"
303-
or env_var == "python_implementation"
304-
):
327+
if env_var in ("platform_python_implementation", "python_implementation"):
305328
return Variable("platform_python_implementation")
306329
else:
307330
return Variable(env_var)

0 commit comments

Comments
 (0)