diff options
author | Brian Curtin <brian@python.org> | 2012-08-13 22:12:02 (GMT) |
---|---|---|
committer | Brian Curtin <brian@python.org> | 2012-08-13 22:12:02 (GMT) |
commit | 835df52471421bfc360653422fb24eb6da2a00cf (patch) | |
tree | 80bbc86e005b8ffc0e4604667a7889ea293eacc5 /Lib | |
parent | f334f740e47a8ac1fd5d144813be7380192ac28b (diff) | |
parent | 6f5c5cb75b2fddf31cbb311d2a5508c54f6e21f6 (diff) | |
download | cpython-835df52471421bfc360653422fb24eb6da2a00cf.zip cpython-835df52471421bfc360653422fb24eb6da2a00cf.tar.gz cpython-835df52471421bfc360653422fb24eb6da2a00cf.tar.bz2 |
Merge 3.2
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/support.py | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/Lib/test/support.py b/Lib/test/support.py index f5f574e..35ae76f 100644 --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -225,17 +225,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 i7@4.3GHz 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: if error.errno != errno.ENOENT: raise |