From b20df9582778119a2ae3d031da8b597c19ad4fc9 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sun, 20 May 2012 06:33:29 +0300 Subject: Issue #14849: setup Element data members to be assignable in subclasses --- Lib/test/test_xml_etree.py | 4 ++++ Modules/_elementtree.c | 25 ++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 2b05df8..df1f771 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1914,6 +1914,10 @@ class ElementTreeTest(unittest.TestCase): self.assertIsInstance(mye, MyElement) self.assertEqual(mye.tag, 'foo') + # test that attribute assignment works (issue 14849) + mye.text = "joe" + self.assertEqual(mye.text, "joe") + def test_Element_subclass_constructor(self): class MyElement(ET.Element): def __init__(self, tag, attrib={}, **extra): diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 4263497..d74b497 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1640,16 +1640,15 @@ element_getattro(ElementObject* self, PyObject* nameobj) return res; } -static int -element_setattr(ElementObject* self, const char* name, PyObject* value) +static PyObject* +element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) { - if (value == NULL) { - PyErr_SetString( - PyExc_AttributeError, - "can't delete element attributes" - ); - return -1; - } + char *name = ""; + if (PyUnicode_Check(nameobj)) + name = _PyUnicode_AsString(nameobj); + + if (name == NULL) + return NULL; if (strcmp(name, "tag") == 0) { Py_DECREF(self->tag); @@ -1671,10 +1670,10 @@ element_setattr(ElementObject* self, const char* name, PyObject* value) Py_INCREF(self->extra->attrib); } else { PyErr_SetString(PyExc_AttributeError, name); - return -1; + return NULL; } - return 0; + return NULL; } static PySequenceMethods element_as_sequence = { @@ -1700,7 +1699,7 @@ static PyTypeObject Element_Type = { (destructor)element_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ - (setattrfunc)element_setattr, /* tp_setattr */ + 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)element_repr, /* tp_repr */ 0, /* tp_as_number */ @@ -1710,7 +1709,7 @@ static PyTypeObject Element_Type = { 0, /* tp_call */ 0, /* tp_str */ (getattrofunc)element_getattro, /* tp_getattro */ - 0, /* tp_setattro */ + (setattrofunc)element_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ -- cgit v0.12