From a444cd1e1cb46caf8ca8be923b3ea405c7f1fc1e Mon Sep 17 00:00:00 2001
From: Yonggang Luo <luoyonggang@gmail.com>
Date: Wed, 22 Feb 2012 10:53:52 +0800
Subject: [PATCH] utils.py Use onerror deal with rmtree

---
 test/utils.py | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/test/utils.py b/test/utils.py
index 8dbaf63..421f928 100644
--- a/test/utils.py
+++ b/test/utils.py
@@ -40,6 +40,12 @@ import pygit2
 
 __author__ = 'dborowitz@google.com (Dave Borowitz)'
 
+def force_rm_handle(remove_path, path, excinfo):
+    os.chmod(
+        path,
+        os.stat(path).st_mode | stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH
+    )
+    remove_path(path)
 
 def oid_to_hex(oid):
     return b2a_hex(oid).decode('ascii')
@@ -49,16 +55,8 @@ def rmtree(path):
     """In Windows a read-only file cannot be removed, and shutil.rmtree fails.
     So we implement our own version of rmtree to address this issue.
     """
-    for root, dirs, files in os.walk(path, topdown=False):
-        for name in files:
-            filename = os.path.join(root, name)
-            try:
-                os.remove(filename)
-            except OSError:
-                # Try again
-                os.chmod(filename, stat.S_IWUSR)
-                os.remove(filename)
-        os.rmdir(root)
+    if os.path.exists(path):
+        shutil.rmtree(path, onerror=lambda func, path, e: force_rm_handle(func, path, e))
 
 
 class NoRepoTestCase(unittest.TestCase):