No cleanup function is ever generated, but atexit sounds perfect. I'm the obvious person to implement this, I'll see if I can find the time to do so soon.
- Robert On Oct 17, 2007, at 9:04 PM, mabshoff wrote: > > Hello, > > for every module Cython generates "runtime support code" that is place > at the end of the converted file. Each one of those has an > __Pyx_Import function that gets called from > > PyMODINIT_FUNC init$MODULENAME(void) > > static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) { > PyObject *__import__ = 0; > PyObject *empty_list = 0; > PyObject *module = 0; > PyObject *global_dict = 0; > PyObject *empty_dict = 0; > PyObject *list; > __import__ = PyObject_GetAttrString(__pyx_b, "__import__"); > if (!__import__) > goto bad; > if (from_list) > list = from_list; > else { > empty_list = PyList_New(0); > if (!empty_list) > goto bad; > list = empty_list; > } > global_dict = PyModule_GetDict(__pyx_m); > if (!global_dict) > goto bad; > empty_dict = PyDict_New(); > if (!empty_dict) > goto bad; > module = PyObject_CallFunction(__import__, "OOOO", > name, global_dict, empty_dict, list); > bad: > Py_XDECREF(empty_list); > Py_XDECREF(__import__); > Py_XDECREF(empty_dict); > return module; > } > > In that function PyMODINIT_FUNC init$MODULENAME(void) we also call > __Pyx_ImportType quite often: > > static PyTypeObject *__Pyx_ImportType(char *module_name, char > *class_name, > long size) > { > PyObject *py_module_name = 0; > PyObject *py_class_name = 0; > PyObject *py_name_list = 0; > PyObject *py_module = 0; > PyObject *result = 0; > > py_module_name = PyString_FromString(module_name); > if (!py_module_name) > goto bad; > py_class_name = PyString_FromString(class_name); > if (!py_class_name) > goto bad; > py_name_list = PyList_New(1); > if (!py_name_list) > goto bad; > Py_INCREF(py_class_name); > if (PyList_SetItem(py_name_list, 0, py_class_name) < 0) > goto bad; > py_module = __Pyx_Import(py_module_name, py_name_list); > if (!py_module) > goto bad; > result = PyObject_GetAttr(py_module, py_class_name); > if (!result) > goto bad; > if (!PyType_Check(result)) { > PyErr_Format(PyExc_TypeError, > "%s.%s is not a type object", > module_name, class_name); > goto bad; > } > if (((PyTypeObject *)result)->tp_basicsize != size) { > PyErr_Format(PyExc_ValueError, > "%s.%s does not appear to be the correct type object", > module_name, class_name); > goto bad; > } > goto done; > bad: > Py_XDECREF(result); > result = 0; > done: > Py_XDECREF(py_module_name); > Py_XDECREF(py_class_name); > Py_XDECREF(py_name_list); > return (PyTypeObject *)result; > } > > As one can see certain PyObject have refcounts greater 0 when > initialization is successful. But I cannot find a cleanup function > that would decrease the reference count upon exit. Consequently > python's garbage collector never frees those dictionaries, which in > most cases doesn't matter because we are exiting python anyway [some > people claim that one shouldn't care about still reachable memory, > because cleaning it up the nice way just slows down the termination of > a process because the system will reap the heap and stack > automatically]. But it pollutes the memcheck log, which is why I care > about this. > > The usual way to call those functions for each module would be to > register an atexit function, see > > http://docs.python.org/lib/module-atexit.html > > So if anybody want to write am autogenerated cleanup function for > Cython and register it via atexit that person would be very welcome :) > > Cheers, > Michael > > > --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---