New submission from STINNER Victor:
The ElementTree module allows to write a XML parser using Python callbacks. The
module relies on the expat library which is implemented in C. Expat calls these
Python callbacks, but ElementTree does not check if a Python exception was
raised or not.
Example 1:
-------------------
import unittest
from xml.etree import ElementTree as ET
class Target(object):
def start(self, tag, attrib):
print("start")
raise ValueError("raise start")
def end(self, tag):
print("end")
raise ValueError("raise end")
def close(self):
print("close")
raise ValueError("raise close")
parser = ET.XMLParser(target=Target())
parser.feed("<root><test /></root>")
-------------------
Output with Python 3.3:
-------------------
start
startendendTraceback (most recent call last):
File "x.py", line 18, in <module>
parser.feed("<root><test /></root>")
File "x.py", line 10, in end
print("end")
File "x.py", line 10, in end
print("end")
File "x.py", line 6, in start
print("start")
File "x.py", line 7, in start
raise ValueError("raise start")
ValueError: raise start
-------------------
start() was called twice, as end() method, even if the first start() method
raised an exception.
The traceback is strange: it looks like end() was called by start(), which is
wrong.
Example 2:
-------------------
import unittest
from xml.etree import ElementTree as ET
class Target(object):
def start(self, tag, attrib):
raise ValueError("raise start")
def end(self, tag):
raise ValueError("raise end")
def close(self):
raise ValueError("raise close")
parser = ET.XMLParser(target=Target())
parser.feed("<root><test /></root>")
-------------------
Output with Python 3.3:
-------------------
Traceback (most recent call last):
File "x.py", line 15, in <module>
parser.feed("<root><test /></root>")
File "x.py", line 9, in end
raise ValueError("raise end")
ValueError: raise end
-------------------
end() was called even if start() already failed. The exception which was set by
start has been replaced by end() exception.
In my opinion, it's not a good thing to call PyEval_EvalFrameEx() and similar
functions when a Python exception is set, because it behaves badly (ex:
print("end") in Example 1 raises an exception... which is wrong, the traceback
is also corrupted) and may replaces the old exception with a new exception (ex:
"end" replaces "started").
----------
messages: 193325
nosy: haypo
priority: normal
severity: normal
status: open
title: _elementtree.c calls Python callbacks while a Python exception is set
versions: Python 3.4
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue18501>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com