[Distutils] sdist.py::findall chokes on broken links

Bastian Kleineidam calvin@cs.uni-sb.de
Fri, 14 Jul 2000 15:56:41 +0200 (CEST)


Hello,

the findall function in sdist.py gives an error when a broken link is
found. The responsible function call is os.stat().

I replaced the stat() calls with os.path.{isfile,islink,isdir}. This is
somewhat more robust. The new findall is now a member function of the
sdist class so I can use self.announce to warn about broken links.

Here is the patch:

diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/sdist.py distutils/distutils/command/sdist.py
--- distutils.orig/distutils/command/sdist.py	Thu Jul 13 01:15:28 2000
+++ distutils/distutils/command/sdist.py	Fri Jul 14 15:47:05 2000
@@ -324,7 +324,7 @@
         containing a Unix-style glob pattern).  If 'pattern' is None, find
         all files under 'dir'.  Return the list of found filenames.
         """
-        allfiles = findall (dir)
+        allfiles = self.findall (dir)
         if pattern is None:
             return allfiles
 
@@ -376,7 +376,7 @@
                              rstrip_ws=1,
                              collapse_ws=1)
 
-        all_files = findall ()
+        all_files = self.findall ()
 
         while 1:
 
@@ -695,43 +695,42 @@
         """
         return self.archive_files
 
-# class sdist
-
+    def findall(self, dir = os.curdir):
+        """Find all files under 'dir' and return the list of full filenames
+        (relative to 'dir').
+        """
+        list = []
+        stack = [dir]
+        pop = stack.pop
+        push = stack.append
 
-# ----------------------------------------------------------------------
-# Utility functions
+        while stack:
+            dir = pop()
+            names = os.listdir (dir)
 
-def findall (dir = os.curdir):
-    """Find all files under 'dir' and return the list of full filenames
-    (relative to 'dir').
-    """
-    from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK
+            for name in names:
+                if dir != os.curdir:   # avoid the dreaded "./" syndrome
+                    fullname = os.path.join (dir, name)
+                else:
+                    fullname = name
 
-    list = []
-    stack = [dir]
-    pop = stack.pop
-    push = stack.append
+                # note: isfile follows symlinks
+                if os.path.isfile(fullname):
+                    list.append (fullname)
+                elif os.path.islink(fullname):
+                    self.announce("warning: link %s is broken" % fullname)
+                elif os.path.isdir(fullname):
+                    push (fullname)
 
-    while stack:
-        dir = pop()
-        names = os.listdir (dir)
+        return list
 
-        for name in names:
-            if dir != os.curdir:        # avoid the dreaded "./" syndrome
-                fullname = os.path.join (dir, name)
-            else:
-                fullname = name
+    # findall
 
-            # Avoid excess stat calls -- just one will do, thank you!
-            stat = os.stat(fullname)
-            mode = stat[ST_MODE]
-            if S_ISREG(mode):
-                list.append (fullname)
-            elif S_ISDIR(mode) and not S_ISLNK(mode):
-                push (fullname)
+# class sdist
 
-    return list
 
+# ----------------------------------------------------------------------
+# Utility functions
 
 def glob_to_re (pattern):
     """Translate a shell-like glob pattern to a regular expression; return