Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8acbb93

Browse files
bpo-43292: Fix file leak in ET.iterparse() when not exhausted (GH-31696)
Co-authored-by: Serhiy Storchaka <[email protected]> (cherry picked from commit 496c428) Co-authored-by: Jacob Walls <[email protected]>
1 parent ee18df4 commit 8acbb93

File tree

4 files changed

+20
-7
lines changed

4 files changed

+20
-7
lines changed

Lib/test/test_xml_etree.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,14 @@ def test_iterparse(self):
658658
'junk after document element: line 1, column 12')
659659
del cm, it
660660

661+
# Not exhausting the iterator still closes the resource (bpo-43292)
662+
with warnings_helper.check_no_resource_warning(self):
663+
it = iterparse(TESTFN)
664+
del it
665+
666+
with self.assertRaises(FileNotFoundError):
667+
iterparse("nonexistent")
668+
661669
def test_writefile(self):
662670
elem = ET.Element("tag")
663671
elem.text = "text"

Lib/xml/etree/ElementTree.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,8 +1248,14 @@ def iterparse(source, events=None, parser=None):
12481248
# Use the internal, undocumented _parser argument for now; When the
12491249
# parser argument of iterparse is removed, this can be killed.
12501250
pullparser = XMLPullParser(events=events, _parser=parser)
1251-
def iterator():
1251+
1252+
def iterator(source):
1253+
close_source = False
12521254
try:
1255+
if not hasattr(source, "read"):
1256+
source = open(source, "rb")
1257+
close_source = True
1258+
yield None
12531259
while True:
12541260
yield from pullparser.read_events()
12551261
# load event buffer
@@ -1265,16 +1271,12 @@ def iterator():
12651271
source.close()
12661272

12671273
class IterParseIterator(collections.abc.Iterator):
1268-
__next__ = iterator().__next__
1274+
__next__ = iterator(source).__next__
12691275
it = IterParseIterator()
12701276
it.root = None
12711277
del iterator, IterParseIterator
12721278

1273-
close_source = False
1274-
if not hasattr(source, "read"):
1275-
source = open(source, "rb")
1276-
close_source = True
1277-
1279+
next(it)
12781280
return it
12791281

12801282

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,6 +1870,7 @@ Wojtek Walczak
18701870
Charles Waldman
18711871
Richard Walker
18721872
Larry Wall
1873+
Jacob Walls
18731874
Kevin Walzer
18741875
Rodrigo Steinmuller Wanderley
18751876
Dingyuan Wang
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the
2+
iterator is not exhausted. Patch by Jacob Walls.

0 commit comments

Comments
 (0)