os.walk() works differently from pathlib.Path.walk(): Even when followlinks is False (the default), os.walk() appends symlinks to directories to dirs instead of nondirs (so does os.fwalk()), while pathlib.Path.walk() correctly treats symlinks to directories as nondirs. This unintuitive behavior was reported 14 years ago (GH-57179), and has been documented since 2022.
Python 3.12 introduced pathlib.Path.walk(), which corrected this unintuitive behavior with a new API, but os.walk() and os.fwalk() remained unchanged.
In 2024, to fix a recursion error in shutil.rmtree(), a new os._walk_symlinks_as_files sentinel for the followlinks parameter of os.walk() was added to Python 3.14 (GH-119634), and was backported to Python 3.13 and 3.12. This effectively provided a way to avoid the unintuitive behavior. Later, pathlib.Path.walk() was changed to use os.walk() with os._walk_symlinks_as_files instead of its own implementation (GH-119573). However, os.fwalk() remained unchanged.
In my opinion, we can make this sentinel public, allowing users to write something like os.walk(some_dir, followlinks=os.walk_symlinks_as_files) to get the same behavior as pathlib’s. If so, there are two questions:
- Is there a better name for
os._walk_symlinks_as_files? - Should we make
os.fwalk()support this sentinel as well, to ensure consistency betweenos.walk()andos.fwalk()?