-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
Destructor of ElementTree.Element is recursive #73057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The Element class in the xml.etree.ElementTree module is a collection. It can contain other Element's. But unlike to common Python collections (list, dict, etc) and pure Python classes, C implementation of Element doesn't support unlimited recursion. As result, destroying very deep Element tree can cause stack overflow. Example: import xml.etree.cElementTree as ElementTree
y = x = ElementTree.Element('x')
for i in range(200000): y = ElementTree.SubElement(y, 'x') del x |
Proposed patch fixes the crash. |
New changeset 957091874ea0 by Serhiy Storchaka in branch '3.5': New changeset 78bf34b6a713 by Serhiy Storchaka in branch '2.7': |
bm_xml_etree.py benchmark started to crash on Python 2.7 because of the change 78bf34b6a713. Python 2.7 @ 78bf34b6a713: bug.py does crash Full script: https://github.com/python/performance/blob/master/performance/benchmarks/bm_xml_etree.py |
haypo@selma$ gdb -args ./python ~/bug.py Program received signal SIGABRT, Aborted. (gdb) py-bt
Traceback (most recent call first):
File "/home/haypo/bug.py", line 130, in bench_parse
root1 = etree.parse(xml_file).getroot()
File "/home/haypo/bug.py", line 171, in bench_etree
bench_func(etree, file_path, xml_data, xml_root)
File "/home/haypo/bug.py", line 197, in <module>
bench_etree(1, ET, bench_func) (gdb) where |
Ah, I tested only with non-debug build in which asserts were ignored! In 2.7 Element doesn't support garbage collection, and the trashcan mechanism Py_TRASHCAN_SAFE_BEGIN/Py_TRASHCAN_SAFE_END can't be applied. I see three alternatives:
I'll revert the patch (except tests fix) and will try to implement different mechanism. |
This issue seems theorical to me, whereas the breakage of benchmarks is (2) looks like the right design and it was implemented in Python 3 (no?). I don't think that it's worth it to backport the change to Python 2. You |
Changes were reverted by 78bf34b6a713. It is very uneasy to implement an alternative mechanism (without increasing the size of Element objects). It adds duplication of low level garbage collecting code. I think it is better to left all as is in 2.7. Yet one argument for moving to Python 3. |
Yep, thanks ;-) |
Misc/NEWS
so that it is managed by towncrier #552Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: