diff --git a/joblib/disk.py b/joblib/disk.py index 438abeaf1..79f679771 100644 --- a/joblib/disk.py +++ b/joblib/disk.py @@ -10,13 +10,14 @@ import sys import os import shutil +import time def disk_used(path): """ Return the disk usage in a directory. """ size = 0 for file in os.listdir(path) + ['.']: - stat = os.stat(os.path.join(path, file)) + stat = os.stat(os.path.join(path, file)) if hasattr(stat, 'st_blocks'): size += stat.st_blocks * 512 else: @@ -25,16 +26,16 @@ def disk_used(path): size += (stat.st_size // 512 + 1) * 512; # We need to convert to int to avoid having longs on some systems (we # don't want longs to avoid problems we SQLite) - return int(size/1024.) + return int(size / 1024.) def memstr_to_kbytes(text): """ Convert a memory text to it's value in kilobytes. """ kilo = 1024 - units = dict(K=1, M=kilo, G=kilo**2) + units = dict(K=1, M=kilo, G=kilo ** 2) try: - size = int(units[text[-1]]*float(text[:-1])) + size = int(units[text[-1]] * float(text[:-1])) except (KeyError, ValueError): raise ValueError( "Invalid literal for size give: %s (type %s) should be " @@ -42,6 +43,9 @@ def memstr_to_kbytes(text): ) return size +# if a rmtree operation fails in rm_subdirs, wait for this much time (in secs), +# then retry once. if it still fails, raise the exception +RM_SUBDIRS_RETRY_TIME = 0.1 def rm_subdirs(path, onerror=None): """Remove all subdirectories in this path. @@ -67,8 +71,21 @@ def rm_subdirs(path, onerror=None): onerror(os.listdir, path, sys.exc_info()) else: raise - + for name in names: fullname = os.path.join(path, name) if os.path.isdir(fullname): - shutil.rmtree(fullname, False, onerror) + if onerror is not None: + shutil.rmtree(fullname, False, onerror) + else: + # allow the rmtree to fail once, wait and re-try. + # if the error is raised again, fail + err_count = 0 + while True: + try: + shutil.rmtree(fullname, False, None) + break + except os.error, err: + if err_count > 0: raise + err_count += 1 + time.sleep(RM_SUBDIRS_RETRY_TIME)