This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author goodmami
Recipients goodmami
Date 2021-11-02.00:50:51
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1635814251.62.0.355245938965.issue45686@roundup.psfhosted.org>
In-reply-to
Content
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)
History
Date User Action Args
2021-11-02 00:50:51goodmamisetrecipients: + goodmami
2021-11-02 00:50:51goodmamisetmessageid: <1635814251.62.0.355245938965.issue45686@roundup.psfhosted.org>
2021-11-02 00:50:51goodmamilinkissue45686 messages
2021-11-02 00:50:51goodmamicreate