[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.68,2.69

Guido van Rossum gvanrossum@users.sourceforge.net
Fri, 21 Sep 2001 14:24:51 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv21933/Objects

Modified Files:
	typeobject.c 
Log Message:
Add the __getattr__ hook back.  The rules are now:
- if __getattribute__ exists, it is called first;
  if it doesn't exists, PyObject_GenericGetAttr is called first.
- if the above raises AttributeError, and __getattr__ exists,
  it is called.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.68
retrieving revision 2.69
diff -C2 -d -r2.68 -r2.69
*** typeobject.c	2001/09/21 19:29:08	2.68
--- typeobject.c	2001/09/21 21:24:49	2.69
***************
*** 2892,2895 ****
--- 2892,2933 ----
  }
  
+ static PyObject *
+ slot_tp_getattr_hook(PyObject *self, PyObject *name)
+ {
+ 	PyTypeObject *tp = self->ob_type;
+ 	PyObject *getattr, *getattribute, *res;
+ 	static PyObject *getattribute_str = NULL;
+ 	static PyObject *getattr_str = NULL;
+ 
+ 	if (getattr_str == NULL) {
+ 		getattr_str = PyString_InternFromString("__getattr__");
+ 		if (getattr_str == NULL)
+ 			return NULL;
+ 	}
+ 	if (getattribute_str == NULL) {
+ 		getattribute_str =
+ 			PyString_InternFromString("__getattribute__");
+ 		if (getattribute_str == NULL)
+ 			return NULL;
+ 	}
+ 	getattr = _PyType_Lookup(tp, getattr_str);
+ 	getattribute = _PyType_Lookup(tp, getattribute_str);
+ 	if (getattr == NULL && getattribute == NULL) {
+ 		/* Avoid further slowdowns */
+ 		if (tp->tp_getattro == slot_tp_getattr_hook)
+ 			tp->tp_getattro = PyObject_GenericGetAttr;
+ 		return PyObject_GenericGetAttr(self, name);
+ 	}
+ 	if (getattribute == NULL)
+ 		res = PyObject_GenericGetAttr(self, name);
+ 	else
+ 		res = PyObject_CallFunction(getattribute, "OO", self, name);
+ 	if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ 		PyErr_Clear();
+ 		res = PyObject_CallFunction(getattr, "OO", self, name);
+ 	}
+ 	return res;
+ }
+ 
  static int
  slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value)
***************
*** 3198,3201 ****
--- 3236,3240 ----
  	TPSLOT("__str__", tp_str, slot_tp_str);
  	TPSLOT("__getattribute__", tp_getattro, slot_tp_getattro);
+ 	TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook);
  	TPSLOT("__setattr__", tp_setattro, slot_tp_setattro);
  	TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare);