summaryrefslogtreecommitdiffstats
path: root/Doc/library/pathlib.rst
diff options
context:
space:
mode:
authorStanislav Zmiev <zertarx@gmail.com>2022-07-22 23:55:46 (GMT)
committerGitHub <noreply@github.com>2022-07-22 23:55:46 (GMT)
commitc1e929858ad96fc6e41bc637e5ec9343b4f7e3c7 (patch)
tree29ed6ea80acdbb4b670282f391adaac75fea1a38 /Doc/library/pathlib.rst
parente4d3a96a113070fde433834a6c9fb79ebeebad4a (diff)
downloadcpython-c1e929858ad96fc6e41bc637e5ec9343b4f7e3c7.zip
cpython-c1e929858ad96fc6e41bc637e5ec9343b4f7e3c7.tar.gz
cpython-c1e929858ad96fc6e41bc637e5ec9343b4f7e3c7.tar.bz2
gh-90385: Add `pathlib.Path.walk()` method (GH-92517)
Automerge-Triggered-By: GH:brettcannon
Diffstat (limited to 'Doc/library/pathlib.rst')
-rw-r--r--Doc/library/pathlib.rst96
1 files changed, 96 insertions, 0 deletions
diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst
index 0454918..19944bd 100644
--- a/Doc/library/pathlib.rst
+++ b/Doc/library/pathlib.rst
@@ -946,6 +946,101 @@ call fails (for example because the path doesn't exist).
to the directory after creating the iterator, whether a path object for
that file be included is unspecified.
+.. method:: Path.walk(top_down=True, on_error=None, follow_symlinks=False)
+
+ Generate the file names in a directory tree by walking the tree
+ either top-down or bottom-up.
+
+ For each directory in the directory tree rooted at *self* (including
+ *self* but excluding '.' and '..'), the method yields a 3-tuple of
+ ``(dirpath, dirnames, filenames)``.
+
+ *dirpath* is a :class:`Path` to the directory currently being walked,
+ *dirnames* is a list of strings for the names of subdirectories in *dirpath*
+ (excluding ``'.'`` and ``'..'``), and *filenames* is a list of strings for
+ the names of the non-directory files in *dirpath*. To get a full path
+ (which begins with *self*) to a file or directory in *dirpath*, do
+ ``dirpath / name``. Whether or not the lists are sorted is file
+ system-dependent.
+
+ If the optional argument *top_down* is true (which is the default), the triple for a
+ directory is generated before the triples for any of its subdirectories
+ (directories are walked top-down). If *top_down* is false, the triple
+ for a directory is generated after the triples for all of its subdirectories
+ (directories are walked bottom-up). No matter the value of *top_down*, the
+ list of subdirectories is retrieved before the triples for the directory and
+ its subdirectories are walked.
+
+ When *top_down* is true, the caller can modify the *dirnames* list in-place
+ (for example, using :keyword:`del` or slice assignment), and :meth:`Path.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,
+ or even to inform :meth:`Path.walk` about directories the caller creates or
+ renames before it resumes :meth:`Path.walk` again. Modifying *dirnames* when
+ *top_down* is false has no effect on the behavior of :meth:`Path.walk()` since the
+ directories in *dirnames* have already been generated by the time *dirnames*
+ is yielded to the caller.
+
+ By default, errors from :func:`os.scandir` are ignored. If the optional
+ argument *on_error* is specified, it should be a callable; it will be
+ called with one argument, an :exc:`OSError` instance. The callable can handle the
+ error to continue the walk or re-raise it to stop the walk. Note that the
+ filename is available as the ``filename`` attribute of the exception object.
+
+ By default, :meth:`Path.walk` does not follow symbolic links, and instead adds them
+ to the *filenames* list. Set *follow_symlinks* to true to resolve symlinks
+ and place them in *dirnames* and *filenames* as appropriate for their targets, and
+ consequently visit directories pointed to by symlinks (where supported).
+
+ .. note::
+
+ Be aware that setting *follow_symlinks* to true can lead to infinite
+ recursion if a link points to a parent directory of itself. :meth:`Path.walk`
+ does not keep track of the directories it has already visited.
+
+ .. note::
+ :meth:`Path.walk` assumes the directories it walks are not modified during
+ execution. For example, if a directory from *dirnames* has been replaced
+ with a symlink and *follow_symlinks* is false, :meth:`Path.walk` will
+ still try to descend into it. To prevent such behavior, remove directories
+ from *dirnames* as appropriate.
+
+ .. note::
+
+ Unlike :func:`os.walk`, :meth:`Path.walk` lists symlinks to directories in
+ *filenames* if *follow_symlinks* is false.
+
+ This example displays the number of bytes used by all files in each directory,
+ while ignoring ``__pycache__`` directories::
+
+ from pathlib import Path
+ for root, dirs, files in Path("cpython/Lib/concurrent").walk(on_error=print):
+ print(
+ root,
+ "consumes",
+ sum((root / file).stat().st_size for file in files),
+ "bytes in",
+ len(files),
+ "non-directory files"
+ )
+ if '__pycache__' in dirs:
+ dirs.remove('__pycache__')
+
+ This next example is a simple implementation of :func:`shutil.rmtree`.
+ Walking the tree bottom-up is essential as :func:`rmdir` doesn't allow
+ deleting a directory before it is empty::
+
+ # Delete everything reachable from the directory "top".
+ # CAUTION: This is dangerous! For example, if top == Path('/'),
+ # it could delete all of your files.
+ for root, dirs, files in top.walk(topdown=False):
+ for name in files:
+ (root / name).unlink()
+ for name in dirs:
+ (root / name).rmdir()
+
+ .. versionadded:: 3.12
+
.. method:: Path.lchmod(mode)
Like :meth:`Path.chmod` but, if the path points to a symbolic link, the
@@ -1285,6 +1380,7 @@ Below is a table mapping various :mod:`os` functions to their corresponding
:func:`os.path.expanduser` :meth:`Path.expanduser` and
:meth:`Path.home`
:func:`os.listdir` :meth:`Path.iterdir`
+:func:`os.walk` :meth:`Path.walk`
:func:`os.path.isdir` :meth:`Path.is_dir`
:func:`os.path.isfile` :meth:`Path.is_file`
:func:`os.path.islink` :meth:`Path.is_symlink`