Both the Python and C versions of xml.etree.ElementTree allow Element.extend() to accept a sequence or an iterable, such as a generator expression (although the docs only mention "sequence"; that's a separate problem):
>>> from xml.etree import ElementTree as ET
>>> elem = ET.Element('root')
>>> elem.extend(ET.Element('child') for _ in range(3))
>>> pyelem = ET._Element_Py('root')
>>> pyelem.extend(ET._Element_Py('child') for _ in range(3))
If the generator expression raises an Exception (for instance, by omitting the tag name as below), then the Python implementation passes up the error:
>>> pyelem.extend(ET._Element_Py() for _ in range(3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.9/xml/etree/ElementTree.py", line 253, in extend
for element in elements:
File "<stdin>", line 1, in <genexpr>
TypeError: __init__() missing 1 required positional argument: 'tag'
But the C implementation hides it with a misleading exception of its own:
>>> elem.extend(ET.Element() for _ in range(3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected sequence, not "generator"
Is it possible to pass up the original exception, as in the Python implementation? In the C code, the exception is raised when PySequence_Fast returns something false:
seq = PySequence_Fast(elements, "");
if (!seq) {
PyErr_Format(
PyExc_TypeError,
"expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name
);
return NULL;
}
Otherwise, while it would be good if the error message didn't incorrectly state that Element.extend() requires a sequence and not a generator, it currently leads the programmer to the actual error. That is, when the programmer tries to make the argument a sequence by creating a list, the error will be propagated before Element.extend() is called:
>>> elem.extend([ET.Element() for _ in range(3)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcomp>
TypeError: Element() takes at least 1 argument (0 given)
|