Skip to content

Commit 92921a0

Browse files
committed
Updated vendored packaging to 24.0
1 parent a9119c8 commit 92921a0

File tree

14 files changed

+95
-68
lines changed

14 files changed

+95
-68
lines changed

docs/news.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Release Notes
44
**UNRELEASED**
55

66
- Dropped support for Python 3.7
7+
- Updated vendored ``packaging`` to 24.0
78

89
**0.42.0 (2023-11-26)**
910

src/wheel/bdist_wheel.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,9 @@ def run(self):
412412
)
413413

414414
self.set_undefined_options("install_egg_info", ("target", "egginfo_dir"))
415-
distinfo_dirname = "{}-{}.dist-info".format(
416-
safer_name(self.distribution.get_name()),
417-
safer_version(self.distribution.get_version()),
415+
distinfo_dirname = (
416+
f"{safer_name(self.distribution.get_name())}-"
417+
f"{safer_version(self.distribution.get_version())}.dist-info"
418418
)
419419
distinfo_dir = os.path.join(self.bdist_dir, distinfo_dirname)
420420
self.egg2dist(self.egginfo_dir, distinfo_dir)

src/wheel/cli/pack.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ def pack(directory: str, dest_dir: str, build_number: str | None) -> None:
4545

4646
if not tags:
4747
raise WheelError(
48-
"No tags present in {}/WHEEL; cannot determine target wheel "
49-
"filename".format(dist_info_dir)
48+
f"No tags present in {dist_info_dir}/WHEEL; cannot determine target "
49+
f"wheel filename"
5050
)
5151

5252
# Set the wheel file name and add/replace/remove the Build tag in .dist-info/WHEEL

src/wheel/metadata.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Tools for converting old- to new-style metadata.
33
"""
4+
45
from __future__ import annotations
56

67
import functools

src/wheel/vendored/packaging/_manylinux.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool:
5555
return _is_linux_armhf(executable)
5656
if "i686" in archs:
5757
return _is_linux_i686(executable)
58-
allowed_archs = {"x86_64", "aarch64", "ppc64", "ppc64le", "s390x", "loongarch64"}
58+
allowed_archs = {
59+
"x86_64",
60+
"aarch64",
61+
"ppc64",
62+
"ppc64le",
63+
"s390x",
64+
"loongarch64",
65+
"riscv64",
66+
}
5967
return any(arch in allowed_archs for arch in archs)
6068

6169

@@ -82,7 +90,7 @@ def _glibc_version_string_confstr() -> Optional[str]:
8290
# https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
8391
try:
8492
# Should be a string like "glibc 2.17".
85-
version_string: str = getattr(os, "confstr")("CS_GNU_LIBC_VERSION")
93+
version_string: Optional[str] = os.confstr("CS_GNU_LIBC_VERSION")
8694
assert version_string is not None
8795
_, version = version_string.rsplit()
8896
except (AssertionError, AttributeError, OSError, ValueError):
@@ -159,7 +167,7 @@ def _parse_glibc_version(version_str: str) -> Tuple[int, int]:
159167
return int(m.group("major")), int(m.group("minor"))
160168

161169

162-
@functools.lru_cache()
170+
@functools.lru_cache
163171
def _get_glibc_version() -> Tuple[int, int]:
164172
version_str = _glibc_version_string()
165173
if version_str is None:
@@ -174,7 +182,7 @@ def _is_compatible(arch: str, version: _GLibCVersion) -> bool:
174182
return False
175183
# Check for presence of _manylinux module.
176184
try:
177-
import _manylinux # noqa
185+
import _manylinux
178186
except ImportError:
179187
return True
180188
if hasattr(_manylinux, "manylinux_compatible"):

src/wheel/vendored/packaging/_musllinux.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def _parse_musl_version(output: str) -> Optional[_MuslVersion]:
2828
return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2)))
2929

3030

31-
@functools.lru_cache()
31+
@functools.lru_cache
3232
def _get_musl_version(executable: str) -> Optional[_MuslVersion]:
3333
"""Detect currently-running musl runtime version.
3434

src/wheel/vendored/packaging/_parser.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Handwritten parser of dependency specifiers.
22
3-
The docstring for each __parse_* function contains ENBF-inspired grammar representing
3+
The docstring for each __parse_* function contains EBNF-inspired grammar representing
44
the implementation.
55
"""
66

@@ -324,10 +324,7 @@ def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar:
324324

325325

326326
def process_env_var(env_var: str) -> Variable:
327-
if (
328-
env_var == "platform_python_implementation"
329-
or env_var == "python_implementation"
330-
):
327+
if env_var in ("platform_python_implementation", "python_implementation"):
331328
return Variable("platform_python_implementation")
332329
else:
333330
return Variable(env_var)

src/wheel/vendored/packaging/markers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
Op,
1515
Value,
1616
Variable,
17+
)
18+
from ._parser import (
1719
parse_marker as _parse_marker,
1820
)
1921
from ._tokenizer import ParserSyntaxError
@@ -69,7 +71,6 @@ def _normalize_extra_values(results: Any) -> Any:
6971
def _format_marker(
7072
marker: Union[List[str], MarkerAtom, str], first: Optional[bool] = True
7173
) -> str:
72-
7374
assert isinstance(marker, (list, tuple, str))
7475

7576
# Sometimes we have a structure like [[...]] which is a single item list

src/wheel/vendored/packaging/requirements.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def __init__(self, requirement_string: str) -> None:
3838

3939
self.name: str = parsed.name
4040
self.url: Optional[str] = parsed.url or None
41-
self.extras: Set[str] = set(parsed.extras if parsed.extras else [])
41+
self.extras: Set[str] = set(parsed.extras or [])
4242
self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)
4343
self.marker: Optional[Marker] = None
4444
if parsed.marker is not None:

src/wheel/vendored/packaging/specifiers.py

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,7 @@
1111
import abc
1212
import itertools
1313
import re
14-
from typing import (
15-
Callable,
16-
Iterable,
17-
Iterator,
18-
List,
19-
Optional,
20-
Set,
21-
Tuple,
22-
TypeVar,
23-
Union,
24-
)
14+
from typing import Callable, Iterable, Iterator, List, Optional, Tuple, TypeVar, Union
2515

2616
from .utils import canonicalize_version
2717
from .version import Version
@@ -374,7 +364,6 @@ def _get_operator(self, op: str) -> CallableOperator:
374364
return operator_callable
375365

376366
def _compare_compatible(self, prospective: Version, spec: str) -> bool:
377-
378367
# Compatible releases have an equivalent combination of >= and ==. That
379368
# is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
380369
# implement this in terms of the other specifiers instead of
@@ -383,7 +372,7 @@ def _compare_compatible(self, prospective: Version, spec: str) -> bool:
383372

384373
# We want everything but the last item in the version, but we want to
385374
# ignore suffix segments.
386-
prefix = ".".join(
375+
prefix = _version_join(
387376
list(itertools.takewhile(_is_not_suffix, _version_split(spec)))[:-1]
388377
)
389378

@@ -395,7 +384,6 @@ def _compare_compatible(self, prospective: Version, spec: str) -> bool:
395384
)
396385

397386
def _compare_equal(self, prospective: Version, spec: str) -> bool:
398-
399387
# We need special logic to handle prefix matching
400388
if spec.endswith(".*"):
401389
# In the case of prefix matching we want to ignore local segment.
@@ -404,13 +392,13 @@ def _compare_equal(self, prospective: Version, spec: str) -> bool:
404392
)
405393
# Get the normalized version string ignoring the trailing .*
406394
normalized_spec = canonicalize_version(spec[:-2], strip_trailing_zero=False)
407-
# Split the spec out by dots, and pretend that there is an implicit
408-
# dot in between a release segment and a pre-release segment.
395+
# Split the spec out by bangs and dots, and pretend that there is
396+
# an implicit dot in between a release segment and a pre-release segment.
409397
split_spec = _version_split(normalized_spec)
410398

411-
# Split the prospective version out by dots, and pretend that there
412-
# is an implicit dot in between a release segment and a pre-release
413-
# segment.
399+
# Split the prospective version out by bangs and dots, and pretend
400+
# that there is an implicit dot in between a release segment and
401+
# a pre-release segment.
414402
split_prospective = _version_split(normalized_prospective)
415403

416404
# 0-pad the prospective version before shortening it to get the correct
@@ -439,21 +427,18 @@ def _compare_not_equal(self, prospective: Version, spec: str) -> bool:
439427
return not self._compare_equal(prospective, spec)
440428

441429
def _compare_less_than_equal(self, prospective: Version, spec: str) -> bool:
442-
443430
# NB: Local version identifiers are NOT permitted in the version
444431
# specifier, so local version labels can be universally removed from
445432
# the prospective version.
446433
return Version(prospective.public) <= Version(spec)
447434

448435
def _compare_greater_than_equal(self, prospective: Version, spec: str) -> bool:
449-
450436
# NB: Local version identifiers are NOT permitted in the version
451437
# specifier, so local version labels can be universally removed from
452438
# the prospective version.
453439
return Version(prospective.public) >= Version(spec)
454440

455441
def _compare_less_than(self, prospective: Version, spec_str: str) -> bool:
456-
457442
# Convert our spec to a Version instance, since we'll want to work with
458443
# it as a version.
459444
spec = Version(spec_str)
@@ -478,7 +463,6 @@ def _compare_less_than(self, prospective: Version, spec_str: str) -> bool:
478463
return True
479464

480465
def _compare_greater_than(self, prospective: Version, spec_str: str) -> bool:
481-
482466
# Convert our spec to a Version instance, since we'll want to work with
483467
# it as a version.
484468
spec = Version(spec_str)
@@ -644,8 +628,19 @@ def filter(
644628

645629

646630
def _version_split(version: str) -> List[str]:
631+
"""Split version into components.
632+
633+
The split components are intended for version comparison. The logic does
634+
not attempt to retain the original version string, so joining the
635+
components back with :func:`_version_join` may not produce the original
636+
version string.
637+
"""
647638
result: List[str] = []
648-
for item in version.split("."):
639+
640+
epoch, _, rest = version.rpartition("!")
641+
result.append(epoch or "0")
642+
643+
for item in rest.split("."):
649644
match = _prefix_regex.search(item)
650645
if match:
651646
result.extend(match.groups())
@@ -654,6 +649,17 @@ def _version_split(version: str) -> List[str]:
654649
return result
655650

656651

652+
def _version_join(components: List[str]) -> str:
653+
"""Join split version components into a version string.
654+
655+
This function assumes the input came from :func:`_version_split`, where the
656+
first component must be the epoch (either empty or numeric), and all other
657+
components numeric.
658+
"""
659+
epoch, *rest = components
660+
return f"{epoch}!{'.'.join(rest)}"
661+
662+
657663
def _is_not_suffix(segment: str) -> bool:
658664
return not any(
659665
segment.startswith(prefix) for prefix in ("dev", "a", "b", "rc", "post")
@@ -675,7 +681,10 @@ def _pad_version(left: List[str], right: List[str]) -> Tuple[List[str], List[str
675681
left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
676682
right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
677683

678-
return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split)))
684+
return (
685+
list(itertools.chain.from_iterable(left_split)),
686+
list(itertools.chain.from_iterable(right_split)),
687+
)
679688

680689

681690
class SpecifierSet(BaseSpecifier):
@@ -707,14 +716,8 @@ def __init__(
707716
# strip each item to remove leading/trailing whitespace.
708717
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
709718

710-
# Parsed each individual specifier, attempting first to make it a
711-
# Specifier.
712-
parsed: Set[Specifier] = set()
713-
for specifier in split_specifiers:
714-
parsed.add(Specifier(specifier))
715-
716-
# Turn our parsed specifiers into a frozen set and save them for later.
717-
self._specs = frozenset(parsed)
719+
# Make each individual specifier a Specifier and save in a frozen set for later.
720+
self._specs = frozenset(map(Specifier, split_specifiers))
718721

719722
# Store our prereleases value so we can use it later to determine if
720723
# we accept prereleases or not.

src/wheel/vendored/packaging/tags.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import logging
66
import platform
7+
import re
78
import struct
89
import subprocess
910
import sys
@@ -124,20 +125,37 @@ def _normalize_string(string: str) -> str:
124125
return string.replace(".", "_").replace("-", "_").replace(" ", "_")
125126

126127

127-
def _abi3_applies(python_version: PythonVersion) -> bool:
128+
def _is_threaded_cpython(abis: List[str]) -> bool:
129+
"""
130+
Determine if the ABI corresponds to a threaded (`--disable-gil`) build.
131+
132+
The threaded builds are indicated by a "t" in the abiflags.
133+
"""
134+
if len(abis) == 0:
135+
return False
136+
# expect e.g., cp313
137+
m = re.match(r"cp\d+(.*)", abis[0])
138+
if not m:
139+
return False
140+
abiflags = m.group(1)
141+
return "t" in abiflags
142+
143+
144+
def _abi3_applies(python_version: PythonVersion, threading: bool) -> bool:
128145
"""
129146
Determine if the Python version supports abi3.
130147
131-
PEP 384 was first implemented in Python 3.2.
148+
PEP 384 was first implemented in Python 3.2. The threaded (`--disable-gil`)
149+
builds do not support abi3.
132150
"""
133-
return len(python_version) > 1 and tuple(python_version) >= (3, 2)
151+
return len(python_version) > 1 and tuple(python_version) >= (3, 2) and not threading
134152

135153

136154
def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]:
137155
py_version = tuple(py_version) # To allow for version comparison.
138156
abis = []
139157
version = _version_nodot(py_version[:2])
140-
debug = pymalloc = ucs4 = ""
158+
threading = debug = pymalloc = ucs4 = ""
141159
with_debug = _get_config_var("Py_DEBUG", warn)
142160
has_refcount = hasattr(sys, "gettotalrefcount")
143161
# Windows doesn't set Py_DEBUG, so checking for support of debug-compiled
@@ -146,6 +164,8 @@ def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]:
146164
has_ext = "_d.pyd" in EXTENSION_SUFFIXES
147165
if with_debug or (with_debug is None and (has_refcount or has_ext)):
148166
debug = "d"
167+
if py_version >= (3, 13) and _get_config_var("Py_GIL_DISABLED", warn):
168+
threading = "t"
149169
if py_version < (3, 8):
150170
with_pymalloc = _get_config_var("WITH_PYMALLOC", warn)
151171
if with_pymalloc or with_pymalloc is None:
@@ -159,13 +179,8 @@ def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]:
159179
elif debug:
160180
# Debug builds can also load "normal" extension modules.
161181
# We can also assume no UCS-4 or pymalloc requirement.
162-
abis.append(f"cp{version}")
163-
abis.insert(
164-
0,
165-
"cp{version}{debug}{pymalloc}{ucs4}".format(
166-
version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4
167-
),
168-
)
182+
abis.append(f"cp{version}{threading}")
183+
abis.insert(0, f"cp{version}{threading}{debug}{pymalloc}{ucs4}")
169184
return abis
170185

171186

@@ -213,11 +228,14 @@ def cpython_tags(
213228
for abi in abis:
214229
for platform_ in platforms:
215230
yield Tag(interpreter, abi, platform_)
216-
if _abi3_applies(python_version):
231+
232+
threading = _is_threaded_cpython(abis)
233+
use_abi3 = _abi3_applies(python_version, threading)
234+
if use_abi3:
217235
yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms)
218236
yield from (Tag(interpreter, "none", platform_) for platform_ in platforms)
219237

220-
if _abi3_applies(python_version):
238+
if use_abi3:
221239
for minor_version in range(python_version[1] - 1, 1, -1):
222240
for platform_ in platforms:
223241
interpreter = "cp{version}".format(

0 commit comments

Comments
 (0)