changeset: 99297:936fcd0ba6b1 parent: 99291:2662099d477e parent: 99296:3a44f06907f1 user: Serhiy Storchaka date: Mon Nov 23 08:49:39 2015 +0200 files: Misc/NEWS description: Issue #25691: Fixed crash on deleting ElementTree.Element attributes. diff -r 2662099d477e -r 936fcd0ba6b1 Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py Sun Nov 22 18:20:37 2015 -0800 +++ b/Lib/test/test_xml_etree.py Mon Nov 23 08:49:39 2015 +0200 @@ -244,6 +244,33 @@ self.assertEqual(ET.XML, ET.fromstring) self.assertEqual(ET.PI, ET.ProcessingInstruction) + def test_set_attribute(self): + element = ET.Element('tag') + + self.assertEqual(element.tag, 'tag') + element.tag = 'Tag' + self.assertEqual(element.tag, 'Tag') + element.tag = 'TAG' + self.assertEqual(element.tag, 'TAG') + + self.assertIsNone(element.text) + element.text = 'Text' + self.assertEqual(element.text, 'Text') + element.text = 'TEXT' + self.assertEqual(element.text, 'TEXT') + + self.assertIsNone(element.tail) + element.tail = 'Tail' + self.assertEqual(element.tail, 'Tail') + element.tail = 'TAIL' + self.assertEqual(element.tail, 'TAIL') + + self.assertEqual(element.attrib, {}) + element.attrib = {'a': 'b', 'c': 'd'} + self.assertEqual(element.attrib, {'a': 'b', 'c': 'd'}) + element.attrib = {'A': 'B', 'C': 'D'} + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + def test_simpleops(self): # Basic method sanity checks. diff -r 2662099d477e -r 936fcd0ba6b1 Lib/test/test_xml_etree_c.py --- a/Lib/test/test_xml_etree_c.py Sun Nov 22 18:20:37 2015 -0800 +++ b/Lib/test/test_xml_etree_c.py Mon Nov 23 08:49:39 2015 +0200 @@ -22,6 +22,38 @@ finally: data = None + def test_del_attribute(self): + element = cET.Element('tag') + + element.tag = 'TAG' + with self.assertRaises(AttributeError): + del element.tag + self.assertEqual(element.tag, 'TAG') + + with self.assertRaises(AttributeError): + del element.text + self.assertIsNone(element.text) + element.text = 'TEXT' + with self.assertRaises(AttributeError): + del element.text + self.assertEqual(element.text, 'TEXT') + + with self.assertRaises(AttributeError): + del element.tail + self.assertIsNone(element.tail) + element.tail = 'TAIL' + with self.assertRaises(AttributeError): + del element.tail + self.assertEqual(element.tail, 'TAIL') + + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {}) + element.attrib = {'A': 'B', 'C': 'D'} + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff -r 2662099d477e -r 936fcd0ba6b1 Misc/NEWS --- a/Misc/NEWS Sun Nov 22 18:20:37 2015 -0800 +++ b/Misc/NEWS Mon Nov 23 08:49:39 2015 +0200 @@ -95,6 +95,8 @@ Library ------- +- Issue #25691: Fixed crash on deleting ElementTree.Element attributes. + - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. diff -r 2662099d477e -r 936fcd0ba6b1 Modules/_elementtree.c --- a/Modules/_elementtree.c Sun Nov 22 18:20:37 2015 -0800 +++ b/Modules/_elementtree.c Mon Nov 23 08:49:39 2015 +0200 @@ -1921,6 +1921,12 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) { char *name = ""; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete attribute"); + return -1; + } if (PyUnicode_Check(nameobj)) name = _PyUnicode_AsString(nameobj); if (name == NULL)