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