From 3d5bf2a6f287f9887e96198882838b98fb959123 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 12 Sep 2026 01:56:03 +0200 Subject: [PATCH] gh-155742: Remove dead code in _elementtree Add tests on TreeBuilder.data(). --- Lib/test/test_xml_etree.py | 45 ++++++++++++++++++++++++++++++++++++++ Modules/_elementtree.c | 12 +--------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index f9ff8c4c3541eda..b3579069c7a3ad0 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -3336,6 +3336,51 @@ def __iter__(self): e.extend([ET.Element(f'c{i}') for i in range(10)]) e[:] = V() + def test_treebuilder_data(self): + # single data() call: pass the string object + b = ET.TreeBuilder() + b.start('root', {}) + b.data('ABCD') + b.end('root') + elem = b.close() + self.assertEqual(elem.text, 'ABCD') + + # two data() calls: join the two strings + b = ET.TreeBuilder() + b.start('root', {}) + b.data('ABCD') + b.data('EFGH') + b.end('root') + elem = b.close() + self.assertEqual(elem.text, 'ABCDEFGH') + + def test_treebuilder_data_wrong_types(self): + for obj in (b'bytes', 123, 1.0): + # single data() call + try: + b = ET.TreeBuilder() + b.start('tag', {}) + b.data(obj) + b.end('tag') + except TypeError: + # Python implementation raises TypeError, + # C implementation doesn't. + pass + else: + elem = b.close() + self.assertEqual(elem.text, obj) + + # two data() calls + errmsg = f'expected str instance, {type(obj).__name__} found' + with self.assertRaisesRegex(TypeError, errmsg): + b = ET.TreeBuilder() + b.start('tag', {}) + b.data(obj) + b.data(obj) + b.end('tag') + elem = b.close() + _ = elem.text + def test_treebuilder_start(self): # Issue #27863 def element_factory(x, y): diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index f6dedeed981c40d..9bdb534b893c76a 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2935,17 +2935,7 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) self->data = Py_NewRef(data); } else { /* more than one item; use a list to collect items */ - if (PyBytes_CheckExact(self->data) - && _PyObject_IsUniquelyReferenced(self->data) - && PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) { - /* XXX this code path unused in Python 3? */ - /* expat often generates single character data sections; handle - the most common case by resizing the existing string... */ - Py_ssize_t size = PyBytes_GET_SIZE(self->data); - if (_PyBytes_Resize(&self->data, size + 1) < 0) - return NULL; - PyBytes_AS_STRING(self->data)[size] = PyBytes_AS_STRING(data)[0]; - } else if (PyList_CheckExact(self->data)) { + if (PyList_CheckExact(self->data)) { if (PyList_Append(self->data, data) < 0) return NULL; } else {