]> granicus.if.org Git - python/commitdiff
Issue #14849: setup Element data members to be assignable in subclasses
authorEli Bendersky <eliben@gmail.com>
Sun, 20 May 2012 03:33:29 +0000 (06:33 +0300)
committerEli Bendersky <eliben@gmail.com>
Sun, 20 May 2012 03:33:29 +0000 (06:33 +0300)
Lib/test/test_xml_etree.py
Modules/_elementtree.c

index 2b05df86fbaf964093cce5bf2e69810b7e941781..df1f77144051c634fb965a1007b1f87e64484ad0 100644 (file)
@@ -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):
index 42634977dad2125f89c623e0b0494dc9e0f7305e..d74b4972f559d94554a88a3a9cc521a882ab06aa 100644 (file)
@@ -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 */