From 9613c887f1dc6cb80080bc2cd6a8334dab417846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Thu, 12 Nov 2020 12:59:42 +0100 Subject: [PATCH 1/3] Test download editable --- tests/functional/test_download.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/functional/test_download.py b/tests/functional/test_download.py index 2eee51b08..6ee02d817 100644 --- a/tests/functional/test_download.py +++ b/tests/functional/test_download.py @@ -849,3 +849,19 @@ def test_download_http_url_bad_hash( assert len(requests) == 1 assert requests[0]['PATH_INFO'] == '/simple-1.0.tar.gz' assert requests[0]['HTTP_ACCEPT_ENCODING'] == 'identity' + + +def test_download_editable(script, data, tmpdir): + """ + Test 'pip download' of editables in requirement file. + """ + editable_path = os.path.join(data.src, 'simplewheel-1.0') + requirements_path = tmpdir / "requirements.txt" + requirements_path.write_text("-e " + str(editable_path.resolve()) + "\n") + download_dir = tmpdir / "download_dir" + script.pip( + 'download', '--no-deps', '-r', str(requirements_path), '-d', str(download_dir) + ) + downloads = os.listdir(download_dir) + assert len(downloads) == 1 + assert downloads[0].endswith(".zip") From 11d07016d98502710075338d992a6e59ed553a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Thu, 12 Nov 2020 12:34:37 +0100 Subject: [PATCH 2/3] Add failing test for issue 9122 --- tests/functional/test_wheel.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/functional/test_wheel.py b/tests/functional/test_wheel.py index f75b009be..286d69435 100644 --- a/tests/functional/test_wheel.py +++ b/tests/functional/test_wheel.py @@ -169,6 +169,22 @@ def test_pip_wheel_builds_editable(script, data): result.did_create(wheel_file_path) +def test_pip_wheel_builds_editable_does_not_create_zip(script, data, tmpdir): + """ + Test 'pip wheel' of editables does not create zip files + (regression test for issue #9122) + """ + wheel_dir = tmpdir / "wheel_dir" + wheel_dir.mkdir() + editable_path = os.path.join(data.src, 'simplewheel-1.0') + script.pip( + 'wheel', '--no-deps', '-e', editable_path, '-w', wheel_dir + ) + wheels = os.listdir(wheel_dir) + assert len(wheels) == 1 + assert wheels[0].endswith(".whl") + + def test_pip_wheel_fail(script, data): """ Test 'pip wheel' failure. From a24d198c15d03e8e30b1efcd3e32d303238355f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Wed, 11 Nov 2020 23:56:34 +0100 Subject: [PATCH 3/3] Do not download editables while preparing requirements Downloading is done at the end of the download command just like any other requirement. This is necessary to avoid archiving editable requirements to a zip file when running pip wheel. --- news/9122.bugfix.rst | 2 ++ src/pip/_internal/commands/download.py | 2 +- src/pip/_internal/operations/prepare.py | 3 +-- tests/functional/test_download.py | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 news/9122.bugfix.rst diff --git a/news/9122.bugfix.rst b/news/9122.bugfix.rst new file mode 100644 index 000000000..da2ae5e5f --- /dev/null +++ b/news/9122.bugfix.rst @@ -0,0 +1,2 @@ +Fix a regression that made ``pip wheel`` generate zip files of editable +requirements in the wheel directory. diff --git a/src/pip/_internal/commands/download.py b/src/pip/_internal/commands/download.py index 9535ef3cb..a2d3bf7d9 100644 --- a/src/pip/_internal/commands/download.py +++ b/src/pip/_internal/commands/download.py @@ -132,7 +132,7 @@ class DownloadCommand(RequirementCommand): downloaded = [] # type: List[str] for req in requirement_set.requirements.values(): - if not req.editable and req.satisfied_by is None: + if req.satisfied_by is None: assert req.name is not None preparer.save_linked_requirement(req) downloaded.append(req.name) diff --git a/src/pip/_internal/operations/prepare.py b/src/pip/_internal/operations/prepare.py index de017504a..13b2c0bee 100644 --- a/src/pip/_internal/operations/prepare.py +++ b/src/pip/_internal/operations/prepare.py @@ -530,7 +530,7 @@ class RequirementPreparer(object): assert self.download_dir is not None assert req.link is not None link = req.link - if link.is_vcs: + if link.is_vcs or (link.is_existing_dir() and req.editable): # Make a .zip of the source_dir we already created. req.archive(self.download_dir) return @@ -576,7 +576,6 @@ class RequirementPreparer(object): req, self.req_tracker, self.finder, self.build_isolation, ) - req.archive(self.download_dir) req.check_if_exists(self.use_user_site) return dist diff --git a/tests/functional/test_download.py b/tests/functional/test_download.py index 6ee02d817..8a816b63b 100644 --- a/tests/functional/test_download.py +++ b/tests/functional/test_download.py @@ -855,9 +855,9 @@ def test_download_editable(script, data, tmpdir): """ Test 'pip download' of editables in requirement file. """ - editable_path = os.path.join(data.src, 'simplewheel-1.0') + editable_path = str(data.src / 'simplewheel-1.0').replace(os.path.sep, "/") requirements_path = tmpdir / "requirements.txt" - requirements_path.write_text("-e " + str(editable_path.resolve()) + "\n") + requirements_path.write_text("-e " + editable_path + "\n") download_dir = tmpdir / "download_dir" script.pip( 'download', '--no-deps', '-r', str(requirements_path), '-d', str(download_dir)