Repository navigation
FileFinder._find_children can loop forever on a persistently failing directory scan #155935
Copy link
Copy link
Open
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-importlibtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
- Location:
Lib/importlib/_bootstrap_external.py:1469(inside awhile True:loop, backing the newPathEntryFinder.discover()API, added 2026 via IntroduceMetaPathFinder.discoverandPathEntryFinder.discover#139899)
cpython/Lib/importlib/_bootstrap_external.py
Lines 1452 to 1472 in 1ad63cc
| def _find_children(self): | |
| with _os.scandir(self.path) as scan_iterator: | |
| while True: | |
| try: | |
| entry = next(scan_iterator) | |
| if entry.name == _PYCACHE: | |
| continue | |
| # packages | |
| if entry.is_dir() and '.' not in entry.name: | |
| yield entry.name | |
| # files | |
| if entry.is_file(): | |
| yield from { | |
| entry.name.removesuffix(suffix) | |
| for suffix, _ in self._loaders | |
| if entry.name.endswith(suffix) | |
| } | |
| except OSError: | |
| pass # ignore exceptions from next(scan_iterator) and os.DirEntry | |
| except StopIteration: | |
| break |
- Problem: Scans a directory via
os.scandir(); anyOSErrorfromnext()or from an entry'sis_dir()/is_file()is caught and ignored without breaking the loop. For a transient single-entry failure this is reasonable (skip and continue). But if the underlying condition is persistent — e.g. an NFS "stale file handle," a disconnected removable volume — every subsequentnext()raises the same error forever, and the loop never terminates: nobreak, no retry limit. - Reproducer (verified): patched
os.scandirto return an iterator whose__next__unconditionally raisesOSErrorforever;finder._find_children()under a 10-secondtimeoutwas killed (exit 124) — confirmed genuine hang. A companion test with a single transient injected error correctly skipped it and returned all real entries, confirming the "skip one bad entry" case works — it's specifically the persistent-failure case that hangs. - Suggested fix: Add a
break(or a bounded retry counter) in theexcept OSError:branch. - Difficulty: Small, but a real hang bug (not just silent data loss) — worth flagging prominently. New code (2026), no existing discussion found.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-importlibtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity