From 38b56452ad23d68901409da30ee07ad2f0466581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sun, 21 Apr 2024 14:01:47 +0200 Subject: [PATCH] Don't use KeyBasedCompareMixin --- .../resolution/resolvelib/candidates.py | 15 +++++--- .../resolution/resolvelib/requirements.py | 38 +++++++++++++------ 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/pip/_internal/resolution/resolvelib/candidates.py b/src/pip/_internal/resolution/resolvelib/candidates.py index 034fc343975..140aaafcb8f 100644 --- a/src/pip/_internal/resolution/resolvelib/candidates.py +++ b/src/pip/_internal/resolution/resolvelib/candidates.py @@ -20,7 +20,6 @@ from pip._internal.req.req_install import InstallRequirement from pip._internal.utils.direct_url_helpers import direct_url_from_link from pip._internal.utils.misc import normalize_version_info -from pip._internal.utils.models import KeyBasedCompareMixin from .base import Candidate, CandidateVersion, Requirement, format_name @@ -325,7 +324,7 @@ def _prepare_distribution(self) -> BaseDistribution: return self._factory.preparer.prepare_editable_requirement(self._ireq) -class AlreadyInstalledCandidate(Candidate, KeyBasedCompareMixin): +class AlreadyInstalledCandidate(Candidate): is_installed = True source_link = None @@ -347,16 +346,20 @@ def __init__( skip_reason = "already satisfied" factory.preparer.prepare_installed_requirement(self._ireq, skip_reason) - KeyBasedCompareMixin.__init__( - self, key=(self.name, self.version), defining_class=self.__class__ - ) - def __str__(self) -> str: return str(self.dist) def __repr__(self) -> str: return f"{self.__class__.__name__}({self.dist!r})" + def __eq__(self, other: object) -> bool: + if not isinstance(other, AlreadyInstalledCandidate): + return NotImplemented + return self.name == other.name and self.version == other.version + + def __hash__(self) -> int: + return hash((self.name, self.version)) + @property def project_name(self) -> NormalizedName: return self.dist.canonical_name diff --git a/src/pip/_internal/resolution/resolvelib/requirements.py b/src/pip/_internal/resolution/resolvelib/requirements.py index 7f6e72bad18..f980a356f18 100644 --- a/src/pip/_internal/resolution/resolvelib/requirements.py +++ b/src/pip/_internal/resolution/resolvelib/requirements.py @@ -5,7 +5,6 @@ from pip._internal.req.constructors import install_req_drop_extras from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.models import KeyBasedCompareMixin from .base import Candidate, CandidateLookup, Requirement, format_name @@ -48,14 +47,11 @@ def is_satisfied_by(self, candidate: Candidate) -> bool: return candidate == self.candidate -class SpecifierRequirement(Requirement, KeyBasedCompareMixin): +class SpecifierRequirement(Requirement): def __init__(self, ireq: InstallRequirement) -> None: assert ireq.link is None, "This is a link, not a specifier" self._ireq = ireq self._extras = frozenset(canonicalize_name(e) for e in self._ireq.extras) - KeyBasedCompareMixin.__init__( - self, key=str(ireq), defining_class=SpecifierRequirement - ) def __str__(self) -> str: return str(self._ireq.req) @@ -63,6 +59,14 @@ def __str__(self) -> str: def __repr__(self) -> str: return f"{self.__class__.__name__}({str(self._ireq.req)!r})" + def __eq__(self, other: object) -> bool: + if not isinstance(other, SpecifierRequirement): + return NotImplemented + return str(self._ireq) == str(other._ireq) + + def __hash__(self) -> int: + return hash(str(self._ireq)) + @property def project_name(self) -> NormalizedName: assert self._ireq.req, "Specifier-backed ireq is always PEP 508" @@ -111,9 +115,14 @@ def __init__(self, ireq: InstallRequirement) -> None: assert ireq.link is None, "This is a link, not a specifier" self._ireq = install_req_drop_extras(ireq) self._extras = frozenset(canonicalize_name(e) for e in self._ireq.extras) - KeyBasedCompareMixin.__init__( - self, key=str(ireq), defining_class=SpecifierRequirement - ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, SpecifierWithoutExtrasRequirement): + return NotImplemented + return str(self._ireq) == str(other._ireq) + + def __hash__(self) -> int: + return hash(str(self._ireq)) class RequiresPythonRequirement(Requirement): @@ -165,14 +174,11 @@ def is_satisfied_by(self, candidate: Candidate) -> bool: return self.specifier.contains(candidate.version, prereleases=True) -class UnsatisfiableRequirement(Requirement, KeyBasedCompareMixin): +class UnsatisfiableRequirement(Requirement): """A requirement that cannot be satisfied.""" def __init__(self, name: NormalizedName) -> None: self._name = name - KeyBasedCompareMixin.__init__( - self, key=str(name), defining_class=UnsatisfiableRequirement - ) def __str__(self) -> str: return f"{self._name} (unavailable)" @@ -180,6 +186,14 @@ def __str__(self) -> str: def __repr__(self) -> str: return f"{self.__class__.__name__}({str(self._name)!r})" + def __eq__(self, other: object) -> bool: + if not isinstance(other, UnsatisfiableRequirement): + return NotImplemented + return self._name == other._name + + def __hash__(self) -> int: + return hash(self._name) + @property def project_name(self) -> NormalizedName: return self._name