diff --git a/Lib/os.py b/Lib/os.py index 4b48afb040e565..4ee87765ab3976 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -542,7 +542,9 @@ def _fwalk(stack, isbytes, topdown, onerror, follow_symlinks): scandir_it = scandir(topfd) dirs = [] nondirs = [] - entries = None if topdown or follow_symlinks else [] + topprefix = path.join(toppath, toppath[:0]) # Add trailing slash. + if not topdown: + stack.append((_fwalk_yield, (toppath, dirs, nondirs, topfd))) for entry in scandir_it: name = entry.name if isbytes: @@ -550,8 +552,11 @@ def _fwalk(stack, isbytes, topdown, onerror, follow_symlinks): try: if entry.is_dir(): dirs.append(name) - if entries is not None: - entries.append(entry) + if not topdown: + stack.append( + (_fwalk_walk, ( + False, topfd, topprefix + name, name, + None if follow_symlinks else entry))) else: nondirs.append(name) except OSError: @@ -564,18 +569,9 @@ def _fwalk(stack, isbytes, topdown, onerror, follow_symlinks): if topdown: yield toppath, dirs, nondirs, topfd - else: - stack.append((_fwalk_yield, (toppath, dirs, nondirs, topfd))) - - toppath = path.join(toppath, toppath[:0]) # Add trailing slash. - if entries is None: stack.extend( - (_fwalk_walk, (False, topfd, toppath + name, name, None)) + (_fwalk_walk, (False, topfd, topprefix + name, name, None)) for name in dirs[::-1]) - else: - stack.extend( - (_fwalk_walk, (False, topfd, toppath + name, name, entry)) - for name, entry in zip(dirs[::-1], entries[::-1])) __all__.append("fwalk") diff --git a/Misc/NEWS.d/next/Library/2024-07-06-15-31-01.gh-issue-119169.bfpdsr.rst b/Misc/NEWS.d/next/Library/2024-07-06-15-31-01.gh-issue-119169.bfpdsr.rst new file mode 100644 index 00000000000000..38d35871a1407a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-06-15-31-01.gh-issue-119169.bfpdsr.rst @@ -0,0 +1 @@ +Speed up :func:`os.fwalk` in bottom-up mode.