Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add downloaded/local archive path to InstallRequirement #7483

Merged
merged 4 commits into from
Dec 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/pip/_internal/operations/install/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
from pip._internal.exceptions import InstallationError, UnsupportedWheel
from pip._internal.locations import get_major_minor_version
from pip._internal.utils.misc import captured_stdout, ensure_dir, hash_file
from pip._internal.utils.temp_dir import TempDirectory
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
from pip._internal.utils.unpacking import unpack_file

if MYPY_CHECK_RUNNING:
from typing import (
Expand Down Expand Up @@ -618,6 +620,30 @@ def is_entrypoint_wrapper(name):
shutil.move(temp_record, record)


def install_wheel(
name, # type: str
wheel_path, # type: str
scheme, # type: Scheme
req_description, # type: str
pycompile=True, # type: bool
warn_script_location=True, # type: bool
_temp_dir_for_testing=None, # type: Optional[str]
chrahunt marked this conversation as resolved.
Show resolved Hide resolved
):
# type: (...) -> None
with TempDirectory(
path=_temp_dir_for_testing, kind="unpacked-wheel"
) as unpacked_dir:
unpack_file(wheel_path, unpacked_dir.path)
install_unpacked_wheel(
name=name,
wheeldir=unpacked_dir.path,
scheme=scheme,
req_description=req_description,
pycompile=pycompile,
warn_script_location=warn_script_location,
)


def wheel_version(source_dir):
# type: (Optional[str]) -> Optional[Tuple[int, ...]]
"""Return the Wheel-Version of an extracted wheel, if possible.
Expand Down
24 changes: 17 additions & 7 deletions src/pip/_internal/operations/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def unpack_http_url(
download_dir=None, # type: Optional[str]
hashes=None, # type: Optional[Hashes]
):
# type: (...) -> None
# type: (...) -> str
temp_dir = TempDirectory(kind="unpack", globally_managed=True)
# If a download dir is specified, is the file already downloaded there?
already_downloaded_path = None
Expand Down Expand Up @@ -171,6 +171,8 @@ def unpack_http_url(
):
_copy_file(from_path, download_dir, link)

return from_path


def _copy2_ignoring_special_files(src, dest):
# type: (str, str) -> None
Expand Down Expand Up @@ -219,7 +221,7 @@ def unpack_file_url(
download_dir=None, # type: Optional[str]
hashes=None # type: Optional[Hashes]
):
# type: (...) -> None
# type: (...) -> Optional[str]
"""Unpack link into location.

If download_dir is provided and link points to a file, make a copy
Expand All @@ -233,7 +235,7 @@ def unpack_file_url(
_copy_source_tree(link_path, location)
if download_dir:
logger.info('Link is a directory, ignoring download_dir')
return
return None

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

return from_path


def unpack_url(
link, # type: Link
Expand All @@ -275,7 +279,7 @@ def unpack_url(
download_dir=None, # type: Optional[str]
hashes=None, # type: Optional[Hashes]
):
# type: (...) -> None
# type: (...) -> Optional[str]
"""Unpack link.
If link is a VCS link:
if only_download, export into download_dir and ignore location
Expand All @@ -293,14 +297,15 @@ def unpack_url(
# non-editable vcs urls
if link.is_vcs:
unpack_vcs_link(link, location)
return None

# file urls
elif link.is_file:
unpack_file_url(link, location, download_dir, hashes=hashes)
return unpack_file_url(link, location, download_dir, hashes=hashes)

# http urls
else:
unpack_http_url(
return unpack_http_url(
link,
location,
downloader,
Expand Down Expand Up @@ -500,7 +505,7 @@ def prepare_linked_requirement(
download_dir = self.wheel_download_dir

try:
unpack_url(
local_path = unpack_url(
link, req.source_dir, self.downloader, download_dir,
hashes=hashes,
)
Expand All @@ -515,6 +520,11 @@ def prepare_linked_requirement(
'error {} for URL {}'.format(req, exc, link)
)

# For use in later processing, preserve the file path on the
# requirement.
if local_path:
req.local_file_path = local_path

if link.is_wheel:
if download_dir:
# When downloading, we only unpack wheels to get
Expand Down
11 changes: 8 additions & 3 deletions src/pip/_internal/req/req_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
generate_metadata as generate_metadata_legacy
from pip._internal.operations.install.editable_legacy import \
install as install_editable_legacy
from pip._internal.operations.install.wheel import install_unpacked_wheel
from pip._internal.operations.install.wheel import install_wheel
from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path
from pip._internal.req.req_uninstall import UninstallPathSet
from pip._internal.utils.deprecation import deprecated
Expand Down Expand Up @@ -137,6 +137,10 @@ def __init__(
# PEP 508 URL requirement
link = Link(req.url)
self.link = self.original_link = link
# Path to any downloaded or already-existing package.
self.local_file_path = None # type: Optional[str]
if self.link and self.link.is_file:
self.local_file_path = self.link.file_path

if extras:
self.extras = extras
Expand Down Expand Up @@ -770,9 +774,10 @@ def install(
return

if self.is_wheel:
install_unpacked_wheel(
assert self.local_file_path
install_wheel(
self.name,
self.source_dir,
self.local_file_path,
scheme=scheme,
req_description=str(self.req),
pycompile=pycompile,
Expand Down
1 change: 1 addition & 0 deletions src/pip/_internal/wheel_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ def build(
)
# Update the link for this.
req.link = Link(path_to_url(wheel_file))
req.local_file_path = req.link.file_path
assert req.link.is_wheel
# extract the wheel into the dir
unpack_file(req.link.file_path, req.source_dir)
Expand Down
14 changes: 7 additions & 7 deletions tests/unit/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ def prep(self, data, tmpdir):
self.req = Requirement('sample')
self.src = os.path.join(tmpdir, 'src')
self.dest = os.path.join(tmpdir, 'dest')
unpack_file(self.wheelpath, self.src)
self.scheme = Scheme(
purelib=os.path.join(self.dest, 'lib'),
platlib=os.path.join(self.dest, 'lib'),
Expand Down Expand Up @@ -290,9 +289,9 @@ def assert_installed(self):

def test_std_install(self, data, tmpdir):
self.prep(data, tmpdir)
wheel.install_unpacked_wheel(
wheel.install_wheel(
self.name,
self.src,
self.wheelpath,
scheme=self.scheme,
req_description=str(self.req),
)
Expand All @@ -309,9 +308,9 @@ def test_install_prefix(self, data, tmpdir):
isolated=False,
prefix=prefix,
)
wheel.install_unpacked_wheel(
wheel.install_wheel(
self.name,
self.src,
self.wheelpath,
scheme=scheme,
req_description=str(self.req),
)
Expand All @@ -330,11 +329,12 @@ def test_dist_info_contains_empty_dir(self, data, tmpdir):
self.src_dist_info, 'empty_dir', 'empty_dir')
os.makedirs(src_empty_dir)
assert os.path.isdir(src_empty_dir)
wheel.install_unpacked_wheel(
wheel.install_wheel(
self.name,
self.src,
self.wheelpath,
scheme=self.scheme,
req_description=str(self.req),
_temp_dir_for_testing=self.src,
)
self.assert_installed()
assert not os.path.isdir(
Expand Down