Skip to content

Commit 08ae751

Browse files
sbidoulpradyunsg
authored andcommitted
Upgrade packaging to 24.0
1 parent 8f97eb5 commit 08ae751

File tree

9 files changed

+135
-100
lines changed

9 files changed

+135
-100
lines changed

news/packaging.vendor.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Upgrade packaging to 23.2
1+
Upgrade packaging to 24.0

src/pip/_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__ = "23.2"
9+
__version__ = "24.0"
1010

1111
__author__ = "Donald Stufft and individual contributors"
1212
__email__ = "[email protected]"

src/pip/_vendor/packaging/_manylinux.py

Lines changed: 11 additions & 3 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):
@@ -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/pip/_vendor/packaging/_parser.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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/pip/_vendor/packaging/metadata.py

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ def __init_subclass__(*_args, **_kwargs):
4141

4242

4343
try:
44-
ExceptionGroup = __builtins__.ExceptionGroup # type: ignore[attr-defined]
45-
except AttributeError:
44+
ExceptionGroup
45+
except NameError: # pragma: no cover
4646

47-
class ExceptionGroup(Exception): # type: ignore[no-redef] # noqa: N818
47+
class ExceptionGroup(Exception): # noqa: N818
4848
"""A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11.
4949
5050
If :external:exc:`ExceptionGroup` is already defined by Python itself,
@@ -61,6 +61,9 @@ def __init__(self, message: str, exceptions: List[Exception]) -> None:
6161
def __repr__(self) -> str:
6262
return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})"
6363

64+
else: # pragma: no cover
65+
ExceptionGroup = ExceptionGroup
66+
6467

6568
class InvalidMetadata(ValueError):
6669
"""A metadata field contains invalid data."""
@@ -505,24 +508,19 @@ def __get__(self, instance: "Metadata", _owner: Type["Metadata"]) -> T:
505508
# No need to check the cache as attribute lookup will resolve into the
506509
# instance's __dict__ before __get__ is called.
507510
cache = instance.__dict__
508-
try:
509-
value = instance._raw[self.name] # type: ignore[literal-required]
510-
except KeyError:
511-
if self.name in _STRING_FIELDS:
512-
value = ""
513-
elif self.name in _LIST_FIELDS:
514-
value = []
515-
elif self.name in _DICT_FIELDS:
516-
value = {}
517-
else: # pragma: no cover
518-
assert False
511+
value = instance._raw.get(self.name)
519512

520-
try:
521-
converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}")
522-
except AttributeError:
523-
pass
524-
else:
525-
value = converter(value)
513+
# To make the _process_* methods easier, we'll check if the value is None
514+
# and if this field is NOT a required attribute, and if both of those
515+
# things are true, we'll skip the the converter. This will mean that the
516+
# converters never have to deal with the None union.
517+
if self.name in _REQUIRED_ATTRS or value is not None:
518+
try:
519+
converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}")
520+
except AttributeError:
521+
pass
522+
else:
523+
value = converter(value)
526524

527525
cache[self.name] = value
528526
try:
@@ -677,7 +675,7 @@ def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> "Metadata":
677675
ins._raw = data.copy() # Mutations occur due to caching enriched values.
678676

679677
if validate:
680-
exceptions: List[InvalidMetadata] = []
678+
exceptions: List[Exception] = []
681679
try:
682680
metadata_version = ins.metadata_version
683681
metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version)
@@ -732,10 +730,10 @@ def from_email(
732730
If *validate* is true, the metadata will be validated. All exceptions
733731
related to validation will be gathered and raised as an :class:`ExceptionGroup`.
734732
"""
735-
exceptions: list[InvalidMetadata] = []
736733
raw, unparsed = parse_email(data)
737734

738735
if validate:
736+
exceptions: list[Exception] = []
739737
for unparsed_key in unparsed:
740738
if unparsed_key in _EMAIL_TO_RAW_MAPPING:
741739
message = f"{unparsed_key!r} has invalid data"
@@ -749,8 +747,9 @@ def from_email(
749747
try:
750748
return cls.from_raw(raw, validate=validate)
751749
except ExceptionGroup as exc_group:
752-
exceptions.extend(exc_group.exceptions)
753-
raise ExceptionGroup("invalid or unparsed metadata", exceptions) from None
750+
raise ExceptionGroup(
751+
"invalid or unparsed metadata", exc_group.exceptions
752+
) from None
754753

755754
metadata_version: _Validator[_MetadataVersion] = _Validator()
756755
""":external:ref:`core-metadata-metadata-version`
@@ -761,62 +760,66 @@ def from_email(
761760
*validate* parameter)"""
762761
version: _Validator[version_module.Version] = _Validator()
763762
""":external:ref:`core-metadata-version` (required)"""
764-
dynamic: _Validator[List[str]] = _Validator(
763+
dynamic: _Validator[Optional[List[str]]] = _Validator(
765764
added="2.2",
766765
)
767766
""":external:ref:`core-metadata-dynamic`
768767
(validated against core metadata field names and lowercased)"""
769-
platforms: _Validator[List[str]] = _Validator()
768+
platforms: _Validator[Optional[List[str]]] = _Validator()
770769
""":external:ref:`core-metadata-platform`"""
771-
supported_platforms: _Validator[List[str]] = _Validator(added="1.1")
770+
supported_platforms: _Validator[Optional[List[str]]] = _Validator(added="1.1")
772771
""":external:ref:`core-metadata-supported-platform`"""
773-
summary: _Validator[str] = _Validator()
772+
summary: _Validator[Optional[str]] = _Validator()
774773
""":external:ref:`core-metadata-summary` (validated to contain no newlines)"""
775-
description: _Validator[str] = _Validator() # TODO 2.1: can be in body
774+
description: _Validator[Optional[str]] = _Validator() # TODO 2.1: can be in body
776775
""":external:ref:`core-metadata-description`"""
777-
description_content_type: _Validator[str] = _Validator(added="2.1")
776+
description_content_type: _Validator[Optional[str]] = _Validator(added="2.1")
778777
""":external:ref:`core-metadata-description-content-type` (validated)"""
779-
keywords: _Validator[List[str]] = _Validator()
778+
keywords: _Validator[Optional[List[str]]] = _Validator()
780779
""":external:ref:`core-metadata-keywords`"""
781-
home_page: _Validator[str] = _Validator()
780+
home_page: _Validator[Optional[str]] = _Validator()
782781
""":external:ref:`core-metadata-home-page`"""
783-
download_url: _Validator[str] = _Validator(added="1.1")
782+
download_url: _Validator[Optional[str]] = _Validator(added="1.1")
784783
""":external:ref:`core-metadata-download-url`"""
785-
author: _Validator[str] = _Validator()
784+
author: _Validator[Optional[str]] = _Validator()
786785
""":external:ref:`core-metadata-author`"""
787-
author_email: _Validator[str] = _Validator()
786+
author_email: _Validator[Optional[str]] = _Validator()
788787
""":external:ref:`core-metadata-author-email`"""
789-
maintainer: _Validator[str] = _Validator(added="1.2")
788+
maintainer: _Validator[Optional[str]] = _Validator(added="1.2")
790789
""":external:ref:`core-metadata-maintainer`"""
791-
maintainer_email: _Validator[str] = _Validator(added="1.2")
790+
maintainer_email: _Validator[Optional[str]] = _Validator(added="1.2")
792791
""":external:ref:`core-metadata-maintainer-email`"""
793-
license: _Validator[str] = _Validator()
792+
license: _Validator[Optional[str]] = _Validator()
794793
""":external:ref:`core-metadata-license`"""
795-
classifiers: _Validator[List[str]] = _Validator(added="1.1")
794+
classifiers: _Validator[Optional[List[str]]] = _Validator(added="1.1")
796795
""":external:ref:`core-metadata-classifier`"""
797-
requires_dist: _Validator[List[requirements.Requirement]] = _Validator(added="1.2")
796+
requires_dist: _Validator[Optional[List[requirements.Requirement]]] = _Validator(
797+
added="1.2"
798+
)
798799
""":external:ref:`core-metadata-requires-dist`"""
799-
requires_python: _Validator[specifiers.SpecifierSet] = _Validator(added="1.2")
800+
requires_python: _Validator[Optional[specifiers.SpecifierSet]] = _Validator(
801+
added="1.2"
802+
)
800803
""":external:ref:`core-metadata-requires-python`"""
801804
# Because `Requires-External` allows for non-PEP 440 version specifiers, we
802805
# don't do any processing on the values.
803-
requires_external: _Validator[List[str]] = _Validator(added="1.2")
806+
requires_external: _Validator[Optional[List[str]]] = _Validator(added="1.2")
804807
""":external:ref:`core-metadata-requires-external`"""
805-
project_urls: _Validator[Dict[str, str]] = _Validator(added="1.2")
808+
project_urls: _Validator[Optional[Dict[str, str]]] = _Validator(added="1.2")
806809
""":external:ref:`core-metadata-project-url`"""
807810
# PEP 685 lets us raise an error if an extra doesn't pass `Name` validation
808811
# regardless of metadata version.
809-
provides_extra: _Validator[List[utils.NormalizedName]] = _Validator(
812+
provides_extra: _Validator[Optional[List[utils.NormalizedName]]] = _Validator(
810813
added="2.1",
811814
)
812815
""":external:ref:`core-metadata-provides-extra`"""
813-
provides_dist: _Validator[List[str]] = _Validator(added="1.2")
816+
provides_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2")
814817
""":external:ref:`core-metadata-provides-dist`"""
815-
obsoletes_dist: _Validator[List[str]] = _Validator(added="1.2")
818+
obsoletes_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2")
816819
""":external:ref:`core-metadata-obsoletes-dist`"""
817-
requires: _Validator[List[str]] = _Validator(added="1.1")
820+
requires: _Validator[Optional[List[str]]] = _Validator(added="1.1")
818821
"""``Requires`` (deprecated)"""
819-
provides: _Validator[List[str]] = _Validator(added="1.1")
822+
provides: _Validator[Optional[List[str]]] = _Validator(added="1.1")
820823
"""``Provides`` (deprecated)"""
821-
obsoletes: _Validator[List[str]] = _Validator(added="1.1")
824+
obsoletes: _Validator[Optional[List[str]]] = _Validator(added="1.1")
822825
"""``Obsoletes`` (deprecated)"""

src/pip/_vendor/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/pip/_vendor/packaging/specifiers.py

Lines changed: 36 additions & 27 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
@@ -383,7 +373,7 @@ def _compare_compatible(self, prospective: Version, spec: str) -> bool:
383373

384374
# We want everything but the last item in the version, but we want to
385375
# ignore suffix segments.
386-
prefix = ".".join(
376+
prefix = _version_join(
387377
list(itertools.takewhile(_is_not_suffix, _version_split(spec)))[:-1]
388378
)
389379

@@ -404,13 +394,13 @@ def _compare_equal(self, prospective: Version, spec: str) -> bool:
404394
)
405395
# Get the normalized version string ignoring the trailing .*
406396
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.
397+
# Split the spec out by bangs and dots, and pretend that there is
398+
# an implicit dot in between a release segment and a pre-release segment.
409399
split_spec = _version_split(normalized_spec)
410400

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.
401+
# Split the prospective version out by bangs and dots, and pretend
402+
# that there is an implicit dot in between a release segment and
403+
# a pre-release segment.
414404
split_prospective = _version_split(normalized_prospective)
415405

416406
# 0-pad the prospective version before shortening it to get the correct
@@ -644,8 +634,19 @@ def filter(
644634

645635

646636
def _version_split(version: str) -> List[str]:
637+
"""Split version into components.
638+
639+
The split components are intended for version comparison. The logic does
640+
not attempt to retain the original version string, so joining the
641+
components back with :func:`_version_join` may not produce the original
642+
version string.
643+
"""
647644
result: List[str] = []
648-
for item in version.split("."):
645+
646+
epoch, _, rest = version.rpartition("!")
647+
result.append(epoch or "0")
648+
649+
for item in rest.split("."):
649650
match = _prefix_regex.search(item)
650651
if match:
651652
result.extend(match.groups())
@@ -654,6 +655,17 @@ def _version_split(version: str) -> List[str]:
654655
return result
655656

656657

658+
def _version_join(components: List[str]) -> str:
659+
"""Join split version components into a version string.
660+
661+
This function assumes the input came from :func:`_version_split`, where the
662+
first component must be the epoch (either empty or numeric), and all other
663+
components numeric.
664+
"""
665+
epoch, *rest = components
666+
return f"{epoch}!{'.'.join(rest)}"
667+
668+
657669
def _is_not_suffix(segment: str) -> bool:
658670
return not any(
659671
segment.startswith(prefix) for prefix in ("dev", "a", "b", "rc", "post")
@@ -675,7 +687,10 @@ def _pad_version(left: List[str], right: List[str]) -> Tuple[List[str], List[str
675687
left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
676688
right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
677689

678-
return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split)))
690+
return (
691+
list(itertools.chain.from_iterable(left_split)),
692+
list(itertools.chain.from_iterable(right_split)),
693+
)
679694

680695

681696
class SpecifierSet(BaseSpecifier):
@@ -707,14 +722,8 @@ def __init__(
707722
# strip each item to remove leading/trailing whitespace.
708723
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
709724

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)
725+
# Make each individual specifier a Specifier and save in a frozen set for later.
726+
self._specs = frozenset(map(Specifier, split_specifiers))
718727

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

0 commit comments

Comments
 (0)