@@ -150,6 +150,7 @@ def __init__(self, url, method="GET", headers={}, outfile=None):
150150 self .proxy_settings = _proxy_settings_from_env ()
151151 self ._on_progress = None
152152 self ._on_auth_request = None
153+ self ._on_cancel = None
153154
154155 def __str__ (self ):
155156 return sanitise_url (self .url )
@@ -167,6 +168,11 @@ def on_auth_request(self, url=None):
167168 return self .username , self .password
168169 return None
169170
171+ def on_cancel (self ):
172+ if self ._on_cancel :
173+ return self ._on_cancel ()
174+ return False
175+
170176
171177def _bits_urlretrieve (request ):
172178 from _native import (coinitialize , bits_connect , bits_begin , bits_cancel ,
@@ -234,6 +240,18 @@ def _bits_urlretrieve(request):
234240 request .on_progress (progress )
235241 last_progress = progress
236242 time .sleep (0.1 )
243+ except KeyboardInterrupt :
244+ request .on_progress (None )
245+ if job and request .on_cancel ():
246+ try :
247+ bits_cancel (bits , job )
248+ except OSError :
249+ LOGGER .warn ("Failed to cancel background download." )
250+ LOGGER .debug ("ERROR:" , exc_info = True )
251+ else :
252+ if jobfile .is_file ():
253+ unlink (jobfile )
254+ raise
237255 except OSError as ex :
238256 if job :
239257 bits_cancel (bits , job )
@@ -542,7 +560,8 @@ def urlopen(url, method="GET", headers={}, on_progress=None, on_auth_request=Non
542560 raise RuntimeError ("Unable to download from the internet" )
543561
544562
545- def urlretrieve (url , outfile , method = "GET" , headers = {}, chunksize = 64 * 1024 , on_progress = None , on_auth_request = None ):
563+ def urlretrieve (url , outfile , method = "GET" , headers = {}, chunksize = 64 * 1024 ,
564+ on_progress = None , on_auth_request = None , on_cancel = None ):
546565 scheme , sep , path = url .partition ("://" )
547566 if not sep :
548567 scheme = "file"
@@ -574,6 +593,7 @@ def on_progress(_): pass
574593 request .chunksize = chunksize
575594 request ._on_progress = on_progress
576595 request ._on_auth_request = on_auth_request
596+ request ._on_cancel = on_cancel
577597
578598 first_error = None
579599
0 commit comments