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

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


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

Modified Files:
	typeobject.c 
Log Message:
Add call_maybe(): a variant of call_method() that returns
NotImplemented when the lookup fails, and use this for binary
operators.  Also lookup_maybe() which doesn't raise an exception when
the lookup fails (still returning NULL).


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.60
retrieving revision 2.61
diff -C2 -d -r2.60 -r2.61
*** typeobject.c	2001/09/14 16:58:08	2.60
--- typeobject.c	2001/09/14 17:51:50	2.61
***************
*** 301,313 ****
  }
  
! /* 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;
--- 301,321 ----
  }
  
! /* Internal routines 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.
! 
!    Two variants:
! 
!    - lookup_maybe() returns NULL without raising an exception
!      when the _PyType_Lookup() call fails;
! 
!    - lookup_method() always raises an exception upon errors.
! */
  
  static PyObject *
! lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj)
  {
  	PyObject *res;
***************
*** 319,325 ****
  	}
  	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)
--- 327,331 ----
  	}
  	res = _PyType_Lookup(self->ob_type, *attrobj);
! 	if (res != NULL) {
  		descrgetfunc f;
  		if ((f = res->ob_type->tp_descr_get) == NULL)
***************
*** 331,334 ****
--- 337,349 ----
  }
  
+ static PyObject *
+ lookup_method(PyObject *self, char *attrstr, PyObject **attrobj)
+ {
+ 	PyObject *res = lookup_maybe(self, attrstr, attrobj);
+ 	if (res == NULL && !PyErr_Occurred())
+ 		PyErr_SetObject(PyExc_AttributeError, *attrobj);
+ 	return res;
+ }
+ 
  /* A variation of PyObject_CallMethod that uses lookup_method()
     instead of PyObject_GetAttrString().  This uses the same convention
***************
*** 343,351 ****
  	va_start(va, format);
  
! 	func = lookup_method(o, name, &dummy_str);
  	Py_XDECREF(dummy_str);
  	if (func == NULL) {
  		va_end(va);
! 		PyErr_SetString(PyExc_AttributeError, name);
  		return NULL;
  	}
--- 358,408 ----
  	va_start(va, format);
  
! 	func = lookup_maybe(o, name, &dummy_str);
! 	if (func == NULL) {
! 		va_end(va);
! 		if (!PyErr_Occurred())
! 			PyErr_SetObject(PyExc_AttributeError, dummy_str);
! 		Py_XDECREF(dummy_str);
! 		return NULL;
! 	}
! 	Py_DECREF(dummy_str);
! 
! 	if (format && *format)
! 		args = Py_VaBuildValue(format, va);
! 	else
! 		args = PyTuple_New(0);
! 
! 	va_end(va);
! 
! 	if (args == NULL)
! 		return NULL;
! 
! 	assert(PyTuple_Check(args));
! 	retval = PyObject_Call(func, args, NULL);
! 
! 	Py_DECREF(args);
! 	Py_DECREF(func);
! 
! 	return retval;
! }
! 
! /* Clone of call_method() that returns NotImplemented when the lookup fails. */
! 
! PyObject *
! call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
! {
! 	va_list va;
! 	PyObject *args, *func = 0, *retval;
! 	PyObject *dummy_str = NULL;
! 	va_start(va, format);
! 
! 	func = lookup_maybe(o, name, &dummy_str);
  	Py_XDECREF(dummy_str);
  	if (func == NULL) {
  		va_end(va);
! 		if (!PyErr_Occurred()) {
! 			Py_INCREF(Py_NotImplemented);
! 			return Py_NotImplemented;
! 		}
  		return NULL;
  	}
***************
*** 2448,2452 ****
  	    self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
  		PyObject *r; \
! 		r = call_method( \
  			self, OPSTR, &cache_str, "(O)", other); \
  		if (r != Py_NotImplemented || \
--- 2505,2509 ----
  	    self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
  		PyObject *r; \
! 		r = call_maybe( \
  			self, OPSTR, &cache_str, "(O)", other); \
  		if (r != Py_NotImplemented || \
***************
*** 2457,2461 ****
  	if (other->ob_type->tp_as_number != NULL && \
  	    other->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
! 		return call_method( \
  			other, ROPSTR, &rcache_str, "(O)", self); \
  	} \
--- 2514,2518 ----
  	if (other->ob_type->tp_as_number != NULL && \
  	    other->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
! 		return call_maybe( \
  			other, ROPSTR, &rcache_str, "(O)", self); \
  	} \