summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/glob.py37
-rw-r--r--Lib/pathlib/_abc.py32
-rw-r--r--Lib/pathlib/_local.py4
3 files changed, 34 insertions, 39 deletions
diff --git a/Lib/glob.py b/Lib/glob.py
index 920f79a..fbb1d35 100644
--- a/Lib/glob.py
+++ b/Lib/glob.py
@@ -519,43 +519,6 @@ class _Globber:
elif self.lexists(path):
yield path
- @classmethod
- def walk(cls, root, top_down, on_error, follow_symlinks):
- """Walk the directory tree from the given root, similar to os.walk().
- """
- paths = [root]
- while paths:
- path = paths.pop()
- if isinstance(path, tuple):
- yield path
- continue
- try:
- with cls.scandir(path) as scandir_it:
- dirnames = []
- filenames = []
- if not top_down:
- paths.append((path, dirnames, filenames))
- for entry in scandir_it:
- name = entry.name
- try:
- if entry.is_dir(follow_symlinks=follow_symlinks):
- if not top_down:
- paths.append(cls.parse_entry(entry))
- dirnames.append(name)
- else:
- filenames.append(name)
- except OSError:
- filenames.append(name)
- except OSError as error:
- if on_error is not None:
- on_error(error)
- else:
- if top_down:
- yield path, dirnames, filenames
- if dirnames:
- prefix = cls.add_slash(path)
- paths += [cls.concat_path(prefix, d) for d in reversed(dirnames)]
-
class _StringGlobber(_Globber):
lexists = staticmethod(os.path.lexists)
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index 6b5d9fc..d7471b6 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -621,7 +621,37 @@ class PathBase(PurePathBase):
def walk(self, top_down=True, on_error=None, follow_symlinks=False):
"""Walk the directory tree from this directory, similar to os.walk()."""
- return self._globber.walk(self, top_down, on_error, follow_symlinks)
+ paths = [self]
+ while paths:
+ path = paths.pop()
+ if isinstance(path, tuple):
+ yield path
+ continue
+ dirnames = []
+ filenames = []
+ if not top_down:
+ paths.append((path, dirnames, filenames))
+ try:
+ for child in path.iterdir():
+ try:
+ if child.is_dir(follow_symlinks=follow_symlinks):
+ if not top_down:
+ paths.append(child)
+ dirnames.append(child.name)
+ else:
+ filenames.append(child.name)
+ except OSError:
+ filenames.append(child.name)
+ except OSError as error:
+ if on_error is not None:
+ on_error(error)
+ if not top_down:
+ while not isinstance(paths.pop(), tuple):
+ pass
+ continue
+ if top_down:
+ yield path, dirnames, filenames
+ paths += [path.joinpath(d) for d in reversed(dirnames)]
def absolute(self):
"""Return an absolute version of this path
diff --git a/Lib/pathlib/_local.py b/Lib/pathlib/_local.py
index 49d9f81..473fd52 100644
--- a/Lib/pathlib/_local.py
+++ b/Lib/pathlib/_local.py
@@ -672,7 +672,9 @@ class Path(PathBase, PurePath):
"""Walk the directory tree from this directory, similar to os.walk()."""
sys.audit("pathlib.Path.walk", self, on_error, follow_symlinks)
root_dir = str(self)
- results = self._globber.walk(root_dir, top_down, on_error, follow_symlinks)
+ if not follow_symlinks:
+ follow_symlinks = os._walk_symlinks_as_files
+ results = os.walk(root_dir, top_down, on_error, follow_symlinks)
for path_str, dirnames, filenames in results:
if root_dir == '.':
path_str = path_str[2:]