diff --git a/src/pip/_internal/resolution/resolvelib/candidates.py b/src/pip/_internal/resolution/resolvelib/candidates.py index 1a048eb10..f8461ade2 100644 --- a/src/pip/_internal/resolution/resolvelib/candidates.py +++ b/src/pip/_internal/resolution/resolvelib/candidates.py @@ -288,6 +288,17 @@ class AlreadyInstalledCandidate(Candidate): distribution=self.dist, ) + def __eq__(self, other): + # type: (Any) -> bool + if isinstance(other, self.__class__): + return self.name == other.name and self.version == other.version + return False + + # Needed for Python 2, which does not implement this by default + def __ne__(self, other): + # type: (Any) -> bool + return not self.__eq__(other) + @property def name(self): # type: () -> str @@ -351,6 +362,17 @@ class ExtrasCandidate(Candidate): extras=self.extras, ) + def __eq__(self, other): + # type: (Any) -> bool + if isinstance(other, self.__class__): + return self.base == other.base and self.extras == other.extras + return False + + # Needed for Python 2, which does not implement this by default + def __ne__(self, other): + # type: (Any) -> bool + return not self.__eq__(other) + @property def name(self): # type: () -> str @@ -404,6 +426,10 @@ class RequiresPythonCandidate(Candidate): version_info = sys.version_info[:3] self._version = Version(".".join(str(c) for c in version_info)) + # We don't need to implement __eq__() and __ne__() since there is always + # only one RequiresPythonCandidate in a resolution, i.e. the host Python. + # The built-in object.__eq__() and object.__ne__() do exactly what we want. + @property def name(self): # type: () -> str