40
40
from pip ._internal .utils .misc import (
41
41
ask_path_exists ,
42
42
backup_dir ,
43
- consume ,
44
43
display_path ,
45
44
format_size ,
46
45
hide_url ,
58
57
59
58
if MYPY_CHECK_RUNNING :
60
59
from typing import (
61
- Any , Callable , IO , List , Optional , Tuple ,
60
+ Callable , Iterable , List , Optional , Tuple ,
62
61
)
63
62
64
63
from mypy_extensions import TypedDict
@@ -122,14 +121,12 @@ def _get_http_response_size(resp):
122
121
return None
123
122
124
123
125
- def _download_url (
124
+ def _prepare_download (
126
125
resp , # type: Response
127
126
link , # type: Link
128
- content_file , # type: IO[Any]
129
- hashes , # type: Optional[Hashes]
130
127
progress_bar # type: str
131
128
):
132
- # type: (...) -> None
129
+ # type: (...) -> Iterable[bytes]
133
130
total_length = _get_http_response_size (resp )
134
131
135
132
if link .netloc == PyPI .file_storage_domain :
@@ -159,27 +156,16 @@ def _download_url(
159
156
else :
160
157
show_progress = False
161
158
162
- def written_chunks (chunks ):
163
- for chunk in chunks :
164
- content_file .write (chunk )
165
- yield chunk
166
-
167
159
progress_indicator = _progress_indicator
168
160
169
161
if show_progress : # We don't show progress on cached responses
170
162
progress_indicator = DownloadProgressProvider (
171
163
progress_bar , max = total_length
172
164
)
173
165
174
- downloaded_chunks = written_chunks (
175
- progress_indicator (
176
- response_chunks (resp , CONTENT_CHUNK_SIZE )
177
- )
166
+ return progress_indicator (
167
+ response_chunks (resp , CONTENT_CHUNK_SIZE )
178
168
)
179
- if hashes :
180
- hashes .check_against_chunks (downloaded_chunks )
181
- else :
182
- consume (downloaded_chunks )
183
169
184
170
185
171
def _copy_file (filename , location , link ):
@@ -215,10 +201,9 @@ def _copy_file(filename, location, link):
215
201
def unpack_http_url (
216
202
link , # type: Link
217
203
location , # type: str
218
- session , # type: PipSession
204
+ downloader , # type: Downloader
219
205
download_dir = None , # type: Optional[str]
220
206
hashes = None , # type: Optional[Hashes]
221
- progress_bar = "on" # type: str
222
207
):
223
208
# type: (...) -> None
224
209
with TempDirectory (kind = "unpack" ) as temp_dir :
@@ -235,7 +220,7 @@ def unpack_http_url(
235
220
else :
236
221
# let's download to a tmp dir
237
222
from_path , content_type = _download_http_url (
238
- link , session , temp_dir .path , hashes , progress_bar
223
+ link , downloader , temp_dir .path , hashes
239
224
)
240
225
241
226
# unpack the archive to the build dir location. even when only
@@ -346,10 +331,9 @@ def unpack_file_url(
346
331
def unpack_url (
347
332
link , # type: Link
348
333
location , # type: str
349
- session , # type: PipSession
334
+ downloader , # type: Downloader
350
335
download_dir = None , # type: Optional[str]
351
336
hashes = None , # type: Optional[Hashes]
352
- progress_bar = "on" # type: str
353
337
):
354
338
# type: (...) -> None
355
339
"""Unpack link.
@@ -379,10 +363,9 @@ def unpack_url(
379
363
unpack_http_url (
380
364
link ,
381
365
location ,
382
- session ,
366
+ downloader ,
383
367
download_dir ,
384
368
hashes = hashes ,
385
- progress_bar = progress_bar
386
369
)
387
370
388
371
@@ -464,28 +447,65 @@ def _http_get_download(session, link):
464
447
return resp
465
448
466
449
450
+ class Download (object ):
451
+ def __init__ (
452
+ self ,
453
+ response , # type: Response
454
+ filename , # type: str
455
+ chunks , # type: Iterable[bytes]
456
+ ):
457
+ # type: (...) -> None
458
+ self .response = response
459
+ self .filename = filename
460
+ self .chunks = chunks
461
+
462
+
463
+ class Downloader (object ):
464
+ def __init__ (
465
+ self ,
466
+ session , # type: PipSession
467
+ progress_bar , # type: str
468
+ ):
469
+ # type: (...) -> None
470
+ self ._session = session
471
+ self ._progress_bar = progress_bar
472
+
473
+ def __call__ (self , link ):
474
+ # type: (Link) -> Download
475
+ try :
476
+ resp = _http_get_download (self ._session , link )
477
+ except requests .HTTPError as e :
478
+ logger .critical (
479
+ "HTTP error %s while getting %s" , e .response .status_code , link
480
+ )
481
+ raise
482
+
483
+ return Download (
484
+ resp ,
485
+ _get_http_response_filename (resp , link ),
486
+ _prepare_download (resp , link , self ._progress_bar ),
487
+ )
488
+
489
+
467
490
def _download_http_url (
468
491
link , # type: Link
469
- session , # type: PipSession
492
+ downloader , # type: Downloader
470
493
temp_dir , # type: str
471
494
hashes , # type: Optional[Hashes]
472
- progress_bar # type: str
473
495
):
474
496
# type: (...) -> Tuple[str, str]
475
497
"""Download link url into temp_dir using provided session"""
476
- try :
477
- resp = _http_get_download (session , link )
478
- except requests .HTTPError as exc :
479
- logger .critical (
480
- "HTTP error %s while getting %s" , exc .response .status_code , link ,
481
- )
482
- raise
498
+ download = downloader (link )
483
499
484
- filename = _get_http_response_filename (resp , link )
485
- file_path = os .path .join (temp_dir , filename )
500
+ file_path = os .path .join (temp_dir , download .filename )
486
501
with open (file_path , 'wb' ) as content_file :
487
- _download_url (resp , link , content_file , hashes , progress_bar )
488
- return file_path , resp .headers .get ('content-type' , '' )
502
+ for chunk in download .chunks :
503
+ content_file .write (chunk )
504
+
505
+ if hashes :
506
+ hashes .check_against_path (file_path )
507
+
508
+ return file_path , download .response .headers .get ('content-type' , '' )
489
509
490
510
491
511
def _check_download_dir (link , download_dir , hashes ):
@@ -538,7 +558,7 @@ def __init__(
538
558
self .src_dir = src_dir
539
559
self .build_dir = build_dir
540
560
self .req_tracker = req_tracker
541
- self .session = session
561
+ self .downloader = Downloader ( session , progress_bar )
542
562
self .finder = finder
543
563
544
564
# Where still-packed archives should be written to. If None, they are
@@ -559,8 +579,6 @@ def __init__(
559
579
# be combined if we're willing to have non-wheel archives present in
560
580
# the wheelhouse output by 'pip wheel'.
561
581
562
- self .progress_bar = progress_bar
563
-
564
582
# Is build isolation allowed?
565
583
self .build_isolation = build_isolation
566
584
@@ -662,9 +680,8 @@ def prepare_linked_requirement(
662
680
663
681
try :
664
682
unpack_url (
665
- link , req .source_dir , self .session , download_dir ,
683
+ link , req .source_dir , self .downloader , download_dir ,
666
684
hashes = hashes ,
667
- progress_bar = self .progress_bar
668
685
)
669
686
except requests .HTTPError as exc :
670
687
logger .critical (
0 commit comments