Skip to content

Commit 1f00ec8

Browse files
fix pypa#11847 for sdists
1 parent 7c6d131 commit 1f00ec8

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

src/pip/_internal/operations/prepare.py

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import mimetypes
88
import os
99
import shutil
10-
from typing import Dict, Iterable, List, Optional
10+
from typing import Dict, Iterable, List, Optional, Set
1111

1212
from pip._vendor.packaging.utils import canonicalize_name
1313

@@ -472,32 +472,44 @@ def _complete_partial_requirements(
472472
assert req.link
473473
links_to_fully_download[req.link] = req
474474

475+
reqs_with_newly_unpacked_source_dirs: Set[Link] = set()
476+
475477
batch_download = self._batch_download(
476478
links_to_fully_download.keys(),
477479
temp_dir,
478480
)
479481
for link, (filepath, _) in batch_download:
480482
logger.debug("Downloading link %s to %s", link, filepath)
481483
req = links_to_fully_download[link]
484+
# Record the downloaded file path so wheel reqs can extract a Distribution
485+
# in .get_dist().
482486
req.local_file_path = filepath
483-
# TODO: This needs fixing for sdists
484-
# This is an emergency fix for #11847, which reports that
485-
# distributions get downloaded twice when metadata is loaded
486-
# from a PEP 658 standalone metadata file. Setting _downloaded
487-
# fixes this for wheels, but breaks the sdist case (tests
488-
# test_download_metadata). As PyPI is currently only serving
489-
# metadata for wheels, this is not an immediate issue.
490-
# Fixing the problem properly looks like it will require a
491-
# complete refactoring of the `prepare_linked_requirements_more`
492-
# logic, and I haven't a clue where to start on that, so for now
493-
# I have fixed the issue *just* for wheels.
494-
if req.is_wheel:
495-
self._downloaded[req.link.url] = filepath
487+
# Record that the file is downloaded so we don't do it again in
488+
# _prepare_linked_requirement().
489+
self._downloaded[req.link.url] = filepath
490+
491+
# If this is an sdist, we need to unpack it and set the .source_dir
492+
# immediately after downloading, as _prepare_linked_requirement() assumes
493+
# the req is either not downloaded at all, or both downloaded and
494+
# unpacked. The downloading and unpacking is is typically done with
495+
# unpack_url(), but we separate the downloading and unpacking steps here in
496+
# order to use the BatchDownloader.
497+
if not req.is_wheel:
498+
hashes = self._get_linked_req_hashes(req)
499+
assert filepath == _check_download_dir(req.link, temp_dir, hashes)
500+
self._ensure_link_req_src_dir(req, parallel_builds)
501+
unpack_file(filepath, req.source_dir)
502+
reqs_with_newly_unpacked_source_dirs.add(req.link)
496503

497504
# This step is necessary to ensure all lazy wheels are processed
498505
# successfully by the 'download', 'wheel', and 'install' commands.
499506
for req in partially_downloaded_reqs:
500-
self._prepare_linked_requirement(req, parallel_builds)
507+
self._prepare_linked_requirement(
508+
req,
509+
parallel_builds,
510+
source_dir_exists_already=req.link
511+
in reqs_with_newly_unpacked_source_dirs,
512+
)
501513

502514
def prepare_linked_requirement(
503515
self, req: InstallRequirement, parallel_builds: bool = False
@@ -568,7 +580,10 @@ def prepare_linked_requirements_more(
568580
)
569581

570582
def _prepare_linked_requirement(
571-
self, req: InstallRequirement, parallel_builds: bool
583+
self,
584+
req: InstallRequirement,
585+
parallel_builds: bool,
586+
source_dir_exists_already: bool = False,
572587
) -> BaseDistribution:
573588
assert req.link
574589
link = req.link
@@ -600,7 +615,8 @@ def _prepare_linked_requirement(
600615
req.link = req.cached_wheel_source_link
601616
link = req.link
602617

603-
self._ensure_link_req_src_dir(req, parallel_builds)
618+
if not source_dir_exists_already:
619+
self._ensure_link_req_src_dir(req, parallel_builds)
604620

605621
if link.is_existing_dir():
606622
local_file = None

0 commit comments

Comments
 (0)