Skip to content

Commit 7cb60b5

Browse files
authored
Merge pull request #2305 from sirosen/fix-finder-cache-clearing
Fix bugs related to losing index URL information when clearing finder cache
2 parents 9386c6b + c5dec05 commit 7cb60b5

5 files changed

Lines changed: 66 additions & 7 deletions

File tree

changelog.d/2220.bugfix.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed a bug in which `pip-compile` lost any index URL options when looking up hashes -- by {user}`sirosen`.
2+
3+
This caused errors when a package was only available from an extra index, and caused `pip-compile` to incorrectly drop index URL options from output, even when they were present in the input requirements.

changelog.d/2294.bugfix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2220.bugfix.md

changelog.d/2305.bugfix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2220.bugfix.md

piptools/repositories/pypi.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,20 @@ def session(self) -> PipSession:
116116
def finder(self) -> PackageFinder:
117117
return self._finder
118118

119+
def _clear_finder_cache(self) -> None:
120+
"""Clear the cache of installation candidates."""
121+
# `finder.find_all_candidates` is an lru_cache wrapped method on older `pip`
122+
# versions, which can be cleared with `cache_clear()`
123+
# but on newer versions, it's a simple method, and the underlying cache is a
124+
# dict on the instance
125+
# the same holds for `finder.find_best_candidate`
126+
if _pip_api.PIP_VERSION_MAJOR_MINOR >= (25, 1):
127+
self.finder._all_candidates.clear()
128+
self.finder._best_candidates.clear()
129+
else:
130+
self.finder.find_all_candidates.cache_clear()
131+
self.finder.find_best_candidate.cache_clear()
132+
119133
@property
120134
def command(self) -> InstallCommand:
121135
"""Return an install command instance."""
@@ -450,13 +464,10 @@ def _wheel_support_index_min(self: Wheel, tags: list[Tag]) -> int:
450464
Wheel.support_index_min = _wheel_support_index_min
451465
self._available_candidates_cache = {}
452466

453-
# Finder internally caches results, and there is no public method to
454-
# clear the cache, so we re-create the object here. If we don't clear
455-
# this cache then it can contain results from an earlier call when
456-
# allow_all_wheels wasn't active. See GH-1532
457-
self._finder = self.command._build_package_finder(
458-
options=self.options, session=self.session
459-
)
467+
# Finder internally caches results. If we don't clear this cache then it can
468+
# contain results from an earlier call when allow_all_wheels wasn't active.
469+
# See GH-1532
470+
self._clear_finder_cache()
460471

461472
try:
462473
yield

tests/test_cli_compile.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4203,3 +4203,46 @@ def test_that_self_referential_pyproject_toml_extra_can_be_compiled(
42034203
small-fake-a==0.2
42044204
# via foo
42054205
""")
4206+
4207+
4208+
def test_compile_with_generate_hashes_preserves_extra_index_url(
4209+
pip_with_index_conf,
4210+
minimal_wheels_path,
4211+
runner,
4212+
tmpdir_cwd,
4213+
):
4214+
"""
4215+
Regression test for
4216+
https://github.com/jazzband/pip-tools/issues/2220
4217+
4218+
Using ``--generate-hashes`` triggers the codepath which clears the package finder
4219+
cache (``allow_all_wheels()``), and that code incorrectly cleared more information
4220+
than desired, removing extra index URLs in addition to cached package info.
4221+
"""
4222+
reqs_in = tmpdir_cwd / "requirements.in"
4223+
reqs_in.write_text(dedent("""\
4224+
--extra-index-url http://extraindex1.com
4225+
4226+
small-fake-a
4227+
"""))
4228+
4229+
out = runner.invoke(
4230+
cli,
4231+
["--output-file", "-", "--no-header", "--strip-extras", "--generate-hashes"],
4232+
)
4233+
4234+
# the output should contain
4235+
# - the `--index-url` from the pip config
4236+
# - the `--extra-index-url` from `requirements.in`
4237+
# - the `--find-links` option from pip config
4238+
#
4239+
# and then package resolution information
4240+
assert out.stdout == dedent(f"""\
4241+
--index-url http://example.com
4242+
--extra-index-url http://extraindex1.com
4243+
--find-links {minimal_wheels_path.as_posix()}
4244+
4245+
small-fake-a==0.2 \\
4246+
--hash=sha256:33e1acdca3b9162e002cedb0e58b350d731d1ed3f53a6b22e0a628bca7c7c6ed
4247+
# via -r requirements.in
4248+
""")

0 commit comments

Comments
 (0)