@@ -80,6 +80,24 @@ def __getattr__(self, name: str):
8080 return getattr (get_download_manager (), name )
8181
8282
83+ class _PypathDownloadManager (DownloadManager ):
84+ """Finite connect/read waits for shared downloads, including legacy callers."""
85+
86+ def download (self , url , * args , ** kwargs ):
87+ # Requests interprets timeout as socket inactivity, not total transfer
88+ # duration: a large download can continue while it is making progress.
89+ for key , env , default in (
90+ ('connecttimeout' , 'PYPATH_CONNECT_TIMEOUT' , 30 ),
91+ ('timeout' , 'PYPATH_READ_TIMEOUT' , 120 ),
92+ ):
93+ value = float (os .environ .get (env , default ))
94+ if not 0 < value < float ('inf' ):
95+ raise ValueError (f'{ env } must be a finite positive number' )
96+ kwargs .setdefault (key , value )
97+ kwargs .setdefault ('retries' , 1 )
98+ return super ().download (url , * args , ** kwargs )
99+
100+
83101def get_download_manager () -> DownloadManager :
84102 """
85103 Get the shared DownloadManager instance configured with pypath's data folder.
@@ -89,7 +107,7 @@ def get_download_manager() -> DownloadManager:
89107 """
90108 manager = getattr (_thread_local , 'download_manager' , None )
91109 if manager is None :
92- manager = DownloadManager (
110+ manager = _PypathDownloadManager (
93111 path = str (_resolve_data_dir ()),
94112 config = {'backend' : 'requests' },
95113 )
0 commit comments