From 42647739fdd2dc2ab9eb6759cee17b3f796ee6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Sat, 12 Sep 2020 21:08:49 +0700 Subject: [PATCH] New resolver: Avoid polluting dest dir Previously, during dependency resolution for `pip download -d ` or `pip wheel -w `, distributions downloaded are always saved to , even for those are only used in backtracking and are not part of the returned requirement set. --- news/8827.bugfix.rst | 2 ++ src/pip/_internal/commands/download.py | 1 + src/pip/_internal/commands/wheel.py | 11 +++++--- src/pip/_internal/operations/prepare.py | 36 ++++++++++++++++--------- 4 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 news/8827.bugfix.rst diff --git a/news/8827.bugfix.rst b/news/8827.bugfix.rst new file mode 100644 index 00000000000..608cd3d5c61 --- /dev/null +++ b/news/8827.bugfix.rst @@ -0,0 +1,2 @@ +Avoid polluting the destination directory by resolution artifacts +when the new resolver is used for ``pip download`` or ``pip wheel``. diff --git a/src/pip/_internal/commands/download.py b/src/pip/_internal/commands/download.py index 31eebd9628c..2f151e049cf 100644 --- a/src/pip/_internal/commands/download.py +++ b/src/pip/_internal/commands/download.py @@ -137,6 +137,7 @@ def run(self, options, args): for req in requirement_set.requirements.values(): if not req.editable and req.satisfied_by is None: assert req.name is not None + preparer.save_linked_requirement(req) downloaded.append(req.name) if downloaded: write_output('Successfully downloaded %s', ' '.join(downloaded)) diff --git a/src/pip/_internal/commands/wheel.py b/src/pip/_internal/commands/wheel.py index 38a9b197fed..8f5783c353f 100644 --- a/src/pip/_internal/commands/wheel.py +++ b/src/pip/_internal/commands/wheel.py @@ -21,6 +21,7 @@ from optparse import Values from typing import List + from pip._internal.req.req_install import InstallRequirement logger = logging.getLogger(__name__) @@ -156,10 +157,12 @@ def run(self, options, args): reqs, check_supported_wheels=True ) - reqs_to_build = [ - r for r in requirement_set.requirements.values() - if should_build_for_wheel_command(r) - ] + reqs_to_build = [] # type: List[InstallRequirement] + for req in requirement_set.requirements.values(): + if req.is_wheel: + preparer.save_linked_requirement(req) + elif should_build_for_wheel_command(req): + reqs_to_build.append(req) # build wheels build_successes, build_failures = build( diff --git a/src/pip/_internal/operations/prepare.py b/src/pip/_internal/operations/prepare.py index 8767115b8e0..de017504abe 100644 --- a/src/pip/_internal/operations/prepare.py +++ b/src/pip/_internal/operations/prepare.py @@ -523,23 +523,33 @@ def _prepare_linked_requirement(self, req, parallel_builds): dist = _get_prepared_distribution( req, self.req_tracker, self.finder, self.build_isolation, ) + return dist - if self.download_dir is not None: - if link.is_existing_dir(): - logger.info('Link is a directory, ignoring download_dir') - elif local_file: - download_location = os.path.join( - self.download_dir, link.filename - ) - if not os.path.exists(download_location): - shutil.copy(local_file.path, download_location) - download_path = display_path(download_location) - logger.info('Saved %s', download_path) - + def save_linked_requirement(self, req): + # type: (InstallRequirement) -> None + assert self.download_dir is not None + assert req.link is not None + link = req.link if link.is_vcs: # Make a .zip of the source_dir we already created. req.archive(self.download_dir) - return dist + return + + if link.is_existing_dir(): + logger.debug( + 'Not copying link to destination directory ' + 'since it is a directory: %s', link, + ) + return + if req.local_file_path is None: + # No distribution was downloaded for this requirement. + return + + download_location = os.path.join(self.download_dir, link.filename) + if not os.path.exists(download_location): + shutil.copy(req.local_file_path, download_location) + download_path = display_path(download_location) + logger.info('Saved %s', download_path) def prepare_editable_requirement( self,