[Python-Dev] possible fix for recursive __call__ segfault

Brett Cannon brett at python.org
Tue Apr 18 02:34:16 CEST 2006


Bug 532646 is a check for recursive __call__ methods where it is just
set to an instance of the same class::

class A:
    pass
A.__call__ = A()
a = A()
try:
    a() # This should not segfault
except RuntimeError:
    pass
else:
    raise TestFailed, "how could this not have overflowed the stack?"


Turns out this was never handled for new-style classes and thus goes
back to 2.4 at least.  I don't know if this is a good solution or not,
but I came up with this as a quick fix::

Index: Objects/typeobject.c
===================================================================
--- Objects/typeobject.c        (revision 45499)
+++ Objects/typeobject.c        (working copy)
@@ -4585,6 +4585,11 @@

        if (meth == NULL)
                return NULL;
+       if (meth == self) {
+               PyErr_SetString(PyExc_RuntimeError,
+                               "recursive __call__ definition");
+               return NULL;
+       }
        res = PyObject_Call(meth, args, kwds);
        Py_DECREF(meth);
        return res;


Of course SF is down (can't wait until the summer when I can do more
tracker work) so I can't post there at the moment.  But does anyone
think there is a better solution to this without some counter
somewhere to keep track how far one goes down fetching __call__
attributes?

-Brett


More information about the Python-Dev mailing list