aggieNick02
aggieNick02

Reputation: 2787

Are either of os.rmdir or shutil.rmtree guaranteed or supposed to be synchronous on Windows?

It appears that shutil.rmtree is not synchronous on Windows, as I've had the second line in the following code raise an error that the directory already exists

shutil.rmtree(my_dir)
os.makedirs(my_dir) #intermittently raises Windows error 183 - already exists

We see a similar issue in .NET on windows - see this question . Are there any good options to deal with this in python other than polling to see if the folder really is gone?

Upvotes: 2

Views: 3311

Answers (2)

Asad-ullah Khan
Asad-ullah Khan

Reputation: 1853

Simple solution that worked for me:

if os.path.isdir(destination):
    shutil.rmtree(destination)
while os.path.isdir(destination):
    pass
<other code>

Upvotes: 3

ShadowRanger
ShadowRanger

Reputation: 155536

If you're okay with the folder still existing, and you're on Python 3, you can do pass exist_ok=True to os.makedirs, and it will ignore the case where you try to make a directory that already exists:

shutil.rmtree(my_dir)
os.makedirs(my_dir, exist_ok=True)

Failing that, you're stuck polling. Run your code in a loop (ideally with a small sleep to avoid hammering the disk), and don't end the loop until the makedirs finishes without error:

import errno, os, shutil, time

while True:
    # Blow away directory
    shutil.rmtree(my_dir, ignore_errors=True)
    try:
        # Try to recreate
        os.makedirs(my_dir)
    except OSError as e:
        # If problem is that directory still exists, wait a bit and try again
        if e.winerror == 183:
            time.sleep(0.01)
            continue
        # Otherwise, unrecognized error, let it propagate
        raise
    else:
        # Successfully created empty dir, exit loop
        break

On Python 3.3+, you can probably change:

    except WindowsError as e:
        # If problem is that directory still exists, wait a bit and try again
        if e.errno == errno.EEXIST:
            time.sleep(0.01)
            continue
        # Otherwise, unrecognized error, let it propagate
        raise

to just:

    except FileExistsError:
        # If problem is that directory still exists, wait a bit and try again
        time.sleep(0.01)

as there is a specific exception type for "file exists" which you can catch directly (and let all other OSError/WindowsError exceptions propagate without interruption).

Upvotes: 2

Related Questions