Skip to content

Commit 2e11f31

Browse files
authored
Merge pull request #9078 from xavfernandez/cache_find_best_candidate
2 parents a0e34e9 + 5ec275f commit 2e11f31

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

src/pip/_internal/index/package_finder.py

+1
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ def make_candidate_evaluator(
863863
hashes=hashes,
864864
)
865865

866+
@lru_cache(maxsize=None)
866867
def find_best_candidate(
867868
self,
868869
project_name, # type: str

src/pip/_internal/utils/hashes.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ def __init__(self, hashes=None):
3939
:param hashes: A dict of algorithm names pointing to lists of allowed
4040
hex digests
4141
"""
42-
self._allowed = {} if hashes is None else hashes
42+
allowed = {}
43+
if hashes is not None:
44+
for alg, keys in hashes.items():
45+
# Make sure values are always sorted (to ease equality checks)
46+
allowed[alg] = sorted(keys)
47+
self._allowed = allowed
4348

4449
def __and__(self, other):
4550
# type: (Hashes) -> Hashes
@@ -128,6 +133,22 @@ def __bool__(self):
128133
# type: () -> bool
129134
return self.__nonzero__()
130135

136+
def __eq__(self, other):
137+
# type: (object) -> bool
138+
if not isinstance(other, Hashes):
139+
return NotImplemented
140+
return self._allowed == other._allowed
141+
142+
def __hash__(self):
143+
# type: () -> int
144+
return hash(
145+
",".join(sorted(
146+
":".join((alg, digest))
147+
for alg, digest_list in self._allowed.items()
148+
for digest in digest_list
149+
))
150+
)
151+
131152

132153
class MissingHashes(Hashes):
133154
"""A workalike for Hashes used when we're missing a hash for a requirement

tests/unit/test_utils.py

+10
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,16 @@ def test_non_zero(self):
541541
assert not Hashes()
542542
assert not Hashes({})
543543

544+
def test_equality(self):
545+
assert Hashes() == Hashes()
546+
assert Hashes({'sha256': ['abcd']}) == Hashes({'sha256': ['abcd']})
547+
assert Hashes({'sha256': ['ab', 'cd']}) == Hashes({'sha256': ['cd', 'ab']})
548+
549+
def test_hash(self):
550+
cache = {}
551+
cache[Hashes({'sha256': ['ab', 'cd']})] = 42
552+
assert cache[Hashes({'sha256': ['ab', 'cd']})] == 42
553+
544554

545555
class TestEncoding(object):
546556
"""Tests for pip._internal.utils.encoding"""

0 commit comments

Comments
 (0)