Mercurial > cpython-lru_cache-weakref
view Python/importdl.c @ 87690:66c1c9f32567 default tip
Add use_weakref option to functools.lru_cache
The use_weakref option makes lru_cache create weak references to the function
arguments when creating the cache key, which prevents them from staying in the
memory forever even after all other references to them are gone.
This is a proof of concept for http://bugs.python.org/issue19859
| author | Radomir Dopieralski <devel@sheep.art.pl> |
|---|---|
| date | Tue, 03 Dec 2013 16:02:48 +0100 |
| parents | 479af6ca3a3c |
| children |
line wrap: on
line source
/* Support for dynamic loading of extension modules */ #include "Python.h" /* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is supported on this platform. configure will then compile and link in one of the dynload_*.c files, as appropriate. We will call a function in those modules to get a function pointer to the module's init function. */ #ifdef HAVE_DYNAMIC_LOADING #include "importdl.h" #ifdef MS_WINDOWS extern dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname, PyObject *pathname, FILE *fp); #else extern dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, const char *pathname, FILE *fp); #endif PyObject * _PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp) { PyObject *m = NULL; #ifndef MS_WINDOWS PyObject *pathbytes; #endif PyObject *nameascii; char *namestr, *lastdot, *shortname, *packagecontext, *oldcontext; dl_funcptr p0; PyObject* (*p)(void); struct PyModuleDef *def; m = _PyImport_FindExtensionObject(name, path); if (m != NULL) { Py_INCREF(m); return m; } /* name must be encodable to ASCII because dynamic module must have a function called "PyInit_NAME", they are written in C, and the C language doesn't accept non-ASCII identifiers. */ nameascii = PyUnicode_AsEncodedString(name, "ascii", NULL); if (nameascii == NULL) return NULL; namestr = PyBytes_AS_STRING(nameascii); if (namestr == NULL) goto error; lastdot = strrchr(namestr, '.'); if (lastdot == NULL) { packagecontext = NULL; shortname = namestr; } else { packagecontext = namestr; shortname = lastdot+1; } #ifdef MS_WINDOWS p0 = _PyImport_GetDynLoadWindows(shortname, path, fp); #else pathbytes = PyUnicode_EncodeFSDefault(path); if (pathbytes == NULL) goto error; p0 = _PyImport_GetDynLoadFunc(shortname, PyBytes_AS_STRING(pathbytes), fp); Py_DECREF(pathbytes); #endif p = (PyObject*(*)(void))p0; if (PyErr_Occurred()) goto error; if (p == NULL) { PyObject *msg = PyUnicode_FromFormat("dynamic module does not define " "init function (PyInit_%s)", shortname); if (msg == NULL) goto error; PyErr_SetImportError(msg, name, path); Py_DECREF(msg); goto error; } oldcontext = _Py_PackageContext; _Py_PackageContext = packagecontext; m = (*p)(); _Py_PackageContext = oldcontext; if (m == NULL) goto error; if (PyErr_Occurred()) { PyErr_Format(PyExc_SystemError, "initialization of %s raised unreported exception", shortname); goto error; } /* Remember pointer to module init function. */ def = PyModule_GetDef(m); if (def == NULL) { PyErr_Format(PyExc_SystemError, "initialization of %s did not return an extension " "module", shortname); goto error; } def->m_base.m_init = p; /* Remember the filename as the __file__ attribute */ if (PyModule_AddObject(m, "__file__", path) < 0) PyErr_Clear(); /* Not important enough to report */ else Py_INCREF(path); if (_PyImport_FixupExtensionObject(m, name, path) < 0) goto error; Py_DECREF(nameascii); return m; error: Py_DECREF(nameascii); Py_XDECREF(m); return NULL; } #endif /* HAVE_DYNAMIC_LOADING */
