Skip to content

Commit

Permalink
Fix #15496. Add directory removal helpers to make Windows tests more …
Browse files Browse the repository at this point in the history
…reliable. Patch by Jeremy Kloth
  • Loading branch information
briancurtin committed Aug 13, 2012
1 parent 59db401 commit 6f5c5cb
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
68 changes: 66 additions & 2 deletions Lib/test/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,17 +200,81 @@ def unload(name):
except KeyError:
pass

if sys.platform.startswith("win"):
def _waitfor(func, pathname, waitall=False):
# Peform the operation
func(pathname)
# Now setup the wait loop
if waitall:
dirname = pathname
else:
dirname, name = os.path.split(pathname)
dirname = dirname or '.'
# Check for `pathname` to be removed from the filesystem.
# The exponential backoff of the timeout amounts to a total
# of ~1 second after which the deletion is probably an error
# anyway.
# Testing on a [email protected] shows that usually only 1 iteration is
# required when contention occurs.
timeout = 0.001
while timeout < 1.0:
# Note we are only testing for the existance of the file(s) in
# the contents of the directory regardless of any security or
# access rights. If we have made it this far, we have sufficient
# permissions to do that much using Python's equivalent of the
# Windows API FindFirstFile.
# Other Windows APIs can fail or give incorrect results when
# dealing with files that are pending deletion.
L = os.listdir(dirname)
if not (L if waitall else name in L):
return
# Increase the timeout and try again
time.sleep(timeout)
timeout *= 2
warnings.warn('tests may fail, delete still pending for ' + pathname,
RuntimeWarning, stacklevel=4)

def _unlink(filename):
_waitfor(os.unlink, filename)

def _rmdir(dirname):
_waitfor(os.rmdir, dirname)

def _rmtree(path):
def _rmtree_inner(path):
for name in os.listdir(path):
fullname = os.path.join(path, name)
if os.path.isdir(fullname):
_waitfor(_rmtree_inner, fullname, waitall=True)
os.rmdir(fullname)
else:
os.unlink(fullname)
_waitfor(_rmtree_inner, path, waitall=True)
_waitfor(os.rmdir, path)
else:
_unlink = os.unlink
_rmdir = os.rmdir
_rmtree = shutil.rmtree

def unlink(filename):
try:
os.unlink(filename)
_unlink(filename)
except OSError as error:
# The filename need not exist.
if error.errno not in (errno.ENOENT, errno.ENOTDIR):
raise

def rmdir(dirname):
try:
_rmdir(dirname)
except OSError as error:
# The directory need not exist.
if error.errno != errno.ENOENT:
raise

def rmtree(path):
try:
shutil.rmtree(path)
_rmtree(path)
except OSError as error:
# Unix returns ENOENT, Windows returns ESRCH.
if error.errno not in (errno.ENOENT, errno.ESRCH):
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ Extension Modules
Tests
-----

- Issue #15496: Add directory removal helpers for tests on Windows.
Patch by Jeremy Kloth.

- Issue #15467: Move helpers for __sizeof__ tests into test_support.
Patch by Serhiy Storchaka.

Expand Down

0 comments on commit 6f5c5cb

Please sign in to comment.