Skip to content

Commit d6491fe

Browse files
authored
Merge pull request #7483 from chrahunt/refactor/install-packed-wheel
Add downloaded/local archive path to InstallRequirement
2 parents 81805a5 + 11472e1 commit d6491fe

File tree

5 files changed

+59
-17
lines changed

5 files changed

+59
-17
lines changed

src/pip/_internal/operations/install/wheel.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
from pip._internal.exceptions import InstallationError, UnsupportedWheel
2929
from pip._internal.locations import get_major_minor_version
3030
from pip._internal.utils.misc import captured_stdout, ensure_dir, hash_file
31+
from pip._internal.utils.temp_dir import TempDirectory
3132
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
33+
from pip._internal.utils.unpacking import unpack_file
3234

3335
if MYPY_CHECK_RUNNING:
3436
from typing import (
@@ -618,6 +620,30 @@ def is_entrypoint_wrapper(name):
618620
shutil.move(temp_record, record)
619621

620622

623+
def install_wheel(
624+
name, # type: str
625+
wheel_path, # type: str
626+
scheme, # type: Scheme
627+
req_description, # type: str
628+
pycompile=True, # type: bool
629+
warn_script_location=True, # type: bool
630+
_temp_dir_for_testing=None, # type: Optional[str]
631+
):
632+
# type: (...) -> None
633+
with TempDirectory(
634+
path=_temp_dir_for_testing, kind="unpacked-wheel"
635+
) as unpacked_dir:
636+
unpack_file(wheel_path, unpacked_dir.path)
637+
install_unpacked_wheel(
638+
name=name,
639+
wheeldir=unpacked_dir.path,
640+
scheme=scheme,
641+
req_description=req_description,
642+
pycompile=pycompile,
643+
warn_script_location=warn_script_location,
644+
)
645+
646+
621647
def wheel_version(source_dir):
622648
# type: (Optional[str]) -> Optional[Tuple[int, ...]]
623649
"""Return the Wheel-Version of an extracted wheel, if possible.

src/pip/_internal/operations/prepare.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ def unpack_http_url(
143143
download_dir=None, # type: Optional[str]
144144
hashes=None, # type: Optional[Hashes]
145145
):
146-
# type: (...) -> None
146+
# type: (...) -> str
147147
temp_dir = TempDirectory(kind="unpack", globally_managed=True)
148148
# If a download dir is specified, is the file already downloaded there?
149149
already_downloaded_path = None
@@ -171,6 +171,8 @@ def unpack_http_url(
171171
):
172172
_copy_file(from_path, download_dir, link)
173173

174+
return from_path
175+
174176

175177
def _copy2_ignoring_special_files(src, dest):
176178
# type: (str, str) -> None
@@ -219,7 +221,7 @@ def unpack_file_url(
219221
download_dir=None, # type: Optional[str]
220222
hashes=None # type: Optional[Hashes]
221223
):
222-
# type: (...) -> None
224+
# type: (...) -> Optional[str]
223225
"""Unpack link into location.
224226
225227
If download_dir is provided and link points to a file, make a copy
@@ -233,7 +235,7 @@ def unpack_file_url(
233235
_copy_source_tree(link_path, location)
234236
if download_dir:
235237
logger.info('Link is a directory, ignoring download_dir')
236-
return
238+
return None
237239

238240
# If --require-hashes is off, `hashes` is either empty, the
239241
# link's embedded hash, or MissingHashes; it is required to
@@ -267,6 +269,8 @@ def unpack_file_url(
267269
):
268270
_copy_file(from_path, download_dir, link)
269271

272+
return from_path
273+
270274

271275
def unpack_url(
272276
link, # type: Link
@@ -275,7 +279,7 @@ def unpack_url(
275279
download_dir=None, # type: Optional[str]
276280
hashes=None, # type: Optional[Hashes]
277281
):
278-
# type: (...) -> None
282+
# type: (...) -> Optional[str]
279283
"""Unpack link.
280284
If link is a VCS link:
281285
if only_download, export into download_dir and ignore location
@@ -293,14 +297,15 @@ def unpack_url(
293297
# non-editable vcs urls
294298
if link.is_vcs:
295299
unpack_vcs_link(link, location)
300+
return None
296301

297302
# file urls
298303
elif link.is_file:
299-
unpack_file_url(link, location, download_dir, hashes=hashes)
304+
return unpack_file_url(link, location, download_dir, hashes=hashes)
300305

301306
# http urls
302307
else:
303-
unpack_http_url(
308+
return unpack_http_url(
304309
link,
305310
location,
306311
downloader,
@@ -500,7 +505,7 @@ def prepare_linked_requirement(
500505
download_dir = self.wheel_download_dir
501506

502507
try:
503-
unpack_url(
508+
local_path = unpack_url(
504509
link, req.source_dir, self.downloader, download_dir,
505510
hashes=hashes,
506511
)
@@ -515,6 +520,11 @@ def prepare_linked_requirement(
515520
'error {} for URL {}'.format(req, exc, link)
516521
)
517522

523+
# For use in later processing, preserve the file path on the
524+
# requirement.
525+
if local_path:
526+
req.local_file_path = local_path
527+
518528
if link.is_wheel:
519529
if download_dir:
520530
# When downloading, we only unpack wheels to get

src/pip/_internal/req/req_install.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
generate_metadata as generate_metadata_legacy
2828
from pip._internal.operations.install.editable_legacy import \
2929
install as install_editable_legacy
30-
from pip._internal.operations.install.wheel import install_unpacked_wheel
30+
from pip._internal.operations.install.wheel import install_wheel
3131
from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path
3232
from pip._internal.req.req_uninstall import UninstallPathSet
3333
from pip._internal.utils.deprecation import deprecated
@@ -137,6 +137,10 @@ def __init__(
137137
# PEP 508 URL requirement
138138
link = Link(req.url)
139139
self.link = self.original_link = link
140+
# Path to any downloaded or already-existing package.
141+
self.local_file_path = None # type: Optional[str]
142+
if self.link and self.link.is_file:
143+
self.local_file_path = self.link.file_path
140144

141145
if extras:
142146
self.extras = extras
@@ -770,9 +774,10 @@ def install(
770774
return
771775

772776
if self.is_wheel:
773-
install_unpacked_wheel(
777+
assert self.local_file_path
778+
install_wheel(
774779
self.name,
775-
self.source_dir,
780+
self.local_file_path,
776781
scheme=scheme,
777782
req_description=str(self.req),
778783
pycompile=pycompile,

src/pip/_internal/wheel_builder.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ def build(
472472
)
473473
# Update the link for this.
474474
req.link = Link(path_to_url(wheel_file))
475+
req.local_file_path = req.link.file_path
475476
assert req.link.is_wheel
476477
# extract the wheel into the dir
477478
unpack_file(req.link.file_path, req.source_dir)

tests/unit/test_wheel.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ def prep(self, data, tmpdir):
260260
self.req = Requirement('sample')
261261
self.src = os.path.join(tmpdir, 'src')
262262
self.dest = os.path.join(tmpdir, 'dest')
263-
unpack_file(self.wheelpath, self.src)
264263
self.scheme = Scheme(
265264
purelib=os.path.join(self.dest, 'lib'),
266265
platlib=os.path.join(self.dest, 'lib'),
@@ -290,9 +289,9 @@ def assert_installed(self):
290289

291290
def test_std_install(self, data, tmpdir):
292291
self.prep(data, tmpdir)
293-
wheel.install_unpacked_wheel(
292+
wheel.install_wheel(
294293
self.name,
295-
self.src,
294+
self.wheelpath,
296295
scheme=self.scheme,
297296
req_description=str(self.req),
298297
)
@@ -309,9 +308,9 @@ def test_install_prefix(self, data, tmpdir):
309308
isolated=False,
310309
prefix=prefix,
311310
)
312-
wheel.install_unpacked_wheel(
311+
wheel.install_wheel(
313312
self.name,
314-
self.src,
313+
self.wheelpath,
315314
scheme=scheme,
316315
req_description=str(self.req),
317316
)
@@ -330,11 +329,12 @@ def test_dist_info_contains_empty_dir(self, data, tmpdir):
330329
self.src_dist_info, 'empty_dir', 'empty_dir')
331330
os.makedirs(src_empty_dir)
332331
assert os.path.isdir(src_empty_dir)
333-
wheel.install_unpacked_wheel(
332+
wheel.install_wheel(
334333
self.name,
335-
self.src,
334+
self.wheelpath,
336335
scheme=self.scheme,
337336
req_description=str(self.req),
337+
_temp_dir_for_testing=self.src,
338338
)
339339
self.assert_installed()
340340
assert not os.path.isdir(

0 commit comments

Comments
 (0)