[Python-checkins] python/dist/src/Lib os.py,1.69,1.70

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Fri, 25 Apr 2003 00:12:20 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv13702/Lib

Modified Files:
	os.py 
Log Message:
New generator os.walk() does a bit more than os.path.walk() does, and
seems much easier to use.  Code, docs, NEWS, and additions to test_os.py
(testing this sucker is a bitch!).


Index: os.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v
retrieving revision 1.69
retrieving revision 1.70
diff -C2 -d -r1.69 -r1.70
*** os.py	27 Feb 2003 20:14:37 -0000	1.69
--- os.py	25 Apr 2003 07:11:48 -0000	1.70
***************
*** 27,30 ****
--- 27,31 ----
  _names = sys.builtin_module_names
  
+ # Note:  more names are added to __all__ later.
  __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
             "defpath", "name", "path"]
***************
*** 159,163 ****
      ones.  Works like rmdir except that, if the leaf directory is
      successfully removed, directories corresponding to rightmost path
!     segments will be pruned way until either the whole path is
      consumed or an error occurs.  Errors during this latter phase are
      ignored -- they generally mean that a directory was not empty.
--- 160,164 ----
      ones.  Works like rmdir except that, if the leaf directory is
      successfully removed, directories corresponding to rightmost path
!     segments will be pruned away until either the whole path is
      consumed or an error occurs.  Errors during this latter phase are
      ignored -- they generally mean that a directory was not empty.
***************
*** 202,205 ****
--- 203,284 ----
  
  __all__.extend(["makedirs", "removedirs", "renames"])
+ 
+ def walk(top, topdown=True):
+     """Directory tree generator.
+ 
+     For each directory in the directory tree rooted at top (including top
+     itself, but excluding '.' and '..'), yields a 3-tuple
+ 
+         dirpath, dirnames, filenames
+ 
+     dirpath is a string, the path to the directory.  dirnames is a list of
+     the names of the subdirectories in dirpath (excluding '.' and '..').
+     filenames is a list of the names of the non-directory files in dirpath.
+     Note that the names in the lists are just names, with no path components.
+     To get a full path (which begins with top) to a file or directory in
+     dirpath, do os.path.join(dirpath, name).
+ 
+     If optional arg 'topdown' is true or not specified, the triple for a
+     directory is generated before the triples for any of its subdirectories
+     (directories are generated top down).  If topdown is false, the triple
+     for a directory is generated after the triples for all of its
+     subdirectories (directories are generated bottom up).
+ 
+     When topdown is true, the caller can modify the dirnames list in-place
+     (e.g., via del or slice assignment), and walk will only recurse into the
+     subdirectories whose names remain in dirnames; this can be used to prune
+     the search, or to impose a specific order of visiting.  Modifying
+     dirnames when topdown is false is ineffective, since the directories in
+     dirnames have already been generated by the time dirnames itself is
+     generated.
+ 
+     Caution:  if you pass a relative pathname for top, don't change the
+     current working directory between resumptions of walk.  walk never
+     changes the current directory, and assumes that the client doesn't
+     either.
+ 
+     Example:
+ 
+     from os.path import join, getsize
+     for root, dirs, files in walk('python/Lib/email'):
+         print root, "consumes",
+         print sum([getsize(join(root, name)) for name in files]),
+         print "bytes in", len(files), "non-directory files"
+         if 'CVS' in dirs:
+             dirs.remove('CVS')  # don't visit CVS directories
+     """
+ 
+     from os.path import join, isdir, islink
+ 
+     # We may not have read permission for top, in which case we can't
+     # get a list of the files the directory contains.  os.path.walk
+     # always suppressed the exception then, rather than blow up for a
+     # minor reason when (say) a thousand readable directories are still
+     # left to visit.  That logic is copied here.
+     try:
+         # Note that listdir and error are globals in this module due
+         # to earlier import-*.
+         names = listdir(top)
+     except error:
+         return
+ 
+     dirs, nondirs = [], []
+     for name in names:
+         if isdir(join(top, name)):
+             dirs.append(name)
+         else:
+             nondirs.append(name)
+ 
+     if topdown:
+         yield top, dirs, nondirs
+     for name in dirs:
+         path = join(top, name)
+         if not islink(path):
+             for x in walk(path, topdown):
+                 yield x
+     if not topdown:
+         yield top, dirs, nondirs
+ 
+ __all__.append("walk")
  
  # Make sure os.environ exists, at least