Skip to content

Commit 44c8cac

Browse files
authored
Merge pull request #7285 from sbidoul/pip-wheel-cache-like-pip-install-sbi
Make pip wheel cache what it built
2 parents f9ee892 + ba60397 commit 44c8cac

File tree

3 files changed

+57
-17
lines changed

3 files changed

+57
-17
lines changed

news/6852.feature

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Cache wheels that ``pip wheel`` built locally, matching what
2+
``pip install`` does. This particularly helps performance in workflows where
3+
``pip wheel`` is used for `building before installing
4+
<https://pip.pypa.io/en/stable/user_guide/#installing-from-local-packages>`_.
5+
Users desiring the original behavior can use ``pip wheel --no-cache-dir``.

src/pip/_internal/wheel.py

+28-17
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ def build(
11021102
:param should_unpack: If True, after building the wheel, unpack it
11031103
and replace the sdist with the unpacked version in preparation
11041104
for installation.
1105-
:return: True if all the wheels built correctly.
1105+
:return: The list of InstallRequirement that failed to build.
11061106
"""
11071107
# pip install uses should_unpack=True.
11081108
# pip install never provides a _wheel_dir.
@@ -1124,19 +1124,15 @@ def build(
11241124
):
11251125
continue
11261126

1127-
# Determine where the wheel should go.
1128-
if should_unpack:
1129-
if (
1130-
cache_available and
1131-
should_cache(req, self.check_binary_allowed)
1132-
):
1133-
output_dir = self.wheel_cache.get_path_for_link(req.link)
1134-
else:
1135-
output_dir = self.wheel_cache.get_ephem_path_for_link(
1136-
req.link
1137-
)
1127+
if (
1128+
cache_available and
1129+
should_cache(req, self.check_binary_allowed)
1130+
):
1131+
output_dir = self.wheel_cache.get_path_for_link(req.link)
11381132
else:
1139-
output_dir = self._wheel_dir
1133+
output_dir = self.wheel_cache.get_ephem_path_for_link(
1134+
req.link
1135+
)
11401136

11411137
buildset.append((req, output_dir))
11421138

@@ -1174,10 +1170,6 @@ def build(
11741170
python_tag=python_tag,
11751171
)
11761172
if wheel_file:
1177-
build_success.append(req)
1178-
self.wheel_filenames.append(
1179-
os.path.relpath(wheel_file, output_dir)
1180-
)
11811173
if should_unpack:
11821174
# XXX: This is mildly duplicative with prepare_files,
11831175
# but not close enough to pull out to a single common
@@ -1202,6 +1194,25 @@ def build(
12021194
assert req.link.is_wheel
12031195
# extract the wheel into the dir
12041196
unpack_file(req.link.file_path, req.source_dir)
1197+
else:
1198+
# copy from cache to target directory
1199+
try:
1200+
ensure_dir(self._wheel_dir)
1201+
shutil.copy(
1202+
os.path.join(output_dir, wheel_file),
1203+
self._wheel_dir,
1204+
)
1205+
except OSError as e:
1206+
logger.warning(
1207+
"Building wheel for %s failed: %s",
1208+
req.name, e,
1209+
)
1210+
build_failure.append(req)
1211+
continue
1212+
self.wheel_filenames.append(
1213+
os.path.relpath(wheel_file, output_dir)
1214+
)
1215+
build_success.append(req)
12051216
else:
12061217
build_failure.append(req)
12071218

tests/functional/test_wheel.py

+24
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,30 @@ def test_pip_wheel_success(script, data):
6262
assert "Successfully built simple" in result.stdout, result.stdout
6363

6464

65+
def test_pip_wheel_build_cache(script, data):
66+
"""
67+
Test 'pip wheel' builds and caches.
68+
"""
69+
result = script.pip(
70+
'wheel', '--no-index', '-f', data.find_links,
71+
'simple==3.0',
72+
)
73+
wheel_file_name = 'simple-3.0-py%s-none-any.whl' % pyversion[0]
74+
wheel_file_path = script.scratch / wheel_file_name
75+
assert wheel_file_path in result.files_created, result.stdout
76+
assert "Successfully built simple" in result.stdout, result.stdout
77+
# remove target file
78+
(script.scratch_path / wheel_file_name).unlink()
79+
# pip wheel again and test that no build occurs since
80+
# we get the wheel from cache
81+
result = script.pip(
82+
'wheel', '--no-index', '-f', data.find_links,
83+
'simple==3.0',
84+
)
85+
assert wheel_file_path in result.files_created, result.stdout
86+
assert "Successfully built simple" not in result.stdout, result.stdout
87+
88+
6589
def test_basic_pip_wheel_downloads_wheels(script, data):
6690
"""
6791
Test 'pip wheel' downloads wheels

0 commit comments

Comments
 (0)