[Python-checkins] cpython (2.7): Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.

serhiy.storchaka python-checkins at python.org
Mon Nov 23 08:47:29 EST 2015


https://hg.python.org/cpython/rev/09a8ac75b351
changeset:   99312:09a8ac75b351
branch:      2.7
parent:      99308:686fa9439d38
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Mon Nov 23 15:46:36 2015 +0200
summary:
  Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.

files:
  Lib/xml/etree/ElementTree.py |  71 +++++++++++++----------
  Misc/NEWS                    |   3 +
  2 files changed, 44 insertions(+), 30 deletions(-)


diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py
--- a/Lib/xml/etree/ElementTree.py
+++ b/Lib/xml/etree/ElementTree.py
@@ -1198,9 +1198,14 @@
     if not hasattr(source, "read"):
         source = open(source, "rb")
         close_source = True
-    if not parser:
-        parser = XMLParser(target=TreeBuilder())
-    return _IterParseIterator(source, events, parser, close_source)
+    try:
+        if not parser:
+            parser = XMLParser(target=TreeBuilder())
+        return _IterParseIterator(source, events, parser, close_source)
+    except:
+        if close_source:
+            source.close()
+        raise
 
 class _IterParseIterator(object):
 
@@ -1252,34 +1257,40 @@
                 raise ValueError("unknown event %r" % event)
 
     def next(self):
-        while 1:
-            try:
-                item = self._events[self._index]
-                self._index += 1
-                return item
-            except IndexError:
-                pass
-            if self._error:
-                e = self._error
-                self._error = None
-                raise e
-            if self._parser is None:
-                self.root = self._root
-                if self._close_file:
-                    self._file.close()
-                raise StopIteration
-            # load event buffer
-            del self._events[:]
-            self._index = 0
-            data = self._file.read(16384)
-            if data:
+        try:
+            while 1:
                 try:
-                    self._parser.feed(data)
-                except SyntaxError as exc:
-                    self._error = exc
-            else:
-                self._root = self._parser.close()
-                self._parser = None
+                    item = self._events[self._index]
+                    self._index += 1
+                    return item
+                except IndexError:
+                    pass
+                if self._error:
+                    e = self._error
+                    self._error = None
+                    raise e
+                if self._parser is None:
+                    self.root = self._root
+                    break
+                # load event buffer
+                del self._events[:]
+                self._index = 0
+                data = self._file.read(16384)
+                if data:
+                    try:
+                        self._parser.feed(data)
+                    except SyntaxError as exc:
+                        self._error = exc
+                else:
+                    self._root = self._parser.close()
+                    self._parser = None
+        except:
+            if self._close_file:
+                self._file.close()
+            raise
+        if self._close_file:
+            self._file.close()
+        raise StopIteration
 
     def __iter__(self):
         return self
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,8 +13,11 @@
 Library
 -------
 
+- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.
+
 - Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data.
 
+
 What's New in Python 2.7.11?
 ============================
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list