[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.24,2.16.8.25
Guido van Rossum
gvanrossum@users.sourceforge.net
Tue, 22 May 2001 12:53:17 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv20067/Objects
Modified Files:
Tag: descr-branch
typeobject.c
Log Message:
You can now override __getattr__ and __setattr__. Yay!
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.24
retrieving revision 2.16.8.25
diff -C2 -r2.16.8.24 -r2.16.8.25
*** typeobject.c 2001/05/22 04:21:08 2.16.8.24
--- typeobject.c 2001/05/22 19:53:15 2.16.8.25
***************
*** 968,971 ****
--- 968,1017 ----
};
+ static struct wrapperbase tab_getattr[] = {
+ {"__getattr__", (wrapperfunc)wrap_binaryfunc,
+ "x.__getattr__('name') <==> x.name"},
+ {0}
+ };
+
+ static PyObject *
+ wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
+ {
+ setattrofunc func = (setattrofunc)wrapped;
+ int res;
+ PyObject *name, *value;
+
+ if (!PyArg_ParseTuple(args, "OO", &name, &value))
+ return NULL;
+ res = (*func)(self, name, value);
+ if (res < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ static PyObject *
+ wrap_delattr(PyObject *self, PyObject *args, void *wrapped)
+ {
+ setattrofunc func = (setattrofunc)wrapped;
+ int res;
+ PyObject *name;
+
+ if (!PyArg_ParseTuple(args, "O", &name))
+ return NULL;
+ res = (*func)(self, name, NULL);
+ if (res < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ static struct wrapperbase tab_setattr[] = {
+ {"__setattr__", (wrapperfunc)wrap_setattr,
+ "x.__setattr__('name', value) <==> x.name = value"},
+ {"__delattr__", (wrapperfunc)wrap_delattr,
+ "x.__delattr__('name') <==> del x.name"},
+ {0}
+ };
+
static PyObject *
wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
***************
*** 1185,1189 ****
}
! /* Not yet supported: __getattr__, __setattr__ */
ADD(type->tp_compare, tab_cmp);
ADD(type->tp_repr, tab_repr);
--- 1231,1236 ----
}
! ADD(type->tp_getattro, tab_getattr);
! ADD(type->tp_setattro, tab_setattr);
ADD(type->tp_compare, tab_cmp);
ADD(type->tp_repr, tab_repr);
***************
*** 1384,1387 ****
--- 1431,1473 ----
SLOT0(tp_str, str);
+ static PyObject *
+ slot_tp_getattro(PyObject *self, PyObject *name)
+ {
+ PyTypeObject *tp = self->ob_type;
+ PyObject *dict = NULL;
+ PyObject *getattr;
+
+ if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ dict = tp->tp_dict;
+ if (dict == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "'%.100s' type object has no __dict__???",
+ tp->tp_name);
+ return NULL;
+ }
+ getattr = PyDict_GetItemString(dict, "__getattr__");
+ if (getattr == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "__getattr__");
+ return NULL;
+ }
+ return PyObject_CallFunction(getattr, "OO", self, name);
+ }
+
+ static int
+ slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value)
+ {
+ PyObject *res;
+
+ if (value == NULL)
+ res = PyObject_CallMethod(self, "__delattr__", "O", name);
+ else
+ res = PyObject_CallMethod(self, "__setattr__",
+ "OO", name, value);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+ }
+
/* Map rich comparison operators to their __xx__ namesakes */
static char *name_op[] = {
***************
*** 1530,1533 ****
--- 1616,1621 ----
TPSLOT(call, tp_call);
TPSLOT(str, tp_str);
+ TPSLOT(getattr, tp_getattro);
+ TPSLOT(setattr, tp_setattro);
TPSLOT(lt, tp_richcompare);
TPSLOT(le, tp_richcompare);