mirror of https://github.com/python/cpython
[3.13] gh-123213: Fixed xml.etree.ElementTree.Element.extend and assignment to no longer hide exceptions (GH-123214) (#123257)
gh-123213: Fixed xml.etree.ElementTree.Element.extend and assignment to no longer hide exceptions (GH-123214)
(cherry picked from commit 90b6d0e0f8
)
Co-authored-by: Bar Harel <bharel@barharel.com>
This commit is contained in:
parent
4ea9c5ba78
commit
d9e4c4b61c
|
@ -971,7 +971,7 @@ Element Objects
|
||||||
|
|
||||||
.. method:: extend(subelements)
|
.. method:: extend(subelements)
|
||||||
|
|
||||||
Appends *subelements* from a sequence object with zero or more elements.
|
Appends *subelements* from an iterable of elements.
|
||||||
Raises :exc:`TypeError` if a subelement is not an :class:`Element`.
|
Raises :exc:`TypeError` if a subelement is not an :class:`Element`.
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
|
@ -2423,6 +2423,22 @@ class BugsTest(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, ET.TreeBuilder().start, "tag")
|
self.assertRaises(TypeError, ET.TreeBuilder().start, "tag")
|
||||||
self.assertRaises(TypeError, ET.TreeBuilder().start, "tag", None)
|
self.assertRaises(TypeError, ET.TreeBuilder().start, "tag", None)
|
||||||
|
|
||||||
|
def test_issue123213_correct_extend_exception(self):
|
||||||
|
# Does not hide the internal exception when extending the element
|
||||||
|
self.assertRaises(ZeroDivisionError, ET.Element('tag').extend,
|
||||||
|
(1/0 for i in range(2)))
|
||||||
|
|
||||||
|
# Still raises the TypeError when extending with a non-iterable
|
||||||
|
self.assertRaises(TypeError, ET.Element('tag').extend, None)
|
||||||
|
|
||||||
|
# Preserves the TypeError message when extending with a generator
|
||||||
|
def f():
|
||||||
|
raise TypeError("mymessage")
|
||||||
|
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
TypeError, 'mymessage',
|
||||||
|
ET.Element('tag').extend, (f() for i in range(2)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
@ -3748,6 +3764,22 @@ class ElementSlicingTest(unittest.TestCase):
|
||||||
e[1::-sys.maxsize<<64] = [ET.Element('d')]
|
e[1::-sys.maxsize<<64] = [ET.Element('d')]
|
||||||
self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3'])
|
self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3'])
|
||||||
|
|
||||||
|
def test_issue123213_setslice_exception(self):
|
||||||
|
e = ET.Element('tag')
|
||||||
|
# Does not hide the internal exception when assigning to the element
|
||||||
|
with self.assertRaises(ZeroDivisionError):
|
||||||
|
e[:1] = (1/0 for i in range(2))
|
||||||
|
|
||||||
|
# Still raises the TypeError when assigning with a non-iterable
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
e[:1] = None
|
||||||
|
|
||||||
|
# Preserve the original TypeError message when assigning.
|
||||||
|
def f():
|
||||||
|
raise TypeError("mymessage")
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(TypeError, 'mymessage'):
|
||||||
|
e[:1] = (f() for i in range(2))
|
||||||
|
|
||||||
class IOTest(unittest.TestCase):
|
class IOTest(unittest.TestCase):
|
||||||
def test_encoding(self):
|
def test_encoding(self):
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
:meth:`xml.etree.ElementTree.Element.extend` and
|
||||||
|
:class:`~xml.etree.ElementTree.Element` assignment no longer hide the internal
|
||||||
|
exception if an erronous generator is passed. Patch by Bar Harel.
|
|
@ -1213,12 +1213,8 @@ _elementtree_Element_extend_impl(ElementObject *self, PyTypeObject *cls,
|
||||||
PyObject* seq;
|
PyObject* seq;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
seq = PySequence_Fast(elements, "");
|
seq = PySequence_Fast(elements, "'elements' must be an iterable");
|
||||||
if (!seq) {
|
if (!seq) {
|
||||||
PyErr_Format(
|
|
||||||
PyExc_TypeError,
|
|
||||||
"expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name
|
|
||||||
);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1918,12 +1914,8 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A new slice is actually being assigned */
|
/* A new slice is actually being assigned */
|
||||||
seq = PySequence_Fast(value, "");
|
seq = PySequence_Fast(value, "assignment expects an iterable");
|
||||||
if (!seq) {
|
if (!seq) {
|
||||||
PyErr_Format(
|
|
||||||
PyExc_TypeError,
|
|
||||||
"expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name
|
|
||||||
);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
newlen = PySequence_Fast_GET_SIZE(seq);
|
newlen = PySequence_Fast_GET_SIZE(seq);
|
||||||
|
|
Loading…
Reference in New Issue