Skip to content

Commit b1f67a4

Browse files
Exhausted or failed iterators are auto-closed.
1 parent dd20441 commit b1f67a4

File tree

2 files changed

+9
-26
lines changed

2 files changed

+9
-26
lines changed

Lib/test/test_xml_etree.py

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,6 @@ def test_iterparse(self):
590590
('end', 'root'),
591591
])
592592
self.assertEqual(context.root.tag, 'root')
593-
context.close()
594593

595594
context = iterparse(SIMPLE_NS_XMLFILE)
596595
self.assertEqual([(action, elem.tag) for action, elem in context], [
@@ -599,7 +598,6 @@ def test_iterparse(self):
599598
('end', '{namespace}empty-element'),
600599
('end', '{namespace}root'),
601600
])
602-
context.close()
603601

604602
with open(SIMPLE_XMLFILE, 'rb') as source:
605603
context = iterparse(source)
@@ -615,12 +613,10 @@ def test_iterparse(self):
615613
events = ()
616614
context = iterparse(SIMPLE_XMLFILE, events)
617615
self.assertEqual([(action, elem.tag) for action, elem in context], [])
618-
context.close()
619616

620617
events = ()
621618
context = iterparse(SIMPLE_XMLFILE, events=events)
622619
self.assertEqual([(action, elem.tag) for action, elem in context], [])
623-
context.close()
624620

625621
events = ("start", "end")
626622
context = iterparse(SIMPLE_XMLFILE, events)
@@ -634,7 +630,6 @@ def test_iterparse(self):
634630
('end', 'empty-element'),
635631
('end', 'root'),
636632
])
637-
context.close()
638633

639634
events = ("start", "end", "start-ns", "end-ns")
640635
context = iterparse(SIMPLE_NS_XMLFILE, events)
@@ -652,7 +647,6 @@ def test_iterparse(self):
652647
('end', '{namespace}root'),
653648
('end-ns', None),
654649
])
655-
context.close()
656650

657651
events = ('start-ns', 'end-ns')
658652
context = iterparse(io.StringIO(r"<root xmlns=''/>"), events)
@@ -698,11 +692,13 @@ def test_iterparse(self):
698692
it = iterparse(TESTFN)
699693
action, elem = next(it)
700694
self.assertEqual((action, elem.tag), ('end', 'document'))
701-
with self.assertRaises(ET.ParseError) as cm:
702-
next(it)
703-
self.assertEqual(str(cm.exception),
704-
'junk after document element: line 1, column 12')
705-
it.close()
695+
with warnings_helper.check_no_resource_warning(self):
696+
with self.assertRaises(ET.ParseError) as cm:
697+
next(it)
698+
self.assertEqual(str(cm.exception),
699+
'junk after document element: line 1, column 12')
700+
del cm, it
701+
gc_collect()
706702

707703
with self.assertRaises(FileNotFoundError):
708704
iterparse("nonexistent")
@@ -711,21 +707,6 @@ def test_iterparse_not_close(self):
711707
# Not closing before del should emit ResourceWarning
712708
iterparse = ET.iterparse
713709

714-
it = iterparse(SIMPLE_XMLFILE)
715-
self.assertEqual([(action, elem.tag) for action, elem in it], [
716-
('end', 'element'),
717-
('end', 'element'),
718-
('end', 'empty-element'),
719-
('end', 'root'),
720-
])
721-
self.assertEqual(it.root.tag, 'root')
722-
with self.assertWarns(ResourceWarning) as wm:
723-
del it
724-
gc_collect()
725-
self.assertIn('unclosed file', str(wm.warning))
726-
self.assertIn(repr(SIMPLE_XMLFILE), str(wm.warning))
727-
self.assertEqual(wm.filename, __file__)
728-
729710
# Not exhausting the iterator still closes the resource (bpo-43292)
730711
with self.assertWarns(ResourceWarning) as wm:
731712
it = iterparse(SIMPLE_XMLFILE)

Lib/xml/etree/ElementTree.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,8 +1255,10 @@ def iterator(source):
12551255
if it is not None:
12561256
it.root = root
12571257
finally:
1258+
nonlocal close_source
12581259
if close_source:
12591260
source.close()
1261+
close_source = False
12601262

12611263
gen = iterator(source)
12621264
class IterParseIterator(collections.abc.Iterator):

0 commit comments

Comments
 (0)