xml.dom.pulldom.DOMEventStream leaks file handles opened by parse()
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 77.2k
- Fork
- 35.9k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
pulldom.parse() opens a file when called with a filename string, but the resulting DOMEventStream never closes it. The class has no close() method, no context manager support, and clear() just sets self.stream = None without closing.
This produces ResourceWarning: unclosed file and can lead to file descriptor exhaustion in long-running processes.
The documentation example at https://docs.python.org/3/library/xml.dom.pulldom.html#module-xml.dom.pulldom shows:
doc = pulldom.parse('sales_items.xml')
for event, node in doc:
...
— with no cleanup, so users following the docs will hit this.
Reproduction
import warnings, tempfile, os, gc
from xml.dom import pulldom
warnings.simplefilter('always', ResourceWarning)
fd, path = tempfile.mkstemp(suffix='.xml')
os.write(fd, b'<root><item>test</item></root>')
os.close(fd)
events = pulldom.parse(path)
for event, node in events:
pass
# stream is still open after full iteration
print(f'stream.closed: {events.stream.closed}') # False
# clear() doesn't close it either
events.clear()
del events
gc.collect() # ResourceWarning: unclosed file ...
os.unlink(path)
The existing test in test_pulldom.py already works around this with self.addCleanup(handler.stream.close) (line 36), which further confirms the leak.
Suggested fix
Track whether parse() opened the file (vs. receiving a user-provided stream), then add close(), __enter__/__exit__, and __del__ with ResourceWarning to DOMEventStream. Update clear() to close owned streams.
This follows the same approach used for ElementTree.iterparse() (gh-140601).
Linked PRs
- gh-148437
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia con DOMEventStream e pulldom.parse(), quindi esamina test_pulldom.py, in particolare la pulizia esistente intorno alla riga 36. Riproduci la ResourceWarning e verifica il comportamento di ownership per filename e gli stream forniti dall’utente. Il lavoro è completato quando la pulizia del ciclo di vita e il comportamento del context manager sono coperti dai test senza perdite di handle.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- backend
- Tipo di issue
- Bug
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Stato di attività
- Ferma
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 35/100