From 29dbdcdb69324ad7a71cb4823340cf2bb02bdc55 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 7 Apr 2024 08:10:30 +0530 Subject: [PATCH] Make remove_dir_if_empty a bit more robust against other programs simultaneously deleting the dir or its contents. See #2060340 (Unhandled Exception - FileNotFoundError) --- src/calibre/utils/filenames.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index f047ac1dd3..83e3b5d098 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -536,21 +536,26 @@ def remove_dir_if_empty(path, ignore_metadata_caches=False): try: os.rmdir(path) except OSError as e: - if e.errno == errno.ENOTEMPTY or len(os.listdir(path)) > 0: + try: + entries = os.listdir(path) + except FileNotFoundError: # something deleted path out from under us + return + if e.errno == errno.ENOTEMPTY or len(entries) > 0: # Some linux systems appear to raise an EPERM instead of an # ENOTEMPTY, see https://bugs.launchpad.net/bugs/1240797 if ignore_metadata_caches: try: found = False - for x in os.listdir(path): + for x in entries: if x.lower() in {'.ds_store', 'thumbs.db'}: found = True x = os.path.join(path, x) - if os.path.isdir(x): - import shutil - shutil.rmtree(x) - else: - os.remove(x) + with suppress(FileNotFoundError): + if os.path.isdir(x): + import shutil + shutil.rmtree(x) + else: + os.remove(x) except Exception: # We could get an error, if, for example, windows has locked Thumbs.db found = False if found: