[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);