summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Bendersky <eliben@gmail.com>2012-05-20 03:33:29 (GMT)
committerEli Bendersky <eliben@gmail.com>2012-05-20 03:33:29 (GMT)
commitb20df9582778119a2ae3d031da8b597c19ad4fc9 (patch)
tree8a858701b0951207398bf8c3d30f3974a4e7b21a
parent77a1cf1622a06bf246189372219b7a17ad6abc08 (diff)
downloadcpython-b20df9582778119a2ae3d031da8b597c19ad4fc9.zip
cpython-b20df9582778119a2ae3d031da8b597c19ad4fc9.tar.gz
cpython-b20df9582778119a2ae3d031da8b597c19ad4fc9.tar.bz2
Issue #14849: setup Element data members to be assignable in subclasses
-rw-r--r--Lib/test/test_xml_etree.py4
-rw-r--r--Modules/_elementtree.c25
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 */