diff --git a/monai/apps/utils.py b/monai/apps/utils.py index 4df1c2107b..35941321a5 100644 --- a/monai/apps/utils.py +++ b/monai/apps/utils.py @@ -238,6 +238,12 @@ def download_url( ContentTooShortError: See urllib.request.urlretrieve. IOError: See urllib.request.urlretrieve. HashCheckError: When the hash validation of the ``url`` downloaded file fails. + PermissionError: When access is denied before the downloaded file has been + moved to ``filepath``, including during destination setup or the move. + NotADirectoryError: When a path component is not a directory before the + downloaded file has been moved to ``filepath``. These filesystem + exceptions remain suppressed during temporary-directory cleanup after + a successful move. .. versionchanged:: 1.7 The default `hash_type` changed from "md5" to None for stronger integrity verification. If this is left None @@ -264,6 +270,7 @@ def download_url( raise HashCheckError(f"{hash_type} hash check of existing file failed: {filepath=}, expected {hash_type=}.") logger.info(f"File exists: {filepath}, skipped downloading.") return + download_complete = False try: with tempfile.TemporaryDirectory() as tmp_dir: tmp_name = Path(tmp_dir, _basename(filepath)) @@ -301,8 +308,11 @@ def download_url( if file_dir: os.makedirs(file_dir, exist_ok=True) shutil.move(f"{tmp_name}", f"{filepath}") # copy the downloaded to a user-specified cache. + download_complete = True except (PermissionError, NotADirectoryError): # project-monai/monai issue #3613 #3757 for windows - pass + # Retain only the historical post-publication cleanup exemption. + if not download_complete: + raise logger.info(f"Downloaded: {filepath}")