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/ -~----------~----~----~----~------~----~------~--~---