diff --git a/src/pip/_internal/resolution/resolvelib/candidates.py b/src/pip/_internal/resolution/resolvelib/candidates.py index 4125cda2b7c..97d476ce9ea 100644 --- a/src/pip/_internal/resolution/resolvelib/candidates.py +++ b/src/pip/_internal/resolution/resolvelib/candidates.py @@ -20,6 +20,7 @@ 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 +326,7 @@ def _prepare_distribution(self) -> BaseDistribution: return self._factory.preparer.prepare_editable_requirement(self._ireq) -class AlreadyInstalledCandidate(Candidate): +class AlreadyInstalledCandidate(Candidate, KeyBasedCompareMixin): is_installed = True source_link = None @@ -347,20 +348,16 @@ 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 __hash__(self) -> int: - return hash((self.__class__, self.name, self.version)) - - def __eq__(self, other: Any) -> bool: - if isinstance(other, self.__class__): - return self.name == other.name and self.version == other.version - return False - @property def project_name(self) -> NormalizedName: return self.dist.canonical_name