diff --git a/Doc/lib/libos.tex b/Doc/lib/libos.tex index dd492bbd5fd..074d3320a59 100644 --- a/Doc/lib/libos.tex +++ b/Doc/lib/libos.tex @@ -1054,7 +1054,8 @@ which is used to set the access and modified times, respectively. Availability: Macintosh, \UNIX, Windows. \end{funcdesc} -\begin{funcdesc}{walk}{top\optional{, topdown\code{=True}}} +\begin{funcdesc}{walk}{top\optional{, topdown\code{=True} + \optional{, onerror\code{=None}}}} \index{directory!walking} \index{directory!traversal} \function{walk()} generates the file names in a directory tree, by @@ -1087,6 +1088,13 @@ about directories the caller creates or renames before it resumes false is ineffective, because in bottom-up mode the directories in \var{dirnames} are generated before \var{dirnames} itself is generated. +By default errors from the \code{os.listdir()} call are ignored. If +optional argument \var{onerror} is specified, it should be a function; +it will be called with one argument, an os.error instance. It can +report the error to continue with the walk, or raise the exception +to abort the walk. Note that the filename is available as the +\code{filename} attribute of the exception object. + \begin{notice} If you pass a relative pathname, don't change the current working directory between resumptions of \function{walk()}. \function{walk()} diff --git a/Lib/os.py b/Lib/os.py index 69d1a44c852..e493ad071c1 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -203,7 +203,7 @@ def renames(old, new): __all__.extend(["makedirs", "removedirs", "renames"]) -def walk(top, topdown=True): +def walk(top, topdown=True, onerror=None): """Directory tree generator. For each directory in the directory tree rooted at top (including top @@ -232,6 +232,13 @@ def walk(top, topdown=True): dirnames have already been generated by the time dirnames itself is generated. + By default errors from the os.listdir() call are ignored. If + optional arg 'onerror' is specified, it should be a function; it + will be called with one argument, an os.error instance. It can + report the error to continue with the walk, or raise the exception + to abort the walk. Note that the filename is available as the + filename attribute of the exception object. + 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 @@ -259,7 +266,9 @@ def walk(top, topdown=True): # Note that listdir and error are globals in this module due # to earlier import-*. names = listdir(top) - except error: + except error, err: + if onerror is not None: + onerror(err) return dirs, nondirs = [], [] @@ -274,7 +283,7 @@ def walk(top, topdown=True): for name in dirs: path = join(top, name) if not islink(path): - for x in walk(path, topdown): + for x in walk(path, topdown, onerror): yield x if not topdown: yield top, dirs, nondirs diff --git a/Misc/NEWS b/Misc/NEWS index d8a95a29676..26b543bc992 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -38,6 +38,9 @@ Extension modules Library ------- +- Added optional 'onerror' argument to os.walk(), to control error + handling. + - inspect.is{method|data}descriptor was added, to allow pydoc display __doc__ of data descriptors.