]> granicus.if.org Git - python/commitdiff
Issue #25860: os.fwalk() no longer skips remaining directories when error occurs.
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 22 Dec 2015 22:08:24 +0000 (00:08 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Tue, 22 Dec 2015 22:08:24 +0000 (00:08 +0200)
Original patch by Samson Lee.

Lib/os.py
Lib/test/test_os.py
Misc/NEWS

index 2b89b93d6397289f4b27050c3e04fffc59cdbfb7..13a42c331e783513c1dfc20ea521b2b388fa0e4d 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -514,7 +514,7 @@ if {open, stat} <= supports_dir_fd and {listdir, stat} <= supports_fd:
             except OSError as err:
                 if onerror is not None:
                     onerror(err)
-                return
+                continue
             try:
                 if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
                     dirpath = path.join(toppath, name)
index 618c18abedd390864ab0a5f84a0a375a311ffd94..6c95ec7e1484427ce8a3b328afc3852686523c0b 100644 (file)
@@ -791,12 +791,8 @@ class WalkTests(unittest.TestCase):
 
     # Wrapper to hide minor differences between os.walk and os.fwalk
     # to tests both functions with the same code base
-    def walk(self, directory, topdown=True, follow_symlinks=False):
-        walk_it = os.walk(directory,
-                          topdown=topdown,
-                          followlinks=follow_symlinks)
-        for root, dirs, files in walk_it:
-            yield (root, dirs, files)
+    def walk(self, directory, **kwargs):
+        return os.walk(directory, **kwargs)
 
     def setUp(self):
         join = os.path.join
@@ -926,16 +922,29 @@ class WalkTests(unittest.TestCase):
                     os.remove(dirname)
         os.rmdir(support.TESTFN)
 
+    def test_walk_bad_dir(self):
+        # Walk top-down.
+        errors = []
+        walk_it = self.walk(self.walk_path, onerror=errors.append)
+        root, dirs, files = next(walk_it)
+        self.assertFalse(errors)
+        dir1 = dirs[0]
+        dir1new = dir1 + '.new'
+        os.rename(os.path.join(root, dir1), os.path.join(root, dir1new))
+        roots = [r for r, d, f in walk_it]
+        self.assertTrue(errors)
+        self.assertNotIn(os.path.join(root, dir1), roots)
+        self.assertNotIn(os.path.join(root, dir1new), roots)
+        for dir2 in dirs[1:]:
+            self.assertIn(os.path.join(root, dir2), roots)
+
 
 @unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()")
 class FwalkTests(WalkTests):
     """Tests for os.fwalk()."""
 
-    def walk(self, directory, topdown=True, follow_symlinks=False):
-        walk_it = os.fwalk(directory,
-                           topdown=topdown,
-                           follow_symlinks=follow_symlinks)
-        for root, dirs, files, root_fd in walk_it:
+    def walk(self, directory, **kwargs):
+        for root, dirs, files, root_fd in os.fwalk(directory, **kwargs):
             yield (root, dirs, files)
 
 
index 3257aa4a033759aac223571da19b6251d46010ea..9aa67bfe721fba0ed3fbb00798750203e59e6f5f 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -28,6 +28,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #25860: os.fwalk() no longer skips remaining directories when error
+  occurs.  Original patch by Samson Lee.
+
 - Issue #25914: Fixed and simplified OrderedDict.__sizeof__.
 
 - Issue #25902: Fixed various refcount issues in ElementTree iteration.