mirror of https://github.com/python/cpython
Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.
This commit is contained in:
commit
698068b013
|
@ -561,11 +561,21 @@ class ElementTreeTest(unittest.TestCase):
|
|||
self.assertEqual(res, ['start-ns', 'end-ns'])
|
||||
|
||||
events = ("start", "end", "bogus")
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
with open(SIMPLE_XMLFILE, "rb") as f:
|
||||
with open(SIMPLE_XMLFILE, "rb") as f:
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
iterparse(f, events)
|
||||
self.assertFalse(f.closed)
|
||||
self.assertEqual(str(cm.exception), "unknown event 'bogus'")
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.filterwarnings("always", category=ResourceWarning)
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
iterparse(SIMPLE_XMLFILE, events)
|
||||
self.assertEqual(str(cm.exception), "unknown event 'bogus'")
|
||||
del cm
|
||||
support.gc_collect()
|
||||
self.assertEqual(w, [])
|
||||
|
||||
source = io.BytesIO(
|
||||
b"<?xml version='1.0' encoding='iso-8859-1'?>\n"
|
||||
b"<body xmlns='http://éffbot.org/ns'\n"
|
||||
|
@ -586,6 +596,21 @@ class ElementTreeTest(unittest.TestCase):
|
|||
self.assertEqual(str(cm.exception),
|
||||
'junk after document element: line 1, column 12')
|
||||
|
||||
with open(TESTFN, "wb") as f:
|
||||
f.write(b"<document />junk")
|
||||
it = iterparse(TESTFN)
|
||||
action, elem = next(it)
|
||||
self.assertEqual((action, elem.tag), ('end', 'document'))
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.filterwarnings("always", category=ResourceWarning)
|
||||
with self.assertRaises(ET.ParseError) as cm:
|
||||
next(it)
|
||||
self.assertEqual(str(cm.exception),
|
||||
'junk after document element: line 1, column 12')
|
||||
del cm, it
|
||||
support.gc_collect()
|
||||
self.assertEqual(w, [])
|
||||
|
||||
def test_writefile(self):
|
||||
elem = ET.Element("tag")
|
||||
elem.text = "text"
|
||||
|
|
|
@ -1202,7 +1202,12 @@ def iterparse(source, events=None, parser=None):
|
|||
if not hasattr(source, "read"):
|
||||
source = open(source, "rb")
|
||||
close_source = True
|
||||
return _IterParseIterator(source, events, parser, close_source)
|
||||
try:
|
||||
return _IterParseIterator(source, events, parser, close_source)
|
||||
except:
|
||||
if close_source:
|
||||
source.close()
|
||||
raise
|
||||
|
||||
|
||||
class XMLPullParser:
|
||||
|
@ -1285,20 +1290,26 @@ class _IterParseIterator:
|
|||
self.root = self._root = None
|
||||
|
||||
def __next__(self):
|
||||
while 1:
|
||||
for event in self._parser.read_events():
|
||||
return event
|
||||
if self._parser._parser is None:
|
||||
self.root = self._root
|
||||
if self._close_file:
|
||||
self._file.close()
|
||||
raise StopIteration
|
||||
# load event buffer
|
||||
data = self._file.read(16 * 1024)
|
||||
if data:
|
||||
self._parser.feed(data)
|
||||
else:
|
||||
self._root = self._parser._close_and_return_root()
|
||||
try:
|
||||
while 1:
|
||||
for event in self._parser.read_events():
|
||||
return event
|
||||
if self._parser._parser is None:
|
||||
break
|
||||
# load event buffer
|
||||
data = self._file.read(16 * 1024)
|
||||
if data:
|
||||
self._parser.feed(data)
|
||||
else:
|
||||
self._root = self._parser._close_and_return_root()
|
||||
self.root = self._root
|
||||
except:
|
||||
if self._close_file:
|
||||
self._file.close()
|
||||
raise
|
||||
if self._close_file:
|
||||
self._file.close()
|
||||
raise StopIteration
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
|
Loading…
Reference in New Issue