[3.9] bpo-43292: Fix file leak in `ET.iterparse()` when not exhausted (GH-31696) (GH-31720)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
(cherry picked from commit 496c428de3)

Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
This commit is contained in:
Miss Islington (bot) 2022-03-07 03:48:53 -08:00 committed by GitHub
parent 7fba55f15a
commit 852d9b77ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 7 deletions

View File

@ -640,6 +640,14 @@ def test_iterparse(self):
'junk after document element: line 1, column 12')
del cm, it
# Not exhausting the iterator still closes the resource (bpo-43292)
with support.check_no_resource_warning(self):
it = iterparse(TESTFN)
del it
with self.assertRaises(FileNotFoundError):
iterparse("nonexistent")
def test_writefile(self):
elem = ET.Element("tag")
elem.text = "text"

View File

@ -1248,8 +1248,14 @@ def iterparse(source, events=None, parser=None):
# Use the internal, undocumented _parser argument for now; When the
# parser argument of iterparse is removed, this can be killed.
pullparser = XMLPullParser(events=events, _parser=parser)
def iterator():
def iterator(source):
close_source = False
try:
if not hasattr(source, "read"):
source = open(source, "rb")
close_source = True
yield None
while True:
yield from pullparser.read_events()
# load event buffer
@ -1265,16 +1271,12 @@ def iterator():
source.close()
class IterParseIterator(collections.abc.Iterator):
__next__ = iterator().__next__
__next__ = iterator(source).__next__
it = IterParseIterator()
it.root = None
del iterator, IterParseIterator
close_source = False
if not hasattr(source, "read"):
source = open(source, "rb")
close_source = True
next(it)
return it

View File

@ -1836,6 +1836,7 @@ Wojtek Walczak
Charles Waldman
Richard Walker
Larry Wall
Jacob Walls
Kevin Walzer
Rodrigo Steinmuller Wanderley
Dingyuan Wang

View File

@ -0,0 +1,2 @@
Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the
iterator is not exhausted. Patch by Jacob Walls.