Closes #7334: close source files on ElementTree.parse and iterparse (partial backport of issue #10093 from 3.2).
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 4311ba2..c368e14 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -2915,19 +2915,25 @@
"class ElementTree(ET.ElementTree):\n" /* public */
" def parse(self, source, parser=None):\n"
+ " close_source = False\n"
" if not hasattr(source, 'read'):\n"
" source = open(source, 'rb')\n"
- " if parser is not None:\n"
- " while 1:\n"
- " data = source.read(65536)\n"
- " if not data:\n"
- " break\n"
- " parser.feed(data)\n"
- " self._root = parser.close()\n"
- " else:\n"
- " parser = cElementTree.XMLParser()\n"
- " self._root = parser._parse(source)\n"
- " return self._root\n"
+ " close_source = False\n"
+ " try:\n"
+ " if parser is not None:\n"
+ " while 1:\n"
+ " data = source.read(65536)\n"
+ " if not data:\n"
+ " break\n"
+ " parser.feed(data)\n"
+ " self._root = parser.close()\n"
+ " else:\n"
+ " parser = cElementTree.XMLParser()\n"
+ " self._root = parser._parse(source)\n"
+ " return self._root\n"
+ " finally:\n"
+ " if close_source:\n"
+ " source.close()\n"
"cElementTree.ElementTree = ElementTree\n"
"def iter(node, tag=None):\n" /* helper */
@@ -2957,8 +2963,10 @@
"class iterparse(object):\n"
" root = None\n"
" def __init__(self, file, events=None):\n"
+ " self._close_file = False\n"
" if not hasattr(file, 'read'):\n"
" file = open(file, 'rb')\n"
+ " self._close_file = True\n"
" self._file = file\n"
" self._events = []\n"
" self._index = 0\n"
@@ -2973,6 +2981,8 @@
" except IndexError:\n"
" if self._parser is None:\n"
" self.root = self._root\n"
+ " if self._close_file:\n"
+ " self._file.close()\n"
" raise StopIteration\n"
" # load event buffer\n"
" del self._events[:]\n"