@@ -946,6 +946,101 @@ call fails (for example because the path doesn't exist).
946
946
to the directory after creating the iterator, whether a path object for
947
947
that file be included is unspecified.
948
948
949
+ .. method :: Path.walk(top_down=True, on_error=None, follow_symlinks=False)
950
+
951
+ Generate the file names in a directory tree by walking the tree
952
+ either top-down or bottom-up.
953
+
954
+ For each directory in the directory tree rooted at *self * (including
955
+ *self * but excluding '.' and '..'), the method yields a 3-tuple of
956
+ ``(dirpath, dirnames, filenames) ``.
957
+
958
+ *dirpath * is a :class: `Path ` to the directory currently being walked,
959
+ *dirnames * is a list of strings for the names of subdirectories in *dirpath *
960
+ (excluding ``'.' `` and ``'..' ``), and *filenames * is a list of strings for
961
+ the names of the non-directory files in *dirpath *. To get a full path
962
+ (which begins with *self *) to a file or directory in *dirpath *, do
963
+ ``dirpath / name ``. Whether or not the lists are sorted is file
964
+ system-dependent.
965
+
966
+ If the optional argument *top_down * is true (which is the default), the triple for a
967
+ directory is generated before the triples for any of its subdirectories
968
+ (directories are walked top-down). If *top_down * is false, the triple
969
+ for a directory is generated after the triples for all of its subdirectories
970
+ (directories are walked bottom-up). No matter the value of *top_down *, the
971
+ list of subdirectories is retrieved before the triples for the directory and
972
+ its subdirectories are walked.
973
+
974
+ When *top_down * is true, the caller can modify the *dirnames * list in-place
975
+ (for example, using :keyword: `del ` or slice assignment), and :meth: `Path.walk `
976
+ will only recurse into the subdirectories whose names remain in *dirnames *.
977
+ This can be used to prune the search, or to impose a specific order of visiting,
978
+ or even to inform :meth: `Path.walk ` about directories the caller creates or
979
+ renames before it resumes :meth: `Path.walk ` again. Modifying *dirnames * when
980
+ *top_down * is false has no effect on the behavior of :meth: `Path.walk() ` since the
981
+ directories in *dirnames * have already been generated by the time *dirnames *
982
+ is yielded to the caller.
983
+
984
+ By default, errors from :func: `os.scandir ` are ignored. If the optional
985
+ argument *on_error * is specified, it should be a callable; it will be
986
+ called with one argument, an :exc: `OSError ` instance. The callable can handle the
987
+ error to continue the walk or re-raise it to stop the walk. Note that the
988
+ filename is available as the ``filename `` attribute of the exception object.
989
+
990
+ By default, :meth: `Path.walk ` does not follow symbolic links, and instead adds them
991
+ to the *filenames * list. Set *follow_symlinks * to true to resolve symlinks
992
+ and place them in *dirnames * and *filenames * as appropriate for their targets, and
993
+ consequently visit directories pointed to by symlinks (where supported).
994
+
995
+ .. note ::
996
+
997
+ Be aware that setting *follow_symlinks * to true can lead to infinite
998
+ recursion if a link points to a parent directory of itself. :meth: `Path.walk `
999
+ does not keep track of the directories it has already visited.
1000
+
1001
+ .. note ::
1002
+ :meth: `Path.walk ` assumes the directories it walks are not modified during
1003
+ execution. For example, if a directory from *dirnames * has been replaced
1004
+ with a symlink and *follow_symlinks * is false, :meth: `Path.walk ` will
1005
+ still try to descend into it. To prevent such behavior, remove directories
1006
+ from *dirnames * as appropriate.
1007
+
1008
+ .. note ::
1009
+
1010
+ Unlike :func: `os.walk `, :meth: `Path.walk ` lists symlinks to directories in
1011
+ *filenames * if *follow_symlinks * is false.
1012
+
1013
+ This example displays the number of bytes used by all files in each directory,
1014
+ while ignoring ``__pycache__ `` directories::
1015
+
1016
+ from pathlib import Path
1017
+ for root, dirs, files in Path("cpython/Lib/concurrent").walk(on_error=print):
1018
+ print(
1019
+ root,
1020
+ "consumes",
1021
+ sum((root / file).stat().st_size for file in files),
1022
+ "bytes in",
1023
+ len(files),
1024
+ "non-directory files"
1025
+ )
1026
+ if '__pycache__' in dirs:
1027
+ dirs.remove('__pycache__')
1028
+
1029
+ This next example is a simple implementation of :func: `shutil.rmtree `.
1030
+ Walking the tree bottom-up is essential as :func: `rmdir ` doesn't allow
1031
+ deleting a directory before it is empty::
1032
+
1033
+ # Delete everything reachable from the directory "top".
1034
+ # CAUTION: This is dangerous! For example, if top == Path('/'),
1035
+ # it could delete all of your files.
1036
+ for root, dirs, files in top.walk(topdown=False):
1037
+ for name in files:
1038
+ (root / name).unlink()
1039
+ for name in dirs:
1040
+ (root / name).rmdir()
1041
+
1042
+ .. versionadded :: 3.12
1043
+
949
1044
.. method :: Path.lchmod(mode)
950
1045
951
1046
Like :meth: `Path.chmod ` but, if the path points to a symbolic link, the
@@ -1122,8 +1217,8 @@ call fails (for example because the path doesn't exist).
1122
1217
1123
1218
.. method :: Path.rglob(pattern)
1124
1219
1125
- This is like calling :func: ` Path.glob ` with "`` **/ ``" added in front of the
1126
- given relative *pattern *::
1220
+ Glob the given relative * pattern * recursively. This is like calling
1221
+ :func: ` Path.glob ` with "`` **/ ``" added in front of the *pattern *::
1127
1222
1128
1223
>>> sorted(Path().rglob("*.py"))
1129
1224
[PosixPath('build/lib/pathlib.py'),
@@ -1285,6 +1380,7 @@ Below is a table mapping various :mod:`os` functions to their corresponding
1285
1380
:func: `os.path.expanduser ` :meth: `Path.expanduser ` and
1286
1381
:meth: `Path.home `
1287
1382
:func: `os.listdir ` :meth: `Path.iterdir `
1383
+ :func: `os.walk ` :meth: `Path.walk `
1288
1384
:func: `os.path.isdir ` :meth: `Path.is_dir `
1289
1385
:func: `os.path.isfile ` :meth: `Path.is_file `
1290
1386
:func: `os.path.islink ` :meth: `Path.is_symlink `
0 commit comments