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