Index: Objects/classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.154 diff -C5 -r2.154 classobject.c *** Objects/classobject.c 26 Oct 2001 17:56:51 -0000 2.154 --- Objects/classobject.c 7 Jun 2002 22:50:43 -0000 *************** *** 1877,1897 **** } static PyObject * instance_call(PyObject *func, PyObject *arg, PyObject *kw) { ! PyObject *res, *call = PyObject_GetAttrString(func, "__call__"); ! if (call == NULL) { PyInstanceObject *inst = (PyInstanceObject*) func; ! PyErr_Clear(); ! PyErr_Format(PyExc_AttributeError, ! "%.200s instance has no __call__ method", PyString_AsString(inst->in_class->cl_name)); return NULL; } res = PyObject_Call(call, arg, kw); Py_DECREF(call); return res; } static PyNumberMethods instance_as_number = { --- 1877,1920 ---- } static PyObject * instance_call(PyObject *func, PyObject *arg, PyObject *kw) { ! PyThreadState *tstate = PyThreadState_GET(); ! PyObject *res, *call; ! ! /* Protect against bad code like: ! class C: ! def __getattr__(s, a): ! return C() ! */ ! if (++tstate->recursion_depth> Py_GetRecursionLimit()) { ! /* this shouldn't be reached, but just in case */ PyInstanceObject *inst = (PyInstanceObject*) func; ! PyErr_Format(PyExc_RuntimeError, ! "'%s' maximum recursion depth exceeded" ! " in __call__ method", PyString_AsString(inst->in_class->cl_name)); + --tstate->recursion_depth; + return NULL; + } + + if ((call = PyObject_GetAttrString(func, "__call__")) == NULL) { + PyInstanceObject *inst = (PyInstanceObject*) func; + /* we need to make sure to maintain recursion error msgs */ + if (tstate->recursion_depth < Py_GetRecursionLimit()) { + PyErr_Clear(); + PyErr_Format(PyExc_AttributeError, + "%.200s instance has no __call__ method", + PyString_AsString(inst->in_class->cl_name)); + } + --tstate->recursion_depth; return NULL; } res = PyObject_Call(call, arg, kw); Py_DECREF(call); + --tstate->recursion_depth; return res; } static PyNumberMethods instance_as_number = {

AltStyle によって変換されたページ (->オリジナル) /