-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
Milestone
Description
Describe the bug
It's possible to get an infinite recursion error on binops pandas-dev/pandas#56082 that doesn't exist in Python
Code to reproduce the behaviour:
import cython
@cython.cclass
class C:
def __add__(self, other):
return NotImplemented
def __radd__(self, other):
return self.__add__(other)
C() + C()Expected behaviour
In Python this correctly gives
TypeError: unsupported operand type(s) for +: 'notimplemented.C' and 'notimplemented.C'
In Cython it gives
File "notimplemented.pyx", line 17, in notimplemented.C.__radd__
return self.__add__(other)
File "notimplemented.pyx", line 17, in notimplemented.C.__radd__
return self.__add__(other)
File "notimplemented.pyx", line 17, in notimplemented.C.__radd__
return self.__add__(other)
[Previous line repeated 997 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object
I think the issue is:
static PyMethodDef __pyx_methods_14notimplemented_C[] = {
{"__radd__", (PyCFunction)__pyx_pw_14notimplemented_1C_3__radd__, METH_O|METH_COEXIST, 0},
{"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_14notimplemented_1C_5__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0},
{"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_14notimplemented_1C_7__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0},
{0, 0, 0, 0}
};
Here we need to add __add__ and make it point to the __add__ function rather than our binop wrapper function. This will mean manually calling C.__add__ skips the binop wrapper and calls the function exactly as written.
OS
Linux
Python version
3.11.5
Cython version
Most recent master (but I think also 3.0.x)
Additional context
No response