I am trying to write a C++ extension with support for CPython and PyPy.
My extension involves creating some custom types that support the call interface.
However, I appear to be getting memory leaks in PyPy when I raise Python exceptions. I am not getting any memory leaks with regular CPython.
I have isolated the leaking code, with a corresponding test in https://github.com/Lalaland/memoryleak_example. Run make to build the code and then test it by either running python test.py or pypy test.py
My extension class is the following:
struct custom_function {
PyObject_HEAD
};
PyObject* custom_call(PyObject *self, PyObject *args, PyObject *kwargs) {
std::cout << "Calling custom function with except, simpler" << std::endl;
PyErr_SetString(PyExc_SystemError, "Fancier exception for custom fancy func");
return nullptr;
};
PyTypeObject custom_function_type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom_function",
.tp_basicsize = sizeof(custom_function),
.tp_itemsize = 0,
.tp_call = custom_call,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("Custom function type"),
.tp_new = PyType_GenericNew,
};
My memory leak detection code (using weakref) is:
import helloworld as m
import gc
import weakref
class ExampleClass:
def __init__(self):
pass
def simple_test(f):
it = ExampleClass()
a = weakref.ref(it)
try:
f(it)
except Exception as e:
print("Got exception!", e)
del e
assert a() is not None
del it
gc.collect()
assert a() is None
simple_test(m.custom_fancy_func)
Does anyone know what I am doing wrong?