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

Guido van Rossum gvanrossum@users.sourceforge.net
Tue, 28 Aug 2001 10:47:54 -0700


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

Modified Files:
	typeobject.c 
Log Message:
Change in policy: when a slot_tp_xxx function looks for the __xxx__ method,
don't use getattr, but only look in the dict of the type and base types.
This prevents picking up all sorts of weird stuff, including things defined
by the metaclass when the object is a class (type).

For this purpose, a helper function lookup_method() was added.  One or two
other places also use this.



Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.46
retrieving revision 2.47
diff -C2 -d -r2.46 -r2.47
*** typeobject.c	2001/08/24 18:34:26	2.46
--- typeobject.c	2001/08/28 17:47:51	2.47
***************
*** 290,293 ****
--- 290,323 ----
  }
  
+ /* Internal routine to do a method lookup in the type
+    without looking in the instance dictionary
+    (so we can't use PyObject_GetAttr) but still binding
+    it to the instance.  The arguments are the object,
+    the method name as a C string, and the address of a
+    static variable used to cache the interned Python string. */
+ 
+ static PyObject *
+ lookup_method(PyObject *self, char *attrstr, PyObject **attrobj)
+ {
+ 	PyObject *res;
+ 
+ 	if (*attrobj == NULL) {
+ 		*attrobj = PyString_InternFromString(attrstr);
+ 		if (*attrobj == NULL)
+ 			return NULL;
+ 	}
+ 	res = _PyType_Lookup(self->ob_type, *attrobj);
+ 	if (res == NULL)
+ 		PyErr_SetObject(PyExc_AttributeError, *attrobj);
+ 	else {
+ 		descrgetfunc f;
+ 		if ((f = res->ob_type->tp_descr_get) == NULL)
+ 			Py_INCREF(res);
+ 		else
+ 			res = f(res, self, (PyObject *)(self->ob_type));
+ 	}
+ 	return res;
+ }
+ 
  /* Method resolution order algorithm from "Putting Metaclasses to Work"
     by Forman and Danforth (Addison-Wesley 1999). */
***************
*** 400,404 ****
  	}
  	else {
! 		mro = PyObject_GetAttrString((PyObject *)type, "mro");
  		if (mro == NULL)
  			return -1;
--- 430,435 ----
  	}
  	else {
! 		static PyObject *mro_str;
! 		mro = lookup_method((PyObject *)type, "mro", &mro_str);
  		if (mro == NULL)
  			return -1;
***************
*** 2406,2411 ****
  {
  	PyObject *func, *res, *args;
  
! 	func = PyObject_GetAttrString(self, "__contains__");
  
  	if (func != NULL) {
--- 2437,2443 ----
  {
  	PyObject *func, *res, *args;
+ 	static PyObject *contains_str;
  
! 	func = lookup_method(self, "__contains__", &contains_str);
  
  	if (func != NULL) {
***************
*** 2480,2488 ****
  {
  	PyObject *func, *res;
  
! 	func = PyObject_GetAttrString(self, "__nonzero__");
  	if (func == NULL) {
  		PyErr_Clear();
! 		func = PyObject_GetAttrString(self, "__len__");
  	}
  
--- 2512,2521 ----
  {
  	PyObject *func, *res;
+ 	static PyObject *nonzero_str, *len_str;
  
! 	func = lookup_method(self, "__nonzero__", &nonzero_str);
  	if (func == NULL) {
  		PyErr_Clear();
! 		func = lookup_method(self, "__len__", &len_str);
  	}
  
***************
*** 2533,2539 ****
  {
  	PyObject *func, *args, *res;
  	int c;
  
! 	func = PyObject_GetAttrString(self, "__cmp__");
  	if (func == NULL) {
  		PyErr_Clear();
--- 2566,2573 ----
  {
  	PyObject *func, *args, *res;
+ 	static PyObject *cmp_str;
  	int c;
  
! 	func = lookup_method(self, "__cmp__", &cmp_str);
  	if (func == NULL) {
  		PyErr_Clear();
***************
*** 2586,2591 ****
  {
  	PyObject *func, *res;
  
! 	func = PyObject_GetAttrString(self, "__repr__");
  	if (func != NULL) {
  		res = PyEval_CallObject(func, NULL);
--- 2620,2626 ----
  {
  	PyObject *func, *res;
+ 	static PyObject *repr_str;
  
! 	func = lookup_method(self, "__repr__", &repr_str);
  	if (func != NULL) {
  		res = PyEval_CallObject(func, NULL);
***************
*** 2602,2607 ****
  {
  	PyObject *func, *res;
  
! 	func = PyObject_GetAttrString(self, "__str__");
  	if (func != NULL) {
  		res = PyEval_CallObject(func, NULL);
--- 2637,2643 ----
  {
  	PyObject *func, *res;
+ 	static PyObject *str_str;
  
! 	func = lookup_method(self, "__str__", &str_str);
  	if (func != NULL) {
  		res = PyEval_CallObject(func, NULL);
***************
*** 2619,2625 ****
  {
  	PyObject *func, *res;
  	long h;
  
! 	func = PyObject_GetAttrString(self, "__hash__");
  
  	if (func != NULL) {
--- 2655,2663 ----
  {
  	PyObject *func, *res;
+ 	static PyObject *hash_str, *eq_str, *cmp_str;
+ 
  	long h;
  
! 	func = lookup_method(self, "__hash__", &hash_str);
  
  	if (func != NULL) {
***************
*** 2632,2639 ****
  	else {
  		PyErr_Clear();
! 		func = PyObject_GetAttrString(self, "__eq__");
  		if (func == NULL) {
  			PyErr_Clear();
! 			func = PyObject_GetAttrString(self, "__cmp__");
  		}
  		if (func != NULL) {
--- 2670,2677 ----
  	else {
  		PyErr_Clear();
! 		func = lookup_method(self, "__eq__", &eq_str);
  		if (func == NULL) {
  			PyErr_Clear();
! 			func = lookup_method(self, "__cmp__", &cmp_str);
  		}
  		if (func != NULL) {
***************
*** 2653,2657 ****
  slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
  {
! 	PyObject *meth = PyObject_GetAttrString(self, "__call__");
  	PyObject *res;
  
--- 2691,2696 ----
  slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
  {
! 	static PyObject *call_str;
! 	PyObject *meth = lookup_method(self, "__call__", &call_str);
  	PyObject *res;
  
***************
*** 2715,2720 ****
  {
  	PyObject *func, *args, *res;
  
! 	func = PyObject_GetAttrString(self, name_op[op]);
  	if (func == NULL) {
  		PyErr_Clear();
--- 2754,2760 ----
  {
  	PyObject *func, *args, *res;
+ 	static PyObject *op_str[6];
  
! 	func = lookup_method(self, name_op[op], &op_str[op]);
  	if (func == NULL) {
  		PyErr_Clear();
***************
*** 2762,2767 ****
  {
  	PyObject *func, *res;
  
! 	func = PyObject_GetAttrString(self, "__iter__");
  	if (func != NULL) {
  		 res = PyObject_CallObject(func, NULL);
--- 2802,2808 ----
  {
  	PyObject *func, *res;
+ 	static PyObject *iter_str, *getitem_str;
  
! 	func = lookup_method(self, "__iter__", &iter_str);
  	if (func != NULL) {
  		 res = PyObject_CallObject(func, NULL);
***************
*** 2770,2774 ****
  	}
  	PyErr_Clear();
! 	func = PyObject_GetAttrString(self, "__getitem__");
  	if (func == NULL) {
  		PyErr_SetString(PyExc_TypeError, "iter() of non-sequence");
--- 2811,2815 ----
  	}
  	PyErr_Clear();
! 	func = lookup_method(self, "__getitem__", &getitem_str);
  	if (func == NULL) {
  		PyErr_SetString(PyExc_TypeError, "iter() of non-sequence");
***************
*** 2831,2835 ****
  slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
  {
! 	PyObject *meth = PyObject_GetAttrString(self, "__init__");
  	PyObject *res;
  
--- 2872,2877 ----
  slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
  {
! 	static PyObject *init_str;
! 	PyObject *meth = lookup_method(self, "__init__", &init_str);
  	PyObject *res;