| --- a/Lib/test/support.py Mon Jul 30 00:01:44 2012 +0200 |
| +++ b/Lib/test/support.py Thu Aug 02 08:43:32 2012 -0600 |
| @@ -225,18 +225,79 @@ |
| 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 cannot use os.stat as it opens a handle to the pathname |
| + # (if it has not already been removed) that we are waiting to |
| + # remove, thus causing it to not be removed. |
| + # |
| + # Hence just use the contents of the directory for testing for |
| + # existence. |
| + 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: |
| + # The directory need not exist. |
| if error.errno != errno.ENOENT: |
| raise |