`FileFinder._find_children` can loop forever on a persistently failing directory scan
Open
Nobody has claimed this yet.
stdlib
topic-importlib
type-bug
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
- Location:
Lib/importlib/_bootstrap_external.py:1469(inside awhile True:loop, backing the newPathEntryFinder.discover()API, added 2026 via gh-139899)
- 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
- gh-155939
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in Lib/importlib/_bootstrap_external.py around line 1469, inside FileFinder._find_children’s scan loop. Run the persistent-failure reproducer and the transient-error companion test described in the issue. Done means persistent OSError scanning terminates while a single transient entry failure still allows the remaining entries to be returned.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100