Skip to content

Commit b944856

Browse files
authored
Merge branch 'main' into 2984-new-cache-lower-memory
2 parents e3cd6ee + eddd9dd commit b944856

22 files changed

+201
-77
lines changed

news/11649.bugfix.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Normalize extras according to :pep:`685` from package metadata in the resolver
2+
for comparison. This ensures extras are correctly compared and merged as long
3+
as the package providing the extra(s) is built with values normalized according
4+
to the standard. Note, however, that this *does not* solve cases where the
5+
package itself contains unnormalized extra values in the metadata.

news/12122.doc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Clarify --prefer-binary in CLI and docs

news/E2B261CA-A0CF-4309-B808-1210C0B54632.trivial.rst

Whitespace-only changes.

setup.cfg

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ per-file-ignores =
3636

3737
[mypy]
3838
mypy_path = $MYPY_CONFIG_FILE_DIR/src
39+
40+
strict = True
41+
42+
no_implicit_reexport = False
43+
allow_subclassing_any = True
44+
allow_untyped_calls = True
45+
warn_return_any = False
3946
ignore_missing_imports = True
40-
disallow_untyped_defs = True
41-
disallow_any_generics = True
42-
warn_unused_ignores = True
43-
no_implicit_optional = True
4447

4548
[mypy-pip._internal.utils._jaraco_text]
4649
ignore_errors = True

src/pip/_internal/cli/cmdoptions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,10 @@ def prefer_binary() -> Option:
670670
dest="prefer_binary",
671671
action="store_true",
672672
default=False,
673-
help="Prefer older binary packages over newer source packages.",
673+
help=(
674+
"Prefer binary packages over source packages, even if the "
675+
"source packages are newer."
676+
),
674677
)
675678

676679

src/pip/_internal/metadata/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .base import BaseDistribution, BaseEnvironment, FilesystemWheel, MemoryWheel, Wheel
1010

1111
if TYPE_CHECKING:
12-
from typing import Protocol
12+
from typing import Literal, Protocol
1313
else:
1414
Protocol = object
1515

@@ -50,6 +50,7 @@ def _should_use_importlib_metadata() -> bool:
5050

5151

5252
class Backend(Protocol):
53+
NAME: 'Literal["importlib", "pkg_resources"]'
5354
Distribution: Type[BaseDistribution]
5455
Environment: Type[BaseEnvironment]
5556

src/pip/_internal/metadata/base.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
from pip._vendor.packaging.requirements import Requirement
2626
from pip._vendor.packaging.specifiers import InvalidSpecifier, SpecifierSet
27-
from pip._vendor.packaging.utils import NormalizedName
27+
from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
2828
from pip._vendor.packaging.version import LegacyVersion, Version
2929

3030
from pip._internal.exceptions import NoneMetadataError
@@ -37,7 +37,6 @@
3737
from pip._internal.utils.compat import stdlib_pkgs # TODO: Move definition here.
3838
from pip._internal.utils.egg_link import egg_link_path_from_sys_path
3939
from pip._internal.utils.misc import is_local, normalize_path
40-
from pip._internal.utils.packaging import safe_extra
4140
from pip._internal.utils.urls import url_to_path
4241

4342
from ._json import msg_to_json
@@ -460,6 +459,19 @@ def iter_provided_extras(self) -> Iterable[str]:
460459
461460
For modern .dist-info distributions, this is the collection of
462461
"Provides-Extra:" entries in distribution metadata.
462+
463+
The return value of this function is not particularly useful other than
464+
display purposes due to backward compatibility issues and the extra
465+
names being poorly normalized prior to PEP 685. If you want to perform
466+
logic operations on extras, use :func:`is_extra_provided` instead.
467+
"""
468+
raise NotImplementedError()
469+
470+
def is_extra_provided(self, extra: str) -> bool:
471+
"""Check whether an extra is provided by this distribution.
472+
473+
This is needed mostly for compatibility issues with pkg_resources not
474+
following the extra normalization rules defined in PEP 685.
463475
"""
464476
raise NotImplementedError()
465477

@@ -537,10 +549,11 @@ def _iter_egg_info_extras(self) -> Iterable[str]:
537549
"""Get extras from the egg-info directory."""
538550
known_extras = {""}
539551
for entry in self._iter_requires_txt_entries():
540-
if entry.extra in known_extras:
552+
extra = canonicalize_name(entry.extra)
553+
if extra in known_extras:
541554
continue
542-
known_extras.add(entry.extra)
543-
yield entry.extra
555+
known_extras.add(extra)
556+
yield extra
544557

545558
def _iter_egg_info_dependencies(self) -> Iterable[str]:
546559
"""Get distribution dependencies from the egg-info directory.
@@ -556,10 +569,11 @@ def _iter_egg_info_dependencies(self) -> Iterable[str]:
556569
all currently available PEP 517 backends, although not standardized.
557570
"""
558571
for entry in self._iter_requires_txt_entries():
559-
if entry.extra and entry.marker:
560-
marker = f'({entry.marker}) and extra == "{safe_extra(entry.extra)}"'
561-
elif entry.extra:
562-
marker = f'extra == "{safe_extra(entry.extra)}"'
572+
extra = canonicalize_name(entry.extra)
573+
if extra and entry.marker:
574+
marker = f'({entry.marker}) and extra == "{extra}"'
575+
elif extra:
576+
marker = f'extra == "{extra}"'
563577
elif entry.marker:
564578
marker = entry.marker
565579
else:
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from ._dists import Distribution
22
from ._envs import Environment
33

4-
__all__ = ["Distribution", "Environment"]
4+
__all__ = ["NAME", "Distribution", "Environment"]
5+
6+
NAME = "importlib"

src/pip/_internal/metadata/importlib/_dists.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
Wheel,
2828
)
2929
from pip._internal.utils.misc import normalize_path
30-
from pip._internal.utils.packaging import safe_extra
3130
from pip._internal.utils.temp_dir import TempDirectory
3231
from pip._internal.utils.wheel import parse_wheel, read_wheel_metadata_file
3332

@@ -208,12 +207,16 @@ def _metadata_impl(self) -> email.message.Message:
208207
return cast(email.message.Message, self._dist.metadata)
209208

210209
def iter_provided_extras(self) -> Iterable[str]:
211-
return (
212-
safe_extra(extra) for extra in self.metadata.get_all("Provides-Extra", [])
210+
return self.metadata.get_all("Provides-Extra", [])
211+
212+
def is_extra_provided(self, extra: str) -> bool:
213+
return any(
214+
canonicalize_name(provided_extra) == canonicalize_name(extra)
215+
for provided_extra in self.metadata.get_all("Provides-Extra", [])
213216
)
214217

215218
def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]:
216-
contexts: Sequence[Dict[str, str]] = [{"extra": safe_extra(e)} for e in extras]
219+
contexts: Sequence[Dict[str, str]] = [{"extra": e} for e in extras]
217220
for req_string in self.metadata.get_all("Requires-Dist", []):
218221
req = Requirement(req_string)
219222
if not req.marker:

src/pip/_internal/metadata/pkg_resources.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@
2424
Wheel,
2525
)
2626

27+
__all__ = ["NAME", "Distribution", "Environment"]
28+
2729
logger = logging.getLogger(__name__)
2830

31+
NAME = "pkg_resources"
32+
2933

3034
class EntryPoint(NamedTuple):
3135
name: str
@@ -212,12 +216,16 @@ def _metadata_impl(self) -> email.message.Message:
212216

213217
def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]:
214218
if extras: # pkg_resources raises on invalid extras, so we sanitize.
215-
extras = frozenset(extras).intersection(self._dist.extras)
219+
extras = frozenset(pkg_resources.safe_extra(e) for e in extras)
220+
extras = extras.intersection(self._dist.extras)
216221
return self._dist.requires(extras)
217222

218223
def iter_provided_extras(self) -> Iterable[str]:
219224
return self._dist.extras
220225

226+
def is_extra_provided(self, extra: str) -> bool:
227+
return pkg_resources.safe_extra(extra) in self._dist.extras
228+
221229

222230
class Environment(BaseEnvironment):
223231
def __init__(self, ws: pkg_resources.WorkingSet) -> None:

0 commit comments

Comments
 (0)