[Python-checkins] cpython: #14773: Fix os.fwalk() failing on dangling symlinks

hynek.schlawack python-checkins at python.org
Tue May 15 16:34:47 CEST 2012


http://hg.python.org/cpython/rev/cbe7560d4443
changeset:   76951:cbe7560d4443
user:        Hynek Schlawack <hs at ox.cx>
date:        Tue May 15 16:32:21 2012 +0200
summary:
  #14773: Fix os.fwalk() failing on dangling symlinks

files:
  Lib/os.py           |  24 +++++++++++++++++-------
  Lib/test/test_os.py |   6 +++++-
  Misc/NEWS           |   2 ++
  3 files changed, 24 insertions(+), 8 deletions(-)


diff --git a/Lib/os.py b/Lib/os.py
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -353,13 +353,23 @@
         names = flistdir(topfd)
         dirs, nondirs = [], []
         for name in names:
-            # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
-            # walk() which reports symlinks to directories as directories. We do
-            # however check for symlinks before recursing into a subdirectory.
-            if st.S_ISDIR(fstatat(topfd, name).st_mode):
-                dirs.append(name)
-            else:
-                nondirs.append(name)
+            try:
+                # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
+                # walk() which reports symlinks to directories as directories.
+                # We do however check for symlinks before recursing into
+                # a subdirectory.
+                if st.S_ISDIR(fstatat(topfd, name).st_mode):
+                    dirs.append(name)
+                else:
+                    nondirs.append(name)
+            except FileNotFoundError:
+                try:
+                    # Add dangling symlinks, ignore disappeared files
+                    if st.S_ISLNK(fstatat(topfd, name, AT_SYMLINK_NOFOLLOW)
+                                .st_mode):
+                        nondirs.append(name)
+                except FileNotFoundError:
+                    continue
 
         if topdown:
             yield toppath, dirs, nondirs, topfd
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -651,6 +651,7 @@
         #         SUB2/             a file kid and a dirsymlink kid
         #           tmp3
         #           link/           a symlink to TESTFN.2
+        #           broken_link
         #       TEST2/
         #         tmp4              a lone file
         walk_path = join(support.TESTFN, "TEST1")
@@ -663,6 +664,8 @@
         link_path = join(sub2_path, "link")
         t2_path = join(support.TESTFN, "TEST2")
         tmp4_path = join(support.TESTFN, "TEST2", "tmp4")
+        link_path = join(sub2_path, "link")
+        broken_link_path = join(sub2_path, "broken_link")
 
         # Create stuff.
         os.makedirs(sub11_path)
@@ -679,7 +682,8 @@
             else:
                 symlink_to_dir = os.symlink
             symlink_to_dir(os.path.abspath(t2_path), link_path)
-            sub2_tree = (sub2_path, ["link"], ["tmp3"])
+            symlink_to_dir('broken', broken_link_path)
+            sub2_tree = (sub2_path, ["link"], ["broken_link", "tmp3"])
         else:
             sub2_tree = (sub2_path, [], ["tmp3"])
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -31,6 +31,8 @@
 Library
 -------
 
+- Issue 14773: Fix os.fwalk() failing on dangling symlinks.
+
 - Issue 14807: move undocumented tarfile.filemode() to stat.filemode() and add
   doc entry. Add tarfile.filemode alias with deprecation warning.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list