diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py index 2411895d9d12b1..c7eea6034188e5 100644 --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -175,12 +175,8 @@ def test_parse_bytes(self): with self.assertRaises(SAXException): self.check_parse(BytesIO(xml_bytes(self.data, 'iso-8859-1', None))) make_xml_file(self.data, 'iso-8859-1', None) - with support.check_warnings(('unclosed file', ResourceWarning)): - # XXX Failed parser leaks an opened file. - with self.assertRaises(SAXException): - self.check_parse(TESTFN) - # Collect leaked file. - gc.collect() + with self.assertRaises(SAXException): + self.check_parse(TESTFN) with open(TESTFN, 'rb') as f: with self.assertRaises(SAXException): self.check_parse(f) diff --git a/Lib/xml/sax/__init__.py b/Lib/xml/sax/__init__.py index ef67ae67a6bdd3..5f65e315866f3b 100644 --- a/Lib/xml/sax/__init__.py +++ b/Lib/xml/sax/__init__.py @@ -28,9 +28,16 @@ def parse(source, handler, errorHandler=ErrorHandler()): parser = make_parser() - parser.setContentHandler(handler) - parser.setErrorHandler(errorHandler) - parser.parse(source) + try: + parser.setContentHandler(handler) + parser.setErrorHandler(errorHandler) + parser.parse(source) + except: + # Third party parsers can have no close() method + if hasattr(parser, 'close'): + # On error, close the parser to not leak resources like open files + parser.close() + raise def parseString(string, handler, errorHandler=ErrorHandler()): import io