Issue #24125: Saved error's line and column numbers when an error is occured

during closing expatreader.  Fixed a regression introduced in issue #23865.
This commit is contained in:
Serhiy Storchaka 2015-05-06 09:35:52 +03:00
parent 69af580131
commit 3234abb9a0
2 changed files with 15 additions and 2 deletions

View File

@ -933,6 +933,8 @@ class ErrorReportingTest(unittest.TestCase):
parser = create_parser() parser = create_parser()
parser.setContentHandler(ContentHandler()) # do nothing parser.setContentHandler(ContentHandler()) # do nothing
self.assertRaises(SAXParseException, parser.parse, StringIO("<foo>")) self.assertRaises(SAXParseException, parser.parse, StringIO("<foo>"))
self.assertEqual(parser.getColumnNumber(), 5)
self.assertEqual(parser.getLineNumber(), 1)
def test_sax_parse_exception_str(self): def test_sax_parse_exception_str(self):
# pass various values from a locator to the SAXParseException to # pass various values from a locator to the SAXParseException to

View File

@ -43,6 +43,9 @@ else:
_mkproxy = weakref.proxy _mkproxy = weakref.proxy
del weakref, _weakref del weakref, _weakref
class _ClosedParser:
pass
# --- ExpatLocator # --- ExpatLocator
class ExpatLocator(xmlreader.Locator): class ExpatLocator(xmlreader.Locator):
@ -214,16 +217,24 @@ class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator):
self._err_handler.fatalError(exc) self._err_handler.fatalError(exc)
def close(self): def close(self):
if self._entity_stack or self._parser is None: if (self._entity_stack or self._parser is None or
isinstance(self._parser, _ClosedParser)):
# If we are completing an external entity, do nothing here # If we are completing an external entity, do nothing here
return return
try: try:
self.feed("", isFinal = 1) self.feed("", isFinal = 1)
self._cont_handler.endDocument() self._cont_handler.endDocument()
finally:
self._parsing = 0 self._parsing = 0
# break cycle created by expat handlers pointing to our methods # break cycle created by expat handlers pointing to our methods
self._parser = None self._parser = None
finally:
self._parsing = 0
if self._parser is not None:
# Keep ErrorColumnNumber and ErrorLineNumber after closing.
parser = _ClosedParser()
parser.ErrorColumnNumber = self._parser.ErrorColumnNumber
parser.ErrorLineNumber = self._parser.ErrorLineNumber
self._parser = parser
def _reset_cont_handler(self): def _reset_cont_handler(self):
self._parser.ProcessingInstructionHandler = \ self._parser.ProcessingInstructionHandler = \