From 004869681a2b618d5b64fd42b8f7812f65c7dc88 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 15 Nov 2012 21:39:36 -0500 Subject: Issue #15894: Document why we don't worry about re-acquiring the global import lock after forking. --- Python/import.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 2f71b97bc8..6882b57060 100644 --- a/Python/import.c +++ b/Python/import.c @@ -202,8 +202,11 @@ _PyImport_ReInitLock(void) if (import_lock_level > 1) { /* Forked as a side effect of import */ long me = PyThread_get_thread_ident(); - PyThread_acquire_lock(import_lock, 0); - /* XXX: can the previous line fail? */ + /* The following could fail if the lock is already held, but forking as + a side-effect of an import is a) rare, b) nuts, and c) difficult to + do thanks to the lock only being held when doing individual module + locks per import. */ + PyThread_acquire_lock(import_lock, NOWAIT_LOCK); import_lock_thread = me; import_lock_level--; } else { -- cgit v1.2.1 From 838169869f9d3474c58ed662b1a51541de235c34 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 14 Dec 2012 17:04:59 +0200 Subject: Issue #16421: allow to load multiple modules from the same shared object. Patch by V?clav ?milauer. --- Python/import.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 6882b57060..8e7482ac4e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -452,12 +452,12 @@ PyImport_GetMagicTag(void) /* Magic for extension modules (built-in as well as dynamically loaded). To prevent initializing an extension module more than - once, we keep a static dictionary 'extensions' keyed by module name - (for built-in modules) or by filename (for dynamically loaded - modules), containing these modules. A copy of the module's - dictionary is stored by calling _PyImport_FixupExtensionObject() - immediately after the module initialization function succeeds. A - copy can be retrieved from there by calling + once, we keep a static dictionary 'extensions' keyed by the tuple + (module name, module name) (for built-in modules) or by + (filename, module name) (for dynamically loaded modules), containing these + modules. A copy of the module's dictionary is stored by calling + _PyImport_FixupExtensionObject() immediately after the module initialization + function succeeds. A copy can be retrieved from there by calling _PyImport_FindExtensionObject(). Modules which do support multiple initialization set their m_size @@ -470,7 +470,7 @@ int _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, PyObject *filename) { - PyObject *modules, *dict; + PyObject *modules, *dict, *filename_name; struct PyModuleDef *def; if (extensions == NULL) { extensions = PyDict_New(); @@ -508,7 +508,11 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, if (def->m_base.m_copy == NULL) return -1; } - PyDict_SetItem(extensions, filename, (PyObject*)def); + filename_name = PyTuple_Pack(2,filename, name); + if (filename_name == NULL) + return -1; + if (PyDict_SetItem(extensions, filename_name, (PyObject*)def) < 0) + return -1; return 0; } @@ -528,11 +532,14 @@ _PyImport_FixupBuiltin(PyObject *mod, char *name) PyObject * _PyImport_FindExtensionObject(PyObject *name, PyObject *filename) { - PyObject *mod, *mdict; + PyObject *mod, *mdict, *filename_name; PyModuleDef* def; if (extensions == NULL) return NULL; - def = (PyModuleDef*)PyDict_GetItem(extensions, filename); + filename_name = PyTuple_Pack(2,filename, name); + if (filename_name == NULL) + return NULL; + def = (PyModuleDef*)PyDict_GetItem(extensions, filename_name); if (def == NULL) return NULL; if (def->m_size == -1) { -- cgit v1.2.1 From a0d1572bb8860a41834b2bca05748df2a28ffb5d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 15 Dec 2012 00:05:16 -0500 Subject: cleanup and fix refleaks --- Python/import.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 8e7482ac4e..50267895c5 100644 --- a/Python/import.c +++ b/Python/import.c @@ -470,8 +470,9 @@ int _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, PyObject *filename) { - PyObject *modules, *dict, *filename_name; + PyObject *modules, *dict, *key; struct PyModuleDef *def; + int res; if (extensions == NULL) { extensions = PyDict_New(); if (extensions == NULL) @@ -508,10 +509,12 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, if (def->m_base.m_copy == NULL) return -1; } - filename_name = PyTuple_Pack(2,filename, name); - if (filename_name == NULL) + key = PyTuple_Pack(2, filename, name); + if (key == NULL) return -1; - if (PyDict_SetItem(extensions, filename_name, (PyObject*)def) < 0) + res = PyDict_SetItem(extensions, key, (PyObject *)def); + Py_DECREF(key); + if (res < 0) return -1; return 0; } @@ -532,14 +535,15 @@ _PyImport_FixupBuiltin(PyObject *mod, char *name) PyObject * _PyImport_FindExtensionObject(PyObject *name, PyObject *filename) { - PyObject *mod, *mdict, *filename_name; + PyObject *mod, *mdict, *key; PyModuleDef* def; if (extensions == NULL) return NULL; - filename_name = PyTuple_Pack(2,filename, name); - if (filename_name == NULL) + key = PyTuple_Pack(2, filename, name); + if (key == NULL) return NULL; - def = (PyModuleDef*)PyDict_GetItem(extensions, filename_name); + def = (PyModuleDef *)PyDict_GetItem(extensions, key); + Py_DECREF(key); if (def == NULL) return NULL; if (def->m_size == -1) { -- cgit v1.2.1 From 63c6c6e958c8f9749e69ad62e653147ff08680c1 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 18 Mar 2013 23:13:31 -0700 Subject: sprinkle const --- Python/import.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index a50ef05b07..8773be46ad 100644 --- a/Python/import.c +++ b/Python/import.c @@ -846,7 +846,7 @@ imp_fix_co_filename(PyObject *self, PyObject *args) /* Forward */ -static struct _frozen * find_frozen(PyObject *); +static const struct _frozen * find_frozen(PyObject *); /* Helper to test for built-in module */ @@ -983,10 +983,10 @@ init_builtin(PyObject *name) /* Frozen modules */ -static struct _frozen * +static const struct _frozen * find_frozen(PyObject *name) { - struct _frozen *p; + const struct _frozen *p; if (name == NULL) return NULL; @@ -1003,7 +1003,7 @@ find_frozen(PyObject *name) static PyObject * get_frozen_object(PyObject *name) { - struct _frozen *p = find_frozen(name); + const struct _frozen *p = find_frozen(name); int size; if (p == NULL) { @@ -1027,7 +1027,7 @@ get_frozen_object(PyObject *name) static PyObject * is_frozen_package(PyObject *name) { - struct _frozen *p = find_frozen(name); + const struct _frozen *p = find_frozen(name); int size; if (p == NULL) { @@ -1054,7 +1054,7 @@ is_frozen_package(PyObject *name) int PyImport_ImportFrozenModuleObject(PyObject *name) { - struct _frozen *p; + const struct _frozen *p; PyObject *co, *m, *path; int ispackage; int size; @@ -1781,7 +1781,7 @@ static PyObject * imp_is_frozen(PyObject *self, PyObject *args) { PyObject *name; - struct _frozen *p; + const struct _frozen *p; if (!PyArg_ParseTuple(args, "U:is_frozen", &name)) return NULL; p = find_frozen(name); -- cgit v1.2.1 From 05af1e7fca1463b6a0fc7a790313d93a3e68c222 Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Thu, 2 May 2013 10:44:04 -0700 Subject: Closes #17892: Fix the name of _PyObject_CallMethodObjIdArgs --- Python/import.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 805cdd7e2a..b77eda106d 100644 --- a/Python/import.c +++ b/Python/import.c @@ -704,7 +704,7 @@ PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname, "no interpreter!"); } - pathobj = _PyObject_CallMethodObjIdArgs(interp->importlib, + pathobj = _PyObject_CallMethodIdObjArgs(interp->importlib, &PyId__get_sourcefile, cpathobj, NULL); if (pathobj == NULL) @@ -1441,7 +1441,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } if (initializing > 0) { /* _bootstrap._lock_unlock_module() releases the import lock */ - value = _PyObject_CallMethodObjIdArgs(interp->importlib, + value = _PyObject_CallMethodIdObjArgs(interp->importlib, &PyId__lock_unlock_module, abs_name, NULL); if (value == NULL) @@ -1459,7 +1459,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } else { /* _bootstrap._find_and_load() releases the import lock */ - mod = _PyObject_CallMethodObjIdArgs(interp->importlib, + mod = _PyObject_CallMethodIdObjArgs(interp->importlib, &PyId__find_and_load, abs_name, builtins_import, NULL); if (mod == NULL) { @@ -1528,7 +1528,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } } else { - final_mod = _PyObject_CallMethodObjIdArgs(interp->importlib, + final_mod = _PyObject_CallMethodIdObjArgs(interp->importlib, &PyId__handle_fromlist, mod, fromlist, builtins_import, NULL); -- cgit v1.2.1 From 5756d7dace379752116766907b63ac77ffc4bc98 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 6 May 2013 21:15:57 +0200 Subject: Issue #1545463: Global variables caught in reference cycles are now garbage-collected at shutdown. --- Python/import.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index b77eda106d..cd4fb788a1 100644 --- a/Python/import.c +++ b/Python/import.c @@ -403,6 +403,14 @@ PyImport_Cleanup(void) } } + /* Collect garbage remaining after deleting the modules. Mostly + reference cycles created by classes. */ + PyGC_Collect(); + + /* Dump GC stats before it's too late, since it uses the warnings + machinery. */ + _PyGC_DumpShutdownStats(); + /* Next, delete sys and builtins (in that order) */ value = PyDict_GetItemString(modules, "sys"); if (value != NULL && PyModule_Check(value)) { -- cgit v1.2.1 From 63d05b117ac621279bea27b1a7903d3085d18240 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 8 May 2013 13:23:25 +0200 Subject: Issue #1545463: At shutdown, defer finalization of codec modules so that stderr remains usable. (should fix Windows buildbot failures on test_gc) --- Python/import.c | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index cd4fb788a1..1fbafecc1b 100644 --- a/Python/import.c +++ b/Python/import.c @@ -295,6 +295,30 @@ static char* sys_files[] = { NULL }; +static int +is_essential_module(PyObject *name) +{ + Py_ssize_t name_len; + char *name_str = PyUnicode_AsUTF8AndSize(name, &name_len); + + if (name_str == NULL) { + PyErr_Clear(); + return 0; + } + if (strcmp(name_str, "builtins") == 0) + return 1; + if (strcmp(name_str, "sys") == 0) + return 1; + /* These are all needed for stderr to still function */ + if (strcmp(name_str, "codecs") == 0) + return 1; + if (strcmp(name_str, "_codecs") == 0) + return 1; + if (strncmp(name_str, "encodings.", 10) == 0) + return 1; + return 0; +} + /* Un-initialize things, as good as we can */ @@ -374,9 +398,7 @@ PyImport_Cleanup(void) if (value->ob_refcnt != 1) continue; if (PyUnicode_Check(key) && PyModule_Check(value)) { - if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0) - continue; - if (PyUnicode_CompareWithASCIIString(key, "sys") == 0) + if (is_essential_module(key)) continue; if (Py_VerboseFlag) PySys_FormatStderr( @@ -392,9 +414,7 @@ PyImport_Cleanup(void) pos = 0; while (PyDict_Next(modules, &pos, &key, &value)) { if (PyUnicode_Check(key) && PyModule_Check(value)) { - if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0) - continue; - if (PyUnicode_CompareWithASCIIString(key, "sys") == 0) + if (is_essential_module(key)) continue; if (Py_VerboseFlag) PySys_FormatStderr("# cleanup[2] %U\n", key); @@ -411,20 +431,15 @@ PyImport_Cleanup(void) machinery. */ _PyGC_DumpShutdownStats(); - /* Next, delete sys and builtins (in that order) */ - value = PyDict_GetItemString(modules, "sys"); - if (value != NULL && PyModule_Check(value)) { - if (Py_VerboseFlag) - PySys_WriteStderr("# cleanup sys\n"); - _PyModule_Clear(value); - PyDict_SetItemString(modules, "sys", Py_None); - } - value = PyDict_GetItemString(modules, "builtins"); - if (value != NULL && PyModule_Check(value)) { - if (Py_VerboseFlag) - PySys_WriteStderr("# cleanup builtins\n"); - _PyModule_Clear(value); - PyDict_SetItemString(modules, "builtins", Py_None); + /* Next, delete all remaining modules */ + pos = 0; + while (PyDict_Next(modules, &pos, &key, &value)) { + if (PyUnicode_Check(key) && PyModule_Check(value)) { + if (Py_VerboseFlag) + PySys_FormatStderr("# cleanup[3] %U\n", key); + _PyModule_Clear(value); + PyDict_SetItem(modules, key, Py_None); + } } /* Finally, clear and delete the modules directory */ -- cgit v1.2.1 From 4bb13f5d6801f4857651f13a800a964cb8b47223 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 19 May 2013 01:11:58 +0200 Subject: Issue #17937: Try harder to collect cyclic garbage at shutdown. --- Python/import.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 1fbafecc1b..a42b0f89b0 100644 --- a/Python/import.c +++ b/Python/import.c @@ -444,6 +444,7 @@ PyImport_Cleanup(void) /* Finally, clear and delete the modules directory */ PyDict_Clear(modules); + _PyGC_CollectNoFail(); interp->modules = NULL; Py_DECREF(modules); } -- cgit v1.2.1 From 41c36b5a56ae88660fd66b03ade69aecf4c2de86 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 31 May 2013 23:18:39 -0400 Subject: Issue #18065: For frozen packages set __path__ to []. Previously __path__ was set to [__name__], but that could lead to bad results if someone managed to circumvent the frozen importer and somehow ended up with a finder that thought __name__ was a legit directory/location. --- Python/import.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index a42b0f89b0..0bb46d2e1e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1107,19 +1107,17 @@ PyImport_ImportFrozenModuleObject(PyObject *name) goto err_return; } if (ispackage) { - /* Set __path__ to the package name */ + /* Set __path__ to the empty list */ PyObject *d, *l; int err; m = PyImport_AddModuleObject(name); if (m == NULL) goto err_return; d = PyModule_GetDict(m); - l = PyList_New(1); + l = PyList_New(0); if (l == NULL) { goto err_return; } - Py_INCREF(name); - PyList_SET_ITEM(l, 0, name); err = PyDict_SetItemString(d, "__path__", l); Py_DECREF(l); if (err != 0) -- cgit v1.2.1 From 21d4e9534aceac9c2753b70bffe4f75ff38ec525 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 12 Jun 2013 23:29:18 -0400 Subject: Issue #15767: Touch up ModuleNotFoundError usage by import. Forgot to raise ModuleNotFoundError when None is found in sys.modules. This led to introducing the C function PyErr_SetImportErrorSubclass() to make setting ModuleNotFoundError easier. Also updated the reference docs to mention ModuleNotFoundError appropriately. Updated the docs for ModuleNotFoundError to mention the None in sys.modules case. Lastly, it was noticed that PyErr_SetImportError() was not setting an exception when returning None in one case. That issue is now fixed. --- Python/import.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 0bb46d2e1e..fad54e66ce 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1436,7 +1436,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, PyObject *msg = PyUnicode_FromFormat("import of %R halted; " "None in sys.modules", abs_name); if (msg != NULL) { - PyErr_SetImportError(msg, abs_name, NULL); + PyErr_SetImportErrorSubclass(PyExc_ModuleNotFoundError, msg, + abs_name, NULL); Py_DECREF(msg); } mod = NULL; -- cgit v1.2.1 From 23c2e70efd68fb16de7b6b3ad0e469784c966ace Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sun, 23 Jun 2013 15:53:09 +0200 Subject: import.c does neither need mode_t nor _mkdir() anymore --- Python/import.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index fad54e66ce..b9c5924887 100644 --- a/Python/import.c +++ b/Python/import.c @@ -19,14 +19,6 @@ extern "C" { #endif -#ifdef MS_WINDOWS -/* for stat.st_mode */ -typedef unsigned short mode_t; -/* for _mkdir */ -#include -#endif - - #define CACHEDIR "__pycache__" /* See _PyImport_FixupExtensionObject() below */ -- cgit v1.2.1 From af5e4f4219618da2bfcb02b52ac7c7ac54b7542a Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 4 Jul 2013 17:48:16 -0400 Subject: Issue #15767: Revert 3a50025f1900 for ModuleNotFoundError --- Python/import.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index b9c5924887..2e5d205973 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1428,8 +1428,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, PyObject *msg = PyUnicode_FromFormat("import of %R halted; " "None in sys.modules", abs_name); if (msg != NULL) { - PyErr_SetImportErrorSubclass(PyExc_ModuleNotFoundError, msg, - abs_name, NULL); + PyErr_SetImportError(msg, abs_name, NULL); Py_DECREF(msg); } mod = NULL; -- cgit v1.2.1 From 556ce6a1ab262d2aa56c505aecf6173382ed0e3c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 16 Jul 2013 22:26:05 +0200 Subject: Issue #18408: handle PySys_GetObject() failure, raise a RuntimeError --- Python/import.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 2e5d205973..a1c0aee540 100644 --- a/Python/import.c +++ b/Python/import.c @@ -85,8 +85,10 @@ _PyImportZip_Init(void) int err = 0; path_hooks = PySys_GetObject("path_hooks"); - if (path_hooks == NULL) + if (path_hooks == NULL) { + PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path_hooks"); goto error; + } if (Py_VerboseFlag) PySys_WriteStderr("# installing zipimport hook\n"); @@ -944,11 +946,11 @@ PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path) { PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL; - if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) { - if ((path_hooks = PySys_GetObject("path_hooks"))) { - importer = get_path_importer(path_importer_cache, - path_hooks, path); - } + path_importer_cache = PySys_GetObject("path_importer_cache"); + path_hooks = PySys_GetObject("path_hooks"); + if (path_importer_cache != NULL && path_hooks != NULL) { + importer = get_path_importer(path_importer_cache, + path_hooks, path); } Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */ return importer; -- cgit v1.2.1 From c506ce6f93bff13d93144e71284cf0e5acf34814 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 31 Jul 2013 23:14:08 +0200 Subject: Issue #18214: Improve finalization of Python modules to avoid setting their globals to None, in most cases. --- Python/import.c | 159 ++++++++++++++++++++++++-------------------------------- 1 file changed, 68 insertions(+), 91 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index c6222ec57f..09106555a3 100644 --- a/Python/import.c +++ b/Python/import.c @@ -277,6 +277,7 @@ static char* sys_deletes[] = { "path", "argv", "ps1", "ps2", "last_type", "last_value", "last_traceback", "path_hooks", "path_importer_cache", "meta_path", + "__interactivehook__", /* misc stuff */ "flags", "float_info", NULL @@ -289,40 +290,17 @@ static char* sys_files[] = { NULL }; -static int -is_essential_module(PyObject *name) -{ - Py_ssize_t name_len; - char *name_str = PyUnicode_AsUTF8AndSize(name, &name_len); - - if (name_str == NULL) { - PyErr_Clear(); - return 0; - } - if (strcmp(name_str, "builtins") == 0) - return 1; - if (strcmp(name_str, "sys") == 0) - return 1; - /* These are all needed for stderr to still function */ - if (strcmp(name_str, "codecs") == 0) - return 1; - if (strcmp(name_str, "_codecs") == 0) - return 1; - if (strncmp(name_str, "encodings.", 10) == 0) - return 1; - return 0; -} - - /* Un-initialize things, as good as we can */ void PyImport_Cleanup(void) { - Py_ssize_t pos, ndone; + Py_ssize_t pos; PyObject *key, *value, *dict; PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; + PyObject *builtins = interp->builtins; + PyObject *weaklist = NULL; if (modules == NULL) return; /* Already done */ @@ -333,6 +311,8 @@ PyImport_Cleanup(void) deleted *last* of all, they would come too late in the normal destruction order. Sigh. */ + /* XXX Perhaps these precautions are obsolete. Who knows? */ + value = PyDict_GetItemString(modules, "builtins"); if (value != NULL && PyModule_Check(value)) { dict = PyModule_GetDict(value); @@ -360,87 +340,84 @@ PyImport_Cleanup(void) } } - /* First, delete __main__ */ - value = PyDict_GetItemString(modules, "__main__"); - if (value != NULL && PyModule_Check(value)) { - if (Py_VerboseFlag) - PySys_WriteStderr("# cleanup __main__\n"); - _PyModule_Clear(value); - PyDict_SetItemString(modules, "__main__", Py_None); - } - - /* The special treatment of "builtins" here is because even - when it's not referenced as a module, its dictionary is - referenced by almost every module's __builtins__. Since - deleting a module clears its dictionary (even if there are - references left to it), we need to delete the "builtins" - module last. Likewise, we don't delete sys until the very - end because it is implicitly referenced (e.g. by print). - - Also note that we 'delete' modules by replacing their entry - in the modules dict with None, rather than really deleting - them; this avoids a rehash of the modules dictionary and - also marks them as "non existent" so they won't be - re-imported. */ - - /* Next, repeatedly delete modules with a reference count of - one (skipping builtins and sys) and delete them */ - do { - ndone = 0; - pos = 0; - while (PyDict_Next(modules, &pos, &key, &value)) { - if (value->ob_refcnt != 1) - continue; - if (PyUnicode_Check(key) && PyModule_Check(value)) { - if (is_essential_module(key)) - continue; - if (Py_VerboseFlag) - PySys_FormatStderr( - "# cleanup[1] %U\n", key); - _PyModule_Clear(value); - PyDict_SetItem(modules, key, Py_None); - ndone++; - } - } - } while (ndone > 0); - - /* Next, delete all modules (still skipping builtins and sys) */ + /* We prepare a list which will receive (name, weakref) tuples of + modules when they are removed from sys.modules. The name is used + for diagnosis messages (in verbose mode), while the weakref helps + detect those modules which have been held alive. */ + weaklist = PyList_New(0); + +#define STORE_MODULE_WEAKREF(mod) \ + if (weaklist != NULL) { \ + PyObject *name = PyModule_GetNameObject(mod); \ + PyObject *wr = PyWeakref_NewRef(mod, NULL); \ + if (name && wr) { \ + PyObject *tup = PyTuple_Pack(2, name, wr); \ + PyList_Append(weaklist, tup); \ + Py_XDECREF(tup); \ + } \ + Py_XDECREF(name); \ + Py_XDECREF(wr); \ + if (PyErr_Occurred()) \ + PyErr_Clear(); \ + } + + /* Remove all modules from sys.modules, hoping that garbage collection + can reclaim most of them. */ pos = 0; while (PyDict_Next(modules, &pos, &key, &value)) { - if (PyUnicode_Check(key) && PyModule_Check(value)) { - if (is_essential_module(key)) - continue; - if (Py_VerboseFlag) - PySys_FormatStderr("# cleanup[2] %U\n", key); - _PyModule_Clear(value); + if (PyModule_Check(value)) { + if (Py_VerboseFlag && PyUnicode_Check(key)) + PySys_FormatStderr("# cleanup[2] removing %U\n", key, value); + STORE_MODULE_WEAKREF(value); PyDict_SetItem(modules, key, Py_None); } } - /* Collect garbage remaining after deleting the modules. Mostly - reference cycles created by classes. */ - PyGC_Collect(); - + /* Clear the modules dict. */ + PyDict_Clear(modules); + /* Replace the interpreter's reference to builtins with an empty dict + (module globals still have a reference to the original builtins). */ + builtins = interp->builtins; + interp->builtins = PyDict_New(); + Py_DECREF(builtins); + /* Collect references */ + _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings machinery. */ _PyGC_DumpShutdownStats(); - /* Next, delete all remaining modules */ - pos = 0; - while (PyDict_Next(modules, &pos, &key, &value)) { - if (PyUnicode_Check(key) && PyModule_Check(value)) { + /* Now, if there are any modules left alive, clear their globals to + minimize potential leaks. All C extension modules actually end + up here, since they are kept alive in the interpreter state. */ + if (weaklist != NULL) { + Py_ssize_t i, n; + n = PyList_GET_SIZE(weaklist); + for (i = 0; i < n; i++) { + PyObject *tup = PyList_GET_ITEM(weaklist, i); + PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); + if (mod == Py_None) + continue; + Py_INCREF(mod); + assert(PyModule_Check(mod)); if (Py_VerboseFlag) - PySys_FormatStderr("# cleanup[3] %U\n", key); - _PyModule_Clear(value); - PyDict_SetItem(modules, key, Py_None); + PySys_FormatStderr("# cleanup[3] wiping %U\n", + PyTuple_GET_ITEM(tup, 0), mod); + _PyModule_Clear(mod); + Py_DECREF(mod); } + Py_DECREF(weaklist); } - /* Finally, clear and delete the modules directory */ - PyDict_Clear(modules); - _PyGC_CollectNoFail(); + /* Clear and delete the modules directory. Actual modules will + still be there only if imported during the execution of some + destructor. */ interp->modules = NULL; Py_DECREF(modules); + + /* Once more */ + _PyGC_CollectNoFail(); + +#undef STORE_MODULE_WEAKREF } -- cgit v1.2.1 From 1406c9e41bf56b4ec28c417b2f79abf5c26c77b9 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 1 Aug 2013 22:07:06 +0200 Subject: Issue #10241: Clear extension module dict copies at interpreter shutdown. Patch by Neil Schemenauer, minimally modified. --- Python/import.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 09106555a3..ce09ebedd4 100644 --- a/Python/import.c +++ b/Python/import.c @@ -380,6 +380,8 @@ PyImport_Cleanup(void) builtins = interp->builtins; interp->builtins = PyDict_New(); Py_DECREF(builtins); + /* Clear module dict copies stored in the interpreter state */ + _PyState_ClearModules(); /* Collect references */ _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings -- cgit v1.2.1 From 5d62cd8fe1ac1e2f8286f286530bf16e995cd34d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 2 Aug 2013 20:39:46 +0200 Subject: Backout 62658d9d8926 (issue #10241): it causes a crash at shutdown when deallocating a Tkapp object. --- Python/import.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index ce09ebedd4..09106555a3 100644 --- a/Python/import.c +++ b/Python/import.c @@ -380,8 +380,6 @@ PyImport_Cleanup(void) builtins = interp->builtins; interp->builtins = PyDict_New(); Py_DECREF(builtins); - /* Clear module dict copies stored in the interpreter state */ - _PyState_ClearModules(); /* Collect references */ _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings -- cgit v1.2.1 From 7af1703c1a9afb675322700a1148a1c78e5cf0a9 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 6 Aug 2013 22:50:15 +0200 Subject: Improve verbose reporting of shutdown phase by using the "public" module name --- Python/import.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 09106555a3..be73d4bba8 100644 --- a/Python/import.c +++ b/Python/import.c @@ -345,17 +345,17 @@ PyImport_Cleanup(void) for diagnosis messages (in verbose mode), while the weakref helps detect those modules which have been held alive. */ weaklist = PyList_New(0); + if (weaklist == NULL) + PyErr_Clear(); -#define STORE_MODULE_WEAKREF(mod) \ +#define STORE_MODULE_WEAKREF(name, mod) \ if (weaklist != NULL) { \ - PyObject *name = PyModule_GetNameObject(mod); \ PyObject *wr = PyWeakref_NewRef(mod, NULL); \ if (name && wr) { \ PyObject *tup = PyTuple_Pack(2, name, wr); \ PyList_Append(weaklist, tup); \ Py_XDECREF(tup); \ } \ - Py_XDECREF(name); \ Py_XDECREF(wr); \ if (PyErr_Occurred()) \ PyErr_Clear(); \ @@ -368,7 +368,7 @@ PyImport_Cleanup(void) if (PyModule_Check(value)) { if (Py_VerboseFlag && PyUnicode_Check(key)) PySys_FormatStderr("# cleanup[2] removing %U\n", key, value); - STORE_MODULE_WEAKREF(value); + STORE_MODULE_WEAKREF(key, value); PyDict_SetItem(modules, key, Py_None); } } @@ -394,14 +394,15 @@ PyImport_Cleanup(void) n = PyList_GET_SIZE(weaklist); for (i = 0; i < n; i++) { PyObject *tup = PyList_GET_ITEM(weaklist, i); + PyObject *name = PyTuple_GET_ITEM(tup, 0); PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); if (mod == Py_None) continue; Py_INCREF(mod); assert(PyModule_Check(mod)); - if (Py_VerboseFlag) + if (Py_VerboseFlag && PyUnicode_Check(name)) PySys_FormatStderr("# cleanup[3] wiping %U\n", - PyTuple_GET_ITEM(tup, 0), mod); + name, mod); _PyModule_Clear(mod); Py_DECREF(mod); } -- cgit v1.2.1 From e4564245bddda91df68f13f211e1583ecf6f8c1a Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 11 Aug 2013 00:30:09 +0200 Subject: Issue #10241: Clear extension module dict copies at interpreter shutdown. Patch by Neil Schemenauer, minimally modified. (re-apply after fix for tkinter-related crash) --- Python/import.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index be73d4bba8..113123d564 100644 --- a/Python/import.c +++ b/Python/import.c @@ -380,6 +380,8 @@ PyImport_Cleanup(void) builtins = interp->builtins; interp->builtins = PyDict_New(); Py_DECREF(builtins); + /* Clear module dict copies stored in the interpreter state */ + _PyState_ClearModules(); /* Collect references */ _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings -- cgit v1.2.1 From b8d637188fd301e181ec23106899132f93b50246 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 22 Aug 2013 02:23:13 +0200 Subject: remove unused declaration --- Python/import.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 113123d564..b18ba2cb98 100644 --- a/Python/import.c +++ b/Python/import.c @@ -24,9 +24,6 @@ extern "C" { /* See _PyImport_FixupExtensionObject() below */ static PyObject *extensions = NULL; -/* Function from Parser/tokenizer.c */ -extern char * PyTokenizer_FindEncodingFilename(int, PyObject *); - /* This table is defined in config.c: */ extern struct _inittab _PyImport_Inittab[]; -- cgit v1.2.1 From e5883d6d95989121670eca012dd5bde1721747e7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 28 Aug 2013 00:53:59 +0200 Subject: Issue #18571: Implementation of the PEP 446: file descriptors and file handles are now created non-inheritable; add functions os.get/set_inheritable(), os.get/set_handle_inheritable() and socket.socket.get/set_inheritable(). --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index b18ba2cb98..1a162ee711 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1797,7 +1797,7 @@ imp_load_dynamic(PyObject *self, PyObject *args) &name, PyUnicode_FSDecoder, &pathname, &fob)) return NULL; if (fob != NULL) { - fp = _Py_fopen(pathname, "r"); + fp = _Py_fopen_obj(pathname, "r"); if (fp == NULL) { Py_DECREF(pathname); if (!PyErr_Occurred()) -- cgit v1.2.1 From 6e75c19396402b107f1dfffa8746c6b8b679a9a4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Oct 2013 21:03:34 +0300 Subject: Issue #1772673: The type of `char*` arguments now changed to `const char*`. --- Python/import.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 1a162ee711..c96106f373 100644 --- a/Python/import.c +++ b/Python/import.c @@ -517,7 +517,7 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, } int -_PyImport_FixupBuiltin(PyObject *mod, char *name) +_PyImport_FixupBuiltin(PyObject *mod, const char *name) { int res; PyObject *nameobj; @@ -656,22 +656,23 @@ remove_module(PyObject *name) * interface. The other two exist primarily for backward compatibility. */ PyObject * -PyImport_ExecCodeModule(char *name, PyObject *co) +PyImport_ExecCodeModule(const char *name, PyObject *co) { return PyImport_ExecCodeModuleWithPathnames( name, co, (char *)NULL, (char *)NULL); } PyObject * -PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname) +PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname) { return PyImport_ExecCodeModuleWithPathnames( name, co, pathname, (char *)NULL); } PyObject * -PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname, - char *cpathname) +PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, + const char *pathname, + const char *cpathname) { PyObject *m = NULL; PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL; @@ -1019,7 +1020,7 @@ get_frozen_object(PyObject *name) size = p->size; if (size < 0) size = -size; - return PyMarshal_ReadObjectFromString((char *)p->code, size); + return PyMarshal_ReadObjectFromString((const char *)p->code, size); } static PyObject * @@ -1071,7 +1072,7 @@ PyImport_ImportFrozenModuleObject(PyObject *name) ispackage = (size < 0); if (ispackage) size = -size; - co = PyMarshal_ReadObjectFromString((char *)p->code, size); + co = PyMarshal_ReadObjectFromString((const char *)p->code, size); if (co == NULL) return -1; if (!PyCode_Check(co)) { @@ -1113,7 +1114,7 @@ err_return: } int -PyImport_ImportFrozenModule(char *name) +PyImport_ImportFrozenModule(const char *name) { PyObject *nameobj; int ret; -- cgit v1.2.1 From b727bdb13eb840c0d5ed319c2ca8e4c84c429e7b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Nov 2013 00:43:05 +0100 Subject: Issue #19512: Use the new _PyId_builtins identifier --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index c96106f373..aea29e28f3 100644 --- a/Python/import.c +++ b/Python/import.c @@ -310,7 +310,7 @@ PyImport_Cleanup(void) /* XXX Perhaps these precautions are obsolete. Who knows? */ - value = PyDict_GetItemString(modules, "builtins"); + value = _PyDict_GetItemId(modules, &_PyId_builtins); if (value != NULL && PyModule_Check(value)) { dict = PyModule_GetDict(value); if (Py_VerboseFlag) -- cgit v1.2.1 From 359ed22ea49d63923b451351ebf80decaaa7b79e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Nov 2013 23:07:29 +0100 Subject: Issue #19512, #19515: remove shared identifiers, move identifiers where they are used. Move also _Py_IDENTIFIER() defintions to the top in modified files to remove identifiers duplicated in the same file. --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index aea29e28f3..c96106f373 100644 --- a/Python/import.c +++ b/Python/import.c @@ -310,7 +310,7 @@ PyImport_Cleanup(void) /* XXX Perhaps these precautions are obsolete. Who knows? */ - value = _PyDict_GetItemId(modules, &_PyId_builtins); + value = PyDict_GetItemString(modules, "builtins"); if (value != NULL && PyModule_Check(value)) { dict = PyModule_GetDict(value); if (Py_VerboseFlag) -- cgit v1.2.1 From 9e917bb6e5ab06d5c47fa970737d73b99a2fd17f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 13 Nov 2013 12:11:36 +0100 Subject: Issue #19437: Fix PyImport_ImportModuleLevelObject(), handle PyUnicode_Substring() failure (ex: MemoryError) --- Python/import.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index c96106f373..ad181a2942 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1364,7 +1364,11 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, goto error; } } + base = PyUnicode_Substring(package, 0, last_dot); + if (base == NULL) + goto error; + if (PyUnicode_GET_LENGTH(name) > 0) { PyObject *borrowed_dot, *seq = NULL; -- cgit v1.2.1 From d65ab2d444f5d21586935abe6da2effeb98c498f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 14 Nov 2013 22:38:52 +0100 Subject: Issue #19437: Fix init_builtin(), handle _PyImport_FindExtensionObject() failure --- Python/import.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index ad181a2942..f0ac0515a0 100644 --- a/Python/import.c +++ b/Python/import.c @@ -948,8 +948,12 @@ static int init_builtin(PyObject *name) { struct _inittab *p; + PyObject *mod; - if (_PyImport_FindExtensionObject(name, name) != NULL) + mod = _PyImport_FindExtensionObject(name, name); + if (PyErr_Occurred()) + return -1; + if (mod != NULL) return 1; for (p = PyImport_Inittab; p->name != NULL; p++) { -- cgit v1.2.1 From af248a41919513d573cd57e6cb6cdfd4a9dde66b Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 22 Nov 2013 09:05:39 -0700 Subject: Implement PEP 451 (ModuleSpec). --- Python/import.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index f0ac0515a0..584b1b41cd 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1232,7 +1232,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, int level) { _Py_IDENTIFIER(__import__); - _Py_IDENTIFIER(__initializing__); + _Py_IDENTIFIER(__spec__); + _Py_IDENTIFIER(_initializing); _Py_IDENTIFIER(__package__); _Py_IDENTIFIER(__path__); _Py_IDENTIFIER(__name__); @@ -1426,16 +1427,21 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, goto error_with_unlock; } else if (mod != NULL) { - PyObject *value; + PyObject *value = NULL; + PyObject *spec; int initializing = 0; Py_INCREF(mod); /* Optimization: only call _bootstrap._lock_unlock_module() if - __initializing__ is true. - NOTE: because of this, __initializing__ must be set *before* + __spec__._initializing is true. + NOTE: because of this, initializing must be set *before* stuffing the new module in sys.modules. */ - value = _PyObject_GetAttrId(mod, &PyId___initializing__); + spec = _PyObject_GetAttrId(mod, &PyId___spec__); + if (spec != NULL) { + value = _PyObject_GetAttrId(spec, &PyId__initializing); + Py_DECREF(spec); + } if (value == NULL) PyErr_Clear(); else { -- cgit v1.2.1 From 4d1abac8225602cbdaebad68b749357d097ee9f9 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 9 Jan 2014 19:03:32 -0500 Subject: Issue #20152: import.c now uses Argument Clinic. --- Python/import.c | 550 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 463 insertions(+), 87 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 584b1b41cd..bb2f84af09 100644 --- a/Python/import.c +++ b/Python/import.c @@ -31,6 +31,19 @@ struct _inittab *PyImport_Inittab = _PyImport_Inittab; static PyObject *initstr = NULL; +/*[clinic input] +module _imp +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + +/*[python input] +class fs_unicode_converter(CConverter): + type = 'PyObject *' + converter = 'PyUnicode_FSDecoder' + +[python start generated code]*/ +/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /* Initialize things */ void @@ -210,8 +223,39 @@ _PyImport_ReInitLock(void) #endif +/*[clinic input] +_imp.lock_held + +Return True if the import lock is currently held, else False. + +On platforms without threads, return False. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_lock_held__doc__, +"lock_held()\n" +"Return True if the import lock is currently held, else False.\n" +"\n" +"On platforms without threads, return False."); + +#define _IMP_LOCK_HELD_METHODDEF \ + {"lock_held", (PyCFunction)_imp_lock_held, METH_NOARGS, _imp_lock_held__doc__}, + +static PyObject * +_imp_lock_held_impl(PyModuleDef *module); + static PyObject * -imp_lock_held(PyObject *self, PyObject *noargs) +_imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _imp_lock_held_impl(module); + + return return_value; +} + +static PyObject * +_imp_lock_held_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=c5858b257881f94dee95526229a8d1a57ccff158]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -220,8 +264,41 @@ imp_lock_held(PyObject *self, PyObject *noargs) #endif } +/*[clinic input] +_imp.acquire_lock + +Acquires the interpreter's import lock for the current thread. + +This lock should be used by import hooks to ensure thread-safety when importing +modules. On platforms without threads, this function does nothing. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_acquire_lock__doc__, +"acquire_lock()\n" +"Acquires the interpreter\'s import lock for the current thread.\n" +"\n" +"This lock should be used by import hooks to ensure thread-safety when importing\n" +"modules. On platforms without threads, this function does nothing."); + +#define _IMP_ACQUIRE_LOCK_METHODDEF \ + {"acquire_lock", (PyCFunction)_imp_acquire_lock, METH_NOARGS, _imp_acquire_lock__doc__}, + +static PyObject * +_imp_acquire_lock_impl(PyModuleDef *module); + static PyObject * -imp_acquire_lock(PyObject *self, PyObject *noargs) +_imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _imp_acquire_lock_impl(module); + + return return_value; +} + +static PyObject * +_imp_acquire_lock_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=badb56ed0079a6b902c9616fe068d572765b1863]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -230,8 +307,39 @@ imp_acquire_lock(PyObject *self, PyObject *noargs) return Py_None; } +/*[clinic input] +_imp.release_lock + +Release the interpreter's import lock. + +On platforms without threads, this function does nothing. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_release_lock__doc__, +"release_lock()\n" +"Release the interpreter\'s import lock.\n" +"\n" +"On platforms without threads, this function does nothing."); + +#define _IMP_RELEASE_LOCK_METHODDEF \ + {"release_lock", (PyCFunction)_imp_release_lock, METH_NOARGS, _imp_release_lock__doc__}, + +static PyObject * +_imp_release_lock_impl(PyModuleDef *module); + +static PyObject * +_imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _imp_release_lock_impl(module); + + return return_value; +} + static PyObject * -imp_release_lock(PyObject *self, PyObject *noargs) +_imp_release_lock_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=f1c2a75e3136a113184e0af2a676d5f0b5b685b4]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -817,28 +925,57 @@ update_compiled_module(PyCodeObject *co, PyObject *newname) Py_DECREF(oldname); } -static PyObject * -imp_fix_co_filename(PyObject *self, PyObject *args) -{ - PyObject *co; - PyObject *file_path; +/*[clinic input] +_imp._fix_co_filename - if (!PyArg_ParseTuple(args, "OO:_fix_co_filename", &co, &file_path)) - return NULL; + code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") + Code object to change. - if (!PyCode_Check(co)) { - PyErr_SetString(PyExc_TypeError, - "first argument must be a code object"); - return NULL; - } + path: unicode + File path to use. + / - if (!PyUnicode_Check(file_path)) { - PyErr_SetString(PyExc_TypeError, - "second argument must be a string"); - return NULL; - } +Changes code.co_filename to specify the passed-in file path. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp__fix_co_filename__doc__, +"_fix_co_filename(code, path)\n" +"Changes code.co_filename to specify the passed-in file path.\n" +"\n" +" code\n" +" Code object to change.\n" +" path\n" +" File path to use."); - update_compiled_module((PyCodeObject*)co, file_path); +#define _IMP__FIX_CO_FILENAME_METHODDEF \ + {"_fix_co_filename", (PyCFunction)_imp__fix_co_filename, METH_VARARGS, _imp__fix_co_filename__doc__}, + +static PyObject * +_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path); + +static PyObject * +_imp__fix_co_filename(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyCodeObject *code; + PyObject *path; + + if (!PyArg_ParseTuple(args, + "O!U:_fix_co_filename", + &PyCode_Type, &code, &path)) + goto exit; + return_value = _imp__fix_co_filename_impl(module, code, path); + +exit: + return return_value; +} + +static PyObject * +_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) +/*[clinic end generated code: checksum=4f55bad308072b30ad1921068fc4ce85bd2b39bf]*/ + +{ + update_compiled_module((PyCodeObject*)code, path); Py_RETURN_NONE; } @@ -1691,8 +1828,35 @@ PyImport_Import(PyObject *module_name) return r; } +/*[clinic input] +_imp.extension_suffixes + +Returns the list of file suffixes used to identify extension modules. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_extension_suffixes__doc__, +"extension_suffixes()\n" +"Returns the list of file suffixes used to identify extension modules."); + +#define _IMP_EXTENSION_SUFFIXES_METHODDEF \ + {"extension_suffixes", (PyCFunction)_imp_extension_suffixes, METH_NOARGS, _imp_extension_suffixes__doc__}, + static PyObject * -imp_extension_suffixes(PyObject *self, PyObject *noargs) +_imp_extension_suffixes_impl(PyModuleDef *module); + +static PyObject * +_imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _imp_extension_suffixes_impl(module); + + return return_value; +} + +static PyObject * +_imp_extension_suffixes_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=835921e67fd698e22e101eea64839d1ad62b6451]*/ { PyObject *list; const char *suffix; @@ -1720,14 +1884,48 @@ imp_extension_suffixes(PyObject *self, PyObject *noargs) return list; } +/*[clinic input] +_imp.init_builtin + + name: unicode + / + +Initializes a built-in module. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_init_builtin__doc__, +"init_builtin(name)\n" +"Initializes a built-in module."); + +#define _IMP_INIT_BUILTIN_METHODDEF \ + {"init_builtin", (PyCFunction)_imp_init_builtin, METH_VARARGS, _imp_init_builtin__doc__}, + +static PyObject * +_imp_init_builtin_impl(PyModuleDef *module, PyObject *name); + static PyObject * -imp_init_builtin(PyObject *self, PyObject *args) +_imp_init_builtin(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:init_builtin", + &name)) + goto exit; + return_value = _imp_init_builtin_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +_imp_init_builtin_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=59239206e5b2fb59358066e72fd0e72e55a7baf5]*/ +{ int ret; PyObject *m; - if (!PyArg_ParseTuple(args, "U:init_builtin", &name)) - return NULL; + ret = init_builtin(name); if (ret < 0) return NULL; @@ -1740,14 +1938,48 @@ imp_init_builtin(PyObject *self, PyObject *args) return m; } +/*[clinic input] +_imp.init_frozen + + name: unicode + / + +Initializes a frozen module. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_init_frozen__doc__, +"init_frozen(name)\n" +"Initializes a frozen module."); + +#define _IMP_INIT_FROZEN_METHODDEF \ + {"init_frozen", (PyCFunction)_imp_init_frozen, METH_VARARGS, _imp_init_frozen__doc__}, + static PyObject * -imp_init_frozen(PyObject *self, PyObject *args) +_imp_init_frozen_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_init_frozen(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:init_frozen", + &name)) + goto exit; + return_value = _imp_init_frozen_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +_imp_init_frozen_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=503fcc3de9961263e4d9484259af357a7d287a0b]*/ +{ int ret; PyObject *m; - if (!PyArg_ParseTuple(args, "U:init_frozen", &name)) - return NULL; + ret = PyImport_ImportFrozenModuleObject(name); if (ret < 0) return NULL; @@ -1760,61 +1992,229 @@ imp_init_frozen(PyObject *self, PyObject *args) return m; } +/*[clinic input] +_imp.get_frozen_object + + name: unicode + / + +Create a code object for a frozen module. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_get_frozen_object__doc__, +"get_frozen_object(name)\n" +"Create a code object for a frozen module."); + +#define _IMP_GET_FROZEN_OBJECT_METHODDEF \ + {"get_frozen_object", (PyCFunction)_imp_get_frozen_object, METH_VARARGS, _imp_get_frozen_object__doc__}, + static PyObject * -imp_get_frozen_object(PyObject *self, PyObject *args) +_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_get_frozen_object(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; PyObject *name; - if (!PyArg_ParseTuple(args, "U:get_frozen_object", &name)) - return NULL; + if (!PyArg_ParseTuple(args, + "U:get_frozen_object", + &name)) + goto exit; + return_value = _imp_get_frozen_object_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=7a6423a4daf139496b9a394ff3ac6130089d1cba]*/ +{ return get_frozen_object(name); } +/*[clinic input] +_imp.is_frozen_package + + name: unicode + / + +Returns True if the module name is of a frozen package. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_is_frozen_package__doc__, +"is_frozen_package(name)\n" +"Returns True if the module name is of a frozen package."); + +#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ + {"is_frozen_package", (PyCFunction)_imp_is_frozen_package, METH_VARARGS, _imp_is_frozen_package__doc__}, + static PyObject * -imp_is_frozen_package(PyObject *self, PyObject *args) +_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_is_frozen_package(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; PyObject *name; - if (!PyArg_ParseTuple(args, "U:is_frozen_package", &name)) - return NULL; + if (!PyArg_ParseTuple(args, + "U:is_frozen_package", + &name)) + goto exit; + return_value = _imp_is_frozen_package_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=dc7e361ea30b6945b8bbe7266d7b9a5ea433b510]*/ +{ return is_frozen_package(name); } +/*[clinic input] +_imp.is_builtin + + name: unicode + / + +Returns True if the module name corresponds to a built-in module. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_is_builtin__doc__, +"is_builtin(name)\n" +"Returns True if the module name corresponds to a built-in module."); + +#define _IMP_IS_BUILTIN_METHODDEF \ + {"is_builtin", (PyCFunction)_imp_is_builtin, METH_VARARGS, _imp_is_builtin__doc__}, + +static PyObject * +_imp_is_builtin_impl(PyModuleDef *module, PyObject *name); + static PyObject * -imp_is_builtin(PyObject *self, PyObject *args) +_imp_is_builtin(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; PyObject *name; - if (!PyArg_ParseTuple(args, "U:is_builtin", &name)) - return NULL; + + if (!PyArg_ParseTuple(args, + "U:is_builtin", + &name)) + goto exit; + return_value = _imp_is_builtin_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +_imp_is_builtin_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=353938c1d55210a1e3850d3ccba7539d02165cac]*/ +{ return PyLong_FromLong(is_builtin(name)); } +/*[clinic input] +_imp.is_frozen + + name: unicode + / + +Returns True if the module name corresponds to a frozen module. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_is_frozen__doc__, +"is_frozen(name)\n" +"Returns True if the module name corresponds to a frozen module."); + +#define _IMP_IS_FROZEN_METHODDEF \ + {"is_frozen", (PyCFunction)_imp_is_frozen, METH_VARARGS, _imp_is_frozen__doc__}, + +static PyObject * +_imp_is_frozen_impl(PyModuleDef *module, PyObject *name); + static PyObject * -imp_is_frozen(PyObject *self, PyObject *args) +_imp_is_frozen(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:is_frozen", + &name)) + goto exit; + return_value = _imp_is_frozen_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +_imp_is_frozen_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=978b547ddcb76fa6c4a181ad53569c9acf382c7b]*/ +{ const struct _frozen *p; - if (!PyArg_ParseTuple(args, "U:is_frozen", &name)) - return NULL; + p = find_frozen(name); return PyBool_FromLong((long) (p == NULL ? 0 : p->size)); } #ifdef HAVE_DYNAMIC_LOADING +/*[clinic input] +_imp.load_dynamic + + name: unicode + path: fs_unicode + file: object = NULL + / + +Loads an extension module. +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_load_dynamic__doc__, +"load_dynamic(name, path, file=None)\n" +"Loads an extension module."); + +#define _IMP_LOAD_DYNAMIC_METHODDEF \ + {"load_dynamic", (PyCFunction)_imp_load_dynamic, METH_VARARGS, _imp_load_dynamic__doc__}, + +static PyObject * +_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file); + +static PyObject * +_imp_load_dynamic(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *path; + PyObject *file = NULL; + + if (!PyArg_ParseTuple(args, + "UO&|O:load_dynamic", + &name, PyUnicode_FSDecoder, &path, &file)) + goto exit; + return_value = _imp_load_dynamic_impl(module, name, path, file); + +exit: + return return_value; +} + static PyObject * -imp_load_dynamic(PyObject *self, PyObject *args) +_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) +/*[clinic end generated code: checksum=6795f65d9ce003ccaf08e4e8eef484dc52e262d0]*/ { - PyObject *name, *pathname, *fob = NULL, *mod; + PyObject *mod; FILE *fp; - if (!PyArg_ParseTuple(args, "UO&|O:load_dynamic", - &name, PyUnicode_FSDecoder, &pathname, &fob)) - return NULL; - if (fob != NULL) { - fp = _Py_fopen_obj(pathname, "r"); + if (file != NULL) { + fp = _Py_fopen_obj(path, "r"); if (fp == NULL) { - Py_DECREF(pathname); + Py_DECREF(path); if (!PyErr_Occurred()) PyErr_SetFromErrno(PyExc_IOError); return NULL; @@ -1822,8 +2222,8 @@ imp_load_dynamic(PyObject *self, PyObject *args) } else fp = NULL; - mod = _PyImport_LoadDynamicModule(name, pathname, fp); - Py_DECREF(pathname); + mod = _PyImport_LoadDynamicModule(name, path, fp); + Py_DECREF(path); if (fp) fclose(fp); return mod; @@ -1832,49 +2232,25 @@ imp_load_dynamic(PyObject *self, PyObject *args) #endif /* HAVE_DYNAMIC_LOADING */ -/* Doc strings */ - PyDoc_STRVAR(doc_imp, "(Extremely) low-level import machinery bits as used by importlib and imp."); -PyDoc_STRVAR(doc_extension_suffixes, -"extension_suffixes() -> list of strings\n\ -Returns the list of file suffixes used to identify extension modules."); - -PyDoc_STRVAR(doc_lock_held, -"lock_held() -> boolean\n\ -Return True if the import lock is currently held, else False.\n\ -On platforms without threads, return False."); - -PyDoc_STRVAR(doc_acquire_lock, -"acquire_lock() -> None\n\ -Acquires the interpreter's import lock for the current thread.\n\ -This lock should be used by import hooks to ensure thread-safety\n\ -when importing modules.\n\ -On platforms without threads, this function does nothing."); - -PyDoc_STRVAR(doc_release_lock, -"release_lock() -> None\n\ -Release the interpreter's import lock.\n\ -On platforms without threads, this function does nothing."); - static PyMethodDef imp_methods[] = { - {"extension_suffixes", imp_extension_suffixes, METH_NOARGS, - doc_extension_suffixes}, - {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held}, - {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock}, - {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock}, - {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, - {"is_frozen_package", imp_is_frozen_package, METH_VARARGS}, - {"init_builtin", imp_init_builtin, METH_VARARGS}, - {"init_frozen", imp_init_frozen, METH_VARARGS}, - {"is_builtin", imp_is_builtin, METH_VARARGS}, - {"is_frozen", imp_is_frozen, METH_VARARGS}, + _IMP_EXTENSION_SUFFIXES_METHODDEF + _IMP_LOCK_HELD_METHODDEF + _IMP_ACQUIRE_LOCK_METHODDEF + _IMP_RELEASE_LOCK_METHODDEF + _IMP_GET_FROZEN_OBJECT_METHODDEF + _IMP_IS_FROZEN_PACKAGE_METHODDEF + _IMP_INIT_BUILTIN_METHODDEF + _IMP_INIT_FROZEN_METHODDEF + _IMP_IS_BUILTIN_METHODDEF + _IMP_IS_FROZEN_METHODDEF #ifdef HAVE_DYNAMIC_LOADING - {"load_dynamic", imp_load_dynamic, METH_VARARGS}, + _IMP_LOAD_DYNAMIC_METHODDEF #endif - {"_fix_co_filename", imp_fix_co_filename, METH_VARARGS}, - {NULL, NULL} /* sentinel */ + _IMP__FIX_CO_FILENAME_METHODDEF + {NULL, NULL} /* sentinel */ }; -- cgit v1.2.1 From 6c4f922ecfb375f095cea331737c791e1c3a4c3c Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 10 Jan 2014 07:43:55 -0500 Subject: Remove an unneeded cast. --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index bb2f84af09..be0995dac6 100644 --- a/Python/import.c +++ b/Python/import.c @@ -975,7 +975,7 @@ _imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *pa /*[clinic end generated code: checksum=4f55bad308072b30ad1921068fc4ce85bd2b39bf]*/ { - update_compiled_module((PyCodeObject*)code, path); + update_compiled_module(code, path); Py_RETURN_NONE; } -- cgit v1.2.1 From 046ef5bdc5e5ddcec18ae150d1b82de5a92ba943 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Fri, 17 Jan 2014 17:47:17 -0800 Subject: Issue #20287: Argument Clinic's output is now configurable, allowing delaying its output or even redirecting it to a separate file. --- Python/import.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index be0995dac6..fb7d88c02f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -246,16 +246,12 @@ _imp_lock_held_impl(PyModuleDef *module); static PyObject * _imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - PyObject *return_value = NULL; - - return_value = _imp_lock_held_impl(module); - - return return_value; + return _imp_lock_held_impl(module); } static PyObject * _imp_lock_held_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=c5858b257881f94dee95526229a8d1a57ccff158]*/ +/*[clinic end generated code: checksum=ede1cafb78eb22e3009602f684c8b780e2b82d62]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -289,16 +285,12 @@ _imp_acquire_lock_impl(PyModuleDef *module); static PyObject * _imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - PyObject *return_value = NULL; - - return_value = _imp_acquire_lock_impl(module); - - return return_value; + return _imp_acquire_lock_impl(module); } static PyObject * _imp_acquire_lock_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=badb56ed0079a6b902c9616fe068d572765b1863]*/ +/*[clinic end generated code: checksum=5b520b2416c5954a7cf0ed30955d68abe20b5868]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -330,16 +322,12 @@ _imp_release_lock_impl(PyModuleDef *module); static PyObject * _imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - PyObject *return_value = NULL; - - return_value = _imp_release_lock_impl(module); - - return return_value; + return _imp_release_lock_impl(module); } static PyObject * _imp_release_lock_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=f1c2a75e3136a113184e0af2a676d5f0b5b685b4]*/ +/*[clinic end generated code: checksum=efcd9d2923294c04371596e7f6d66a706d43fcac]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -1847,16 +1835,12 @@ _imp_extension_suffixes_impl(PyModuleDef *module); static PyObject * _imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - PyObject *return_value = NULL; - - return_value = _imp_extension_suffixes_impl(module); - - return return_value; + return _imp_extension_suffixes_impl(module); } static PyObject * _imp_extension_suffixes_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=835921e67fd698e22e101eea64839d1ad62b6451]*/ +/*[clinic end generated code: checksum=82fb35d8429a429a4dc80c84b45b1aad73ff1de7]*/ { PyObject *list; const char *suffix; -- cgit v1.2.1 From f4c0a31a47232b095911314ea560ab5269e160b9 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Fri, 24 Jan 2014 06:17:25 -0800 Subject: Issue #20189: Four additional builtin types (PyTypeObject, PyMethodDescr_Type, _PyMethodWrapper_Type, and PyWrapperDescr_Type) have been modified to provide introspection information for builtins. Also: many additional Lib, test suite, and Argument Clinic fixes. --- Python/import.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index fb7d88c02f..ae8ff5e915 100644 --- a/Python/import.c +++ b/Python/import.c @@ -232,7 +232,7 @@ On platforms without threads, return False. [clinic start generated code]*/ PyDoc_STRVAR(_imp_lock_held__doc__, -"lock_held()\n" +"lock_held(module)\n" "Return True if the import lock is currently held, else False.\n" "\n" "On platforms without threads, return False."); @@ -251,7 +251,7 @@ _imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_lock_held_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=ede1cafb78eb22e3009602f684c8b780e2b82d62]*/ +/*[clinic end generated code: checksum=17172a9917d389dd1564e2108fec34d23aecb6c2]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -270,7 +270,7 @@ modules. On platforms without threads, this function does nothing. [clinic start generated code]*/ PyDoc_STRVAR(_imp_acquire_lock__doc__, -"acquire_lock()\n" +"acquire_lock(module)\n" "Acquires the interpreter\'s import lock for the current thread.\n" "\n" "This lock should be used by import hooks to ensure thread-safety when importing\n" @@ -290,7 +290,7 @@ _imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_acquire_lock_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=5b520b2416c5954a7cf0ed30955d68abe20b5868]*/ +/*[clinic end generated code: checksum=20db30e18f6b8758386fe06907edb3f8e43080d7]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -308,7 +308,7 @@ On platforms without threads, this function does nothing. [clinic start generated code]*/ PyDoc_STRVAR(_imp_release_lock__doc__, -"release_lock()\n" +"release_lock(module)\n" "Release the interpreter\'s import lock.\n" "\n" "On platforms without threads, this function does nothing."); @@ -327,7 +327,7 @@ _imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_release_lock_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=efcd9d2923294c04371596e7f6d66a706d43fcac]*/ +/*[clinic end generated code: checksum=17749fd7752d2c392447a1f83c5d371f54d7ebd3]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -927,7 +927,7 @@ Changes code.co_filename to specify the passed-in file path. [clinic start generated code]*/ PyDoc_STRVAR(_imp__fix_co_filename__doc__, -"_fix_co_filename(code, path)\n" +"_fix_co_filename(module, code, path)\n" "Changes code.co_filename to specify the passed-in file path.\n" "\n" " code\n" @@ -960,7 +960,7 @@ exit: static PyObject * _imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) -/*[clinic end generated code: checksum=4f55bad308072b30ad1921068fc4ce85bd2b39bf]*/ +/*[clinic end generated code: checksum=d32cf2b2e0480c714f909921cc9e55d763b39dd5]*/ { update_compiled_module(code, path); @@ -1823,7 +1823,7 @@ Returns the list of file suffixes used to identify extension modules. [clinic start generated code]*/ PyDoc_STRVAR(_imp_extension_suffixes__doc__, -"extension_suffixes()\n" +"extension_suffixes(module)\n" "Returns the list of file suffixes used to identify extension modules."); #define _IMP_EXTENSION_SUFFIXES_METHODDEF \ @@ -1840,7 +1840,7 @@ _imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_extension_suffixes_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=82fb35d8429a429a4dc80c84b45b1aad73ff1de7]*/ +/*[clinic end generated code: checksum=625c8f11a5bbd4b85373f0a54f7f3ef19c55beb4]*/ { PyObject *list; const char *suffix; @@ -1878,7 +1878,7 @@ Initializes a built-in module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_init_builtin__doc__, -"init_builtin(name)\n" +"init_builtin(module, name)\n" "Initializes a built-in module."); #define _IMP_INIT_BUILTIN_METHODDEF \ @@ -1905,7 +1905,7 @@ exit: static PyObject * _imp_init_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=59239206e5b2fb59358066e72fd0e72e55a7baf5]*/ +/*[clinic end generated code: checksum=a4e4805a523757cd3ddfeec6e5b16740678fed6a]*/ { int ret; PyObject *m; @@ -1932,7 +1932,7 @@ Initializes a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_init_frozen__doc__, -"init_frozen(name)\n" +"init_frozen(module, name)\n" "Initializes a frozen module."); #define _IMP_INIT_FROZEN_METHODDEF \ @@ -1959,7 +1959,7 @@ exit: static PyObject * _imp_init_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=503fcc3de9961263e4d9484259af357a7d287a0b]*/ +/*[clinic end generated code: checksum=2a58c119dd3e121cf5a9924f936cfd7b40253c12]*/ { int ret; PyObject *m; @@ -1986,7 +1986,7 @@ Create a code object for a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_get_frozen_object__doc__, -"get_frozen_object(name)\n" +"get_frozen_object(module, name)\n" "Create a code object for a frozen module."); #define _IMP_GET_FROZEN_OBJECT_METHODDEF \ @@ -2013,7 +2013,7 @@ exit: static PyObject * _imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=7a6423a4daf139496b9a394ff3ac6130089d1cba]*/ +/*[clinic end generated code: checksum=94c9108b58dda80d187fef21275a009bd0f91e96]*/ { return get_frozen_object(name); } @@ -2028,7 +2028,7 @@ Returns True if the module name is of a frozen package. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_frozen_package__doc__, -"is_frozen_package(name)\n" +"is_frozen_package(module, name)\n" "Returns True if the module name is of a frozen package."); #define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ @@ -2055,7 +2055,7 @@ exit: static PyObject * _imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=dc7e361ea30b6945b8bbe7266d7b9a5ea433b510]*/ +/*[clinic end generated code: checksum=17a342b94dbe859cdfc361bc8a6bc1b3cb163364]*/ { return is_frozen_package(name); } @@ -2070,7 +2070,7 @@ Returns True if the module name corresponds to a built-in module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_builtin__doc__, -"is_builtin(name)\n" +"is_builtin(module, name)\n" "Returns True if the module name corresponds to a built-in module."); #define _IMP_IS_BUILTIN_METHODDEF \ @@ -2097,7 +2097,7 @@ exit: static PyObject * _imp_is_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=353938c1d55210a1e3850d3ccba7539d02165cac]*/ +/*[clinic end generated code: checksum=51c6139dcfd9bee1f40980ea68b7797f8489d69a]*/ { return PyLong_FromLong(is_builtin(name)); } @@ -2112,7 +2112,7 @@ Returns True if the module name corresponds to a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_frozen__doc__, -"is_frozen(name)\n" +"is_frozen(module, name)\n" "Returns True if the module name corresponds to a frozen module."); #define _IMP_IS_FROZEN_METHODDEF \ @@ -2139,7 +2139,7 @@ exit: static PyObject * _imp_is_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=978b547ddcb76fa6c4a181ad53569c9acf382c7b]*/ +/*[clinic end generated code: checksum=4b079fb45a495835056ea5604735d552d222be5c]*/ { const struct _frozen *p; @@ -2161,7 +2161,7 @@ Loads an extension module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_load_dynamic__doc__, -"load_dynamic(name, path, file=None)\n" +"load_dynamic(module, name, path, file=None)\n" "Loads an extension module."); #define _IMP_LOAD_DYNAMIC_METHODDEF \ @@ -2190,7 +2190,7 @@ exit: static PyObject * _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) -/*[clinic end generated code: checksum=6795f65d9ce003ccaf08e4e8eef484dc52e262d0]*/ +/*[clinic end generated code: checksum=63e051fd0d0350c785bf185be41b0892f9920622]*/ { PyObject *mod; FILE *fp; -- cgit v1.2.1 From 06dfef7169e62e9ef832275fbe1f072785b2e661 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Tue, 28 Jan 2014 05:00:08 -0800 Subject: Issue #20326: Argument Clinic now uses a simple, unique signature to annotate text signatures in docstrings, resulting in fewer false positives. "self" parameters are also explicitly marked, allowing inspect.Signature() to authoritatively detect (and skip) said parameters. Issue #20326: Argument Clinic now generates separate checksums for the input and output sections of the block, allowing external tools to verify that the input has not changed (and thus the output is not out-of-date). --- Python/import.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index ae8ff5e915..2fd9b4429b 100644 --- a/Python/import.c +++ b/Python/import.c @@ -34,7 +34,7 @@ static PyObject *initstr = NULL; /*[clinic input] module _imp [clinic start generated code]*/ -/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ /*[python input] class fs_unicode_converter(CConverter): @@ -42,7 +42,7 @@ class fs_unicode_converter(CConverter): converter = 'PyUnicode_FSDecoder' [python start generated code]*/ -/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=9d6786230166006e]*/ /* Initialize things */ @@ -232,7 +232,7 @@ On platforms without threads, return False. [clinic start generated code]*/ PyDoc_STRVAR(_imp_lock_held__doc__, -"lock_held(module)\n" +"sig=($module)\n" "Return True if the import lock is currently held, else False.\n" "\n" "On platforms without threads, return False."); @@ -251,7 +251,7 @@ _imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_lock_held_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=17172a9917d389dd1564e2108fec34d23aecb6c2]*/ +/*[clinic end generated code: output=5ce46d12a8e4c469 input=9b088f9b217d9bdf]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -270,7 +270,7 @@ modules. On platforms without threads, this function does nothing. [clinic start generated code]*/ PyDoc_STRVAR(_imp_acquire_lock__doc__, -"acquire_lock(module)\n" +"sig=($module)\n" "Acquires the interpreter\'s import lock for the current thread.\n" "\n" "This lock should be used by import hooks to ensure thread-safety when importing\n" @@ -290,7 +290,7 @@ _imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_acquire_lock_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=20db30e18f6b8758386fe06907edb3f8e43080d7]*/ +/*[clinic end generated code: output=b0dd6a132ad25961 input=4a2d4381866d5fdc]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -308,7 +308,7 @@ On platforms without threads, this function does nothing. [clinic start generated code]*/ PyDoc_STRVAR(_imp_release_lock__doc__, -"release_lock(module)\n" +"sig=($module)\n" "Release the interpreter\'s import lock.\n" "\n" "On platforms without threads, this function does nothing."); @@ -327,7 +327,7 @@ _imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_release_lock_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=17749fd7752d2c392447a1f83c5d371f54d7ebd3]*/ +/*[clinic end generated code: output=b1e6e9d723cf5f89 input=934fb11516dd778b]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -927,7 +927,7 @@ Changes code.co_filename to specify the passed-in file path. [clinic start generated code]*/ PyDoc_STRVAR(_imp__fix_co_filename__doc__, -"_fix_co_filename(module, code, path)\n" +"sig=($module, code, path)\n" "Changes code.co_filename to specify the passed-in file path.\n" "\n" " code\n" @@ -960,7 +960,7 @@ exit: static PyObject * _imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) -/*[clinic end generated code: checksum=d32cf2b2e0480c714f909921cc9e55d763b39dd5]*/ +/*[clinic end generated code: output=3fe5b5a1b0d497df input=895ba50e78b82f05]*/ { update_compiled_module(code, path); @@ -1823,7 +1823,7 @@ Returns the list of file suffixes used to identify extension modules. [clinic start generated code]*/ PyDoc_STRVAR(_imp_extension_suffixes__doc__, -"extension_suffixes(module)\n" +"sig=($module)\n" "Returns the list of file suffixes used to identify extension modules."); #define _IMP_EXTENSION_SUFFIXES_METHODDEF \ @@ -1840,7 +1840,7 @@ _imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_extension_suffixes_impl(PyModuleDef *module) -/*[clinic end generated code: checksum=625c8f11a5bbd4b85373f0a54f7f3ef19c55beb4]*/ +/*[clinic end generated code: output=c1bcfbddabefa00a input=ecdeeecfcb6f839e]*/ { PyObject *list; const char *suffix; @@ -1878,7 +1878,7 @@ Initializes a built-in module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_init_builtin__doc__, -"init_builtin(module, name)\n" +"sig=($module, name)\n" "Initializes a built-in module."); #define _IMP_INIT_BUILTIN_METHODDEF \ @@ -1905,7 +1905,7 @@ exit: static PyObject * _imp_init_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=a4e4805a523757cd3ddfeec6e5b16740678fed6a]*/ +/*[clinic end generated code: output=02437efd4668f53e input=f934d2231ec52a2e]*/ { int ret; PyObject *m; @@ -1932,7 +1932,7 @@ Initializes a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_init_frozen__doc__, -"init_frozen(module, name)\n" +"sig=($module, name)\n" "Initializes a frozen module."); #define _IMP_INIT_FROZEN_METHODDEF \ @@ -1959,7 +1959,7 @@ exit: static PyObject * _imp_init_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=2a58c119dd3e121cf5a9924f936cfd7b40253c12]*/ +/*[clinic end generated code: output=20cea421af513afe input=13019adfc04f3fb3]*/ { int ret; PyObject *m; @@ -1986,7 +1986,7 @@ Create a code object for a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_get_frozen_object__doc__, -"get_frozen_object(module, name)\n" +"sig=($module, name)\n" "Create a code object for a frozen module."); #define _IMP_GET_FROZEN_OBJECT_METHODDEF \ @@ -2013,7 +2013,7 @@ exit: static PyObject * _imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=94c9108b58dda80d187fef21275a009bd0f91e96]*/ +/*[clinic end generated code: output=f00d01ae30ec842f input=ed689bc05358fdbd]*/ { return get_frozen_object(name); } @@ -2028,7 +2028,7 @@ Returns True if the module name is of a frozen package. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_frozen_package__doc__, -"is_frozen_package(module, name)\n" +"sig=($module, name)\n" "Returns True if the module name is of a frozen package."); #define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ @@ -2055,7 +2055,7 @@ exit: static PyObject * _imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=17a342b94dbe859cdfc361bc8a6bc1b3cb163364]*/ +/*[clinic end generated code: output=35c78f2448c6fcff input=81b6cdecd080fbb8]*/ { return is_frozen_package(name); } @@ -2070,7 +2070,7 @@ Returns True if the module name corresponds to a built-in module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_builtin__doc__, -"is_builtin(module, name)\n" +"sig=($module, name)\n" "Returns True if the module name corresponds to a built-in module."); #define _IMP_IS_BUILTIN_METHODDEF \ @@ -2097,7 +2097,7 @@ exit: static PyObject * _imp_is_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=51c6139dcfd9bee1f40980ea68b7797f8489d69a]*/ +/*[clinic end generated code: output=641689f833347f66 input=86befdac021dd1c7]*/ { return PyLong_FromLong(is_builtin(name)); } @@ -2112,7 +2112,7 @@ Returns True if the module name corresponds to a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_frozen__doc__, -"is_frozen(module, name)\n" +"sig=($module, name)\n" "Returns True if the module name corresponds to a frozen module."); #define _IMP_IS_FROZEN_METHODDEF \ @@ -2139,7 +2139,7 @@ exit: static PyObject * _imp_is_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: checksum=4b079fb45a495835056ea5604735d552d222be5c]*/ +/*[clinic end generated code: output=0f80c7a3f283a686 input=7301dbca1897d66b]*/ { const struct _frozen *p; @@ -2161,7 +2161,7 @@ Loads an extension module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_load_dynamic__doc__, -"load_dynamic(module, name, path, file=None)\n" +"sig=($module, name, path, file=None)\n" "Loads an extension module."); #define _IMP_LOAD_DYNAMIC_METHODDEF \ @@ -2190,7 +2190,7 @@ exit: static PyObject * _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) -/*[clinic end generated code: checksum=63e051fd0d0350c785bf185be41b0892f9920622]*/ +/*[clinic end generated code: output=8f33f48dc6252948 input=af64f06e4bad3526]*/ { PyObject *mod; FILE *fp; -- cgit v1.2.1 From b35e8157c9c0286c886cf77eede6bea694d7930a Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Fri, 31 Jan 2014 22:03:12 -0800 Subject: #Issue 20456: Several improvements and bugfixes for Argument Clinic, including correctly generating code for Clinic blocks inside C preprocessor conditional blocks. --- Python/import.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 2fd9b4429b..5e5355d485 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2215,6 +2215,15 @@ _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyOb #endif /* HAVE_DYNAMIC_LOADING */ +/*[clinic input] +dump buffer +[clinic start generated code]*/ + +#ifndef _IMP_LOAD_DYNAMIC_METHODDEF + #define _IMP_LOAD_DYNAMIC_METHODDEF +#endif /* !defined(_IMP_LOAD_DYNAMIC_METHODDEF) */ +/*[clinic end generated code: output=d07c1d4a343a9579 input=524ce2e021e4eba6]*/ + PyDoc_STRVAR(doc_imp, "(Extremely) low-level import machinery bits as used by importlib and imp."); @@ -2230,9 +2239,7 @@ static PyMethodDef imp_methods[] = { _IMP_INIT_FROZEN_METHODDEF _IMP_IS_BUILTIN_METHODDEF _IMP_IS_FROZEN_METHODDEF -#ifdef HAVE_DYNAMIC_LOADING _IMP_LOAD_DYNAMIC_METHODDEF -#endif _IMP__FIX_CO_FILENAME_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -2324,3 +2331,4 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) #ifdef __cplusplus } #endif + -- cgit v1.2.1 From 2883d78b1932e3d3d15495380bfe2cdf0d1a7061 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sat, 8 Feb 2014 22:15:29 -0800 Subject: Issue #20530: Argument Clinic's signature format has been revised again. The new syntax is highly human readable while still preventing false positives. The syntax also extends Python syntax to denote "self" and positional-only parameters, allowing inspect.Signature objects to be totally accurate for all supported builtins in Python 3.4. --- Python/import.c | 72 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 24 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 5e5355d485..001d745783 100644 --- a/Python/import.c +++ b/Python/import.c @@ -232,7 +232,9 @@ On platforms without threads, return False. [clinic start generated code]*/ PyDoc_STRVAR(_imp_lock_held__doc__, -"sig=($module)\n" +"lock_held($module, /)\n" +"--\n" +"\n" "Return True if the import lock is currently held, else False.\n" "\n" "On platforms without threads, return False."); @@ -251,7 +253,7 @@ _imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_lock_held_impl(PyModuleDef *module) -/*[clinic end generated code: output=5ce46d12a8e4c469 input=9b088f9b217d9bdf]*/ +/*[clinic end generated code: output=dae65674966baa65 input=9b088f9b217d9bdf]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -270,7 +272,9 @@ modules. On platforms without threads, this function does nothing. [clinic start generated code]*/ PyDoc_STRVAR(_imp_acquire_lock__doc__, -"sig=($module)\n" +"acquire_lock($module, /)\n" +"--\n" +"\n" "Acquires the interpreter\'s import lock for the current thread.\n" "\n" "This lock should be used by import hooks to ensure thread-safety when importing\n" @@ -290,7 +294,7 @@ _imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_acquire_lock_impl(PyModuleDef *module) -/*[clinic end generated code: output=b0dd6a132ad25961 input=4a2d4381866d5fdc]*/ +/*[clinic end generated code: output=478f1fa089fdb9a4 input=4a2d4381866d5fdc]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -308,7 +312,9 @@ On platforms without threads, this function does nothing. [clinic start generated code]*/ PyDoc_STRVAR(_imp_release_lock__doc__, -"sig=($module)\n" +"release_lock($module, /)\n" +"--\n" +"\n" "Release the interpreter\'s import lock.\n" "\n" "On platforms without threads, this function does nothing."); @@ -327,7 +333,7 @@ _imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_release_lock_impl(PyModuleDef *module) -/*[clinic end generated code: output=b1e6e9d723cf5f89 input=934fb11516dd778b]*/ +/*[clinic end generated code: output=36c77a6832fdafd4 input=934fb11516dd778b]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -927,7 +933,9 @@ Changes code.co_filename to specify the passed-in file path. [clinic start generated code]*/ PyDoc_STRVAR(_imp__fix_co_filename__doc__, -"sig=($module, code, path)\n" +"_fix_co_filename($module, code, path, /)\n" +"--\n" +"\n" "Changes code.co_filename to specify the passed-in file path.\n" "\n" " code\n" @@ -960,7 +968,7 @@ exit: static PyObject * _imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) -/*[clinic end generated code: output=3fe5b5a1b0d497df input=895ba50e78b82f05]*/ +/*[clinic end generated code: output=6b4b1edeb0d55c5d input=895ba50e78b82f05]*/ { update_compiled_module(code, path); @@ -1823,7 +1831,9 @@ Returns the list of file suffixes used to identify extension modules. [clinic start generated code]*/ PyDoc_STRVAR(_imp_extension_suffixes__doc__, -"sig=($module)\n" +"extension_suffixes($module, /)\n" +"--\n" +"\n" "Returns the list of file suffixes used to identify extension modules."); #define _IMP_EXTENSION_SUFFIXES_METHODDEF \ @@ -1840,7 +1850,7 @@ _imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) static PyObject * _imp_extension_suffixes_impl(PyModuleDef *module) -/*[clinic end generated code: output=c1bcfbddabefa00a input=ecdeeecfcb6f839e]*/ +/*[clinic end generated code: output=bb30a2438167798c input=ecdeeecfcb6f839e]*/ { PyObject *list; const char *suffix; @@ -1878,7 +1888,9 @@ Initializes a built-in module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_init_builtin__doc__, -"sig=($module, name)\n" +"init_builtin($module, name, /)\n" +"--\n" +"\n" "Initializes a built-in module."); #define _IMP_INIT_BUILTIN_METHODDEF \ @@ -1905,7 +1917,7 @@ exit: static PyObject * _imp_init_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=02437efd4668f53e input=f934d2231ec52a2e]*/ +/*[clinic end generated code: output=a0244948a43f8e26 input=f934d2231ec52a2e]*/ { int ret; PyObject *m; @@ -1932,7 +1944,9 @@ Initializes a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_init_frozen__doc__, -"sig=($module, name)\n" +"init_frozen($module, name, /)\n" +"--\n" +"\n" "Initializes a frozen module."); #define _IMP_INIT_FROZEN_METHODDEF \ @@ -1959,7 +1973,7 @@ exit: static PyObject * _imp_init_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=20cea421af513afe input=13019adfc04f3fb3]*/ +/*[clinic end generated code: output=e4bc2bff296f8f22 input=13019adfc04f3fb3]*/ { int ret; PyObject *m; @@ -1986,7 +2000,9 @@ Create a code object for a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_get_frozen_object__doc__, -"sig=($module, name)\n" +"get_frozen_object($module, name, /)\n" +"--\n" +"\n" "Create a code object for a frozen module."); #define _IMP_GET_FROZEN_OBJECT_METHODDEF \ @@ -2013,7 +2029,7 @@ exit: static PyObject * _imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=f00d01ae30ec842f input=ed689bc05358fdbd]*/ +/*[clinic end generated code: output=4089ec702a9d70c5 input=ed689bc05358fdbd]*/ { return get_frozen_object(name); } @@ -2028,7 +2044,9 @@ Returns True if the module name is of a frozen package. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_frozen_package__doc__, -"sig=($module, name)\n" +"is_frozen_package($module, name, /)\n" +"--\n" +"\n" "Returns True if the module name is of a frozen package."); #define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ @@ -2055,7 +2073,7 @@ exit: static PyObject * _imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=35c78f2448c6fcff input=81b6cdecd080fbb8]*/ +/*[clinic end generated code: output=86aab14dcd4b959b input=81b6cdecd080fbb8]*/ { return is_frozen_package(name); } @@ -2070,7 +2088,9 @@ Returns True if the module name corresponds to a built-in module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_builtin__doc__, -"sig=($module, name)\n" +"is_builtin($module, name, /)\n" +"--\n" +"\n" "Returns True if the module name corresponds to a built-in module."); #define _IMP_IS_BUILTIN_METHODDEF \ @@ -2097,7 +2117,7 @@ exit: static PyObject * _imp_is_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=641689f833347f66 input=86befdac021dd1c7]*/ +/*[clinic end generated code: output=d5847f8cac50946e input=86befdac021dd1c7]*/ { return PyLong_FromLong(is_builtin(name)); } @@ -2112,7 +2132,9 @@ Returns True if the module name corresponds to a frozen module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_is_frozen__doc__, -"sig=($module, name)\n" +"is_frozen($module, name, /)\n" +"--\n" +"\n" "Returns True if the module name corresponds to a frozen module."); #define _IMP_IS_FROZEN_METHODDEF \ @@ -2139,7 +2161,7 @@ exit: static PyObject * _imp_is_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=0f80c7a3f283a686 input=7301dbca1897d66b]*/ +/*[clinic end generated code: output=6691af884ba4987d input=7301dbca1897d66b]*/ { const struct _frozen *p; @@ -2161,7 +2183,9 @@ Loads an extension module. [clinic start generated code]*/ PyDoc_STRVAR(_imp_load_dynamic__doc__, -"sig=($module, name, path, file=None)\n" +"load_dynamic($module, name, path, file=None, /)\n" +"--\n" +"\n" "Loads an extension module."); #define _IMP_LOAD_DYNAMIC_METHODDEF \ @@ -2190,7 +2214,7 @@ exit: static PyObject * _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) -/*[clinic end generated code: output=8f33f48dc6252948 input=af64f06e4bad3526]*/ +/*[clinic end generated code: output=81d11a1fbd1ea0a8 input=af64f06e4bad3526]*/ { PyObject *mod; FILE *fp; -- cgit v1.2.1 From 7b5e2a97fa852cfb435f4d25b49b25cb4aec420c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 10 Feb 2014 18:21:34 +0200 Subject: Issue #19255: The builtins module is restored to initial value before cleaning other modules. The sys and builtins modules are cleaned last. --- Python/import.c | 87 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 34 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index d0115e46bf..207dbced41 100644 --- a/Python/import.c +++ b/Python/import.c @@ -49,9 +49,13 @@ class fs_unicode_converter(CConverter): void _PyImport_Init(void) { + PyInterpreterState *interp = PyThreadState_Get()->interp; initstr = PyUnicode_InternFromString("__init__"); if (initstr == NULL) Py_FatalError("Can't initialize import variables"); + interp->builtins_copy = PyDict_Copy(interp->builtins); + if (interp->builtins_copy == NULL) + Py_FatalError("Can't backup builtins dict"); } void @@ -397,8 +401,10 @@ PyImport_Cleanup(void) PyObject *key, *value, *dict; PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; - PyObject *builtins = interp->builtins; + PyObject *builtins_mod = NULL; + PyObject *sys_mod = NULL; PyObject *weaklist = NULL; + char **p; if (modules == NULL) return; /* Already done */ @@ -411,31 +417,22 @@ PyImport_Cleanup(void) /* XXX Perhaps these precautions are obsolete. Who knows? */ - value = PyDict_GetItemString(modules, "builtins"); - if (value != NULL && PyModule_Check(value)) { - dict = PyModule_GetDict(value); + if (Py_VerboseFlag) + PySys_WriteStderr("# clear builtins._\n"); + PyDict_SetItemString(interp->builtins, "_", Py_None); + + for (p = sys_deletes; *p != NULL; p++) { if (Py_VerboseFlag) - PySys_WriteStderr("# clear builtins._\n"); - PyDict_SetItemString(dict, "_", Py_None); - } - value = PyDict_GetItemString(modules, "sys"); - if (value != NULL && PyModule_Check(value)) { - char **p; - PyObject *v; - dict = PyModule_GetDict(value); - for (p = sys_deletes; *p != NULL; p++) { - if (Py_VerboseFlag) - PySys_WriteStderr("# clear sys.%s\n", *p); - PyDict_SetItemString(dict, *p, Py_None); - } - for (p = sys_files; *p != NULL; p+=2) { - if (Py_VerboseFlag) - PySys_WriteStderr("# restore sys.%s\n", *p); - v = PyDict_GetItemString(dict, *(p+1)); - if (v == NULL) - v = Py_None; - PyDict_SetItemString(dict, *p, v); - } + PySys_WriteStderr("# clear sys.%s\n", *p); + PyDict_SetItemString(interp->sysdict, *p, Py_None); + } + for (p = sys_files; *p != NULL; p+=2) { + if (Py_VerboseFlag) + PySys_WriteStderr("# restore sys.%s\n", *p); + value = PyDict_GetItemString(interp->sysdict, *(p+1)); + if (value == NULL) + value = Py_None; + PyDict_SetItemString(interp->sysdict, *p, value); } /* We prepare a list which will receive (name, weakref) tuples of @@ -473,11 +470,15 @@ PyImport_Cleanup(void) /* Clear the modules dict. */ PyDict_Clear(modules); - /* Replace the interpreter's reference to builtins with an empty dict - (module globals still have a reference to the original builtins). */ - builtins = interp->builtins; - interp->builtins = PyDict_New(); - Py_DECREF(builtins); + /* Restore the original builtins dict, to ensure that any + user data gets cleared. */ + dict = PyDict_Copy(interp->builtins); + if (dict == NULL) + PyErr_Clear(); + PyDict_Clear(interp->builtins); + if (PyDict_Update(interp->builtins, interp->builtins_copy)) + PyErr_Clear(); + Py_XDECREF(dict); /* Clear module dict copies stored in the interpreter state */ _PyState_ClearModules(); /* Collect references */ @@ -488,7 +489,15 @@ PyImport_Cleanup(void) /* Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end - up here, since they are kept alive in the interpreter state. */ + up here, since they are kept alive in the interpreter state. + + The special treatment of "builtins" here is because even + when it's not referenced as a module, its dictionary is + referenced by almost every module's __builtins__. Since + deleting a module clears its dictionary (even if there are + references left to it), we need to delete the "builtins" + module last. Likewise, we don't delete sys until the very + end because it is implicitly referenced (e.g. by print). */ if (weaklist != NULL) { Py_ssize_t i, n; n = PyList_GET_SIZE(weaklist); @@ -498,17 +507,27 @@ PyImport_Cleanup(void) PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); if (mod == Py_None) continue; - Py_INCREF(mod); assert(PyModule_Check(mod)); + dict = PyModule_GetDict(mod); + if (dict == interp->builtins || dict == interp->sysdict) + continue; + Py_INCREF(mod); if (Py_VerboseFlag && PyUnicode_Check(name)) - PySys_FormatStderr("# cleanup[3] wiping %U\n", - name, mod); + PySys_FormatStderr("# cleanup[3] wiping %U\n", name); _PyModule_Clear(mod); Py_DECREF(mod); } Py_DECREF(weaklist); } + /* Next, delete sys and builtins (in that order) */ + if (Py_VerboseFlag) + PySys_FormatStderr("# cleanup[3] wiping sys\n"); + _PyModule_ClearDict(interp->sysdict); + if (Py_VerboseFlag) + PySys_FormatStderr("# cleanup[3] wiping builtins\n"); + _PyModule_ClearDict(interp->builtins); + /* Clear and delete the modules directory. Actual modules will still be there only if imported during the execution of some destructor. */ -- cgit v1.2.1 From c944c6659e1855d07aeecb98f072b9ed082e5e94 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 10 Feb 2014 19:09:19 +0200 Subject: Temporary silence test broken by issue19255. Remove unused variables. --- Python/import.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 207dbced41..7972f8612f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -401,8 +401,6 @@ PyImport_Cleanup(void) PyObject *key, *value, *dict; PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; - PyObject *builtins_mod = NULL; - PyObject *sys_mod = NULL; PyObject *weaklist = NULL; char **p; -- cgit v1.2.1 From 8e6501d00abb8b44f0e84b40c983732f1908c63d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 4 Apr 2014 10:01:46 -0400 Subject: Issue #20942: PyImport_ImportFrozenModuleObject() no longer sets __file__. This causes _frozen_importlib to no longer have __file__ set as well as any frozen module imported using imp.init_frozen() (which is deprecated). --- Python/import.c | 86 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 32 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 7972f8612f..0e26ffcd94 100644 --- a/Python/import.c +++ b/Python/import.c @@ -837,12 +837,10 @@ error: return m; } -PyObject* -PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, - PyObject *cpathname) +static PyObject * +module_dict_for_exec(PyObject *name) { - PyObject *modules = PyImport_GetModuleDict(); - PyObject *m, *d, *v; + PyObject *m, *d = NULL; m = PyImport_AddModuleObject(name); if (m == NULL) @@ -852,9 +850,51 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__builtins__") == NULL) { if (PyDict_SetItemString(d, "__builtins__", - PyEval_GetBuiltins()) != 0) - goto error; + PyEval_GetBuiltins()) != 0) { + remove_module(name); + return NULL; + } + } + + return d; +} + +static PyObject * +exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object) +{ + PyObject *modules = PyImport_GetModuleDict(); + PyObject *v, *m; + + v = PyEval_EvalCode(code_object, module_dict, module_dict); + if (v == NULL) { + remove_module(name); + return NULL; + } + Py_DECREF(v); + + if ((m = PyDict_GetItem(modules, name)) == NULL) { + PyErr_Format(PyExc_ImportError, + "Loaded module %R not found in sys.modules", + name); + return NULL; + } + + Py_INCREF(m); + + return m; +} + +PyObject* +PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, + PyObject *cpathname) +{ + PyObject *d, *v; + + d = module_dict_for_exec(name); + if (d == NULL) { + return NULL; } + if (pathname != NULL) { v = pathname; } @@ -874,25 +914,7 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, if (PyDict_SetItemString(d, "__cached__", v) != 0) PyErr_Clear(); /* Not important enough to report */ - v = PyEval_EvalCode(co, d, d); - if (v == NULL) - goto error; - Py_DECREF(v); - - if ((m = PyDict_GetItem(modules, name)) == NULL) { - PyErr_Format(PyExc_ImportError, - "Loaded module %R not found in sys.modules", - name); - return NULL; - } - - Py_INCREF(m); - - return m; - - error: - remove_module(name); - return NULL; + return exec_code_in_module(name, d, co); } @@ -1206,7 +1228,7 @@ int PyImport_ImportFrozenModuleObject(PyObject *name) { const struct _frozen *p; - PyObject *co, *m, *path; + PyObject *co, *m, *d; int ispackage; int size; @@ -1235,7 +1257,7 @@ PyImport_ImportFrozenModuleObject(PyObject *name) } if (ispackage) { /* Set __path__ to the empty list */ - PyObject *d, *l; + PyObject *l; int err; m = PyImport_AddModuleObject(name); if (m == NULL) @@ -1250,11 +1272,11 @@ PyImport_ImportFrozenModuleObject(PyObject *name) if (err != 0) goto err_return; } - path = PyUnicode_FromString(""); - if (path == NULL) + d = module_dict_for_exec(name); + if (d == NULL) { goto err_return; - m = PyImport_ExecCodeModuleObject(name, co, path, NULL); - Py_DECREF(path); + } + m = exec_code_in_module(name, d, co); if (m == NULL) goto err_return; Py_DECREF(co); -- cgit v1.2.1 From 21d850401b1f4fc3ab40bd327bffd4299178316e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 12 May 2014 17:54:55 -0600 Subject: Issue #21226: Set all attrs in PyImport_ExecCodeModuleObject. --- Python/import.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 0e26ffcd94..4c8f67f499 100644 --- a/Python/import.c +++ b/Python/import.c @@ -856,7 +856,7 @@ module_dict_for_exec(PyObject *name) } } - return d; + return d; /* Return a borrowed reference. */ } static PyObject * @@ -888,33 +888,25 @@ PyObject* PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname) { - PyObject *d, *v; + PyObject *d, *res; + PyInterpreterState *interp = PyThreadState_GET()->interp; + _Py_IDENTIFIER(_fix_up_module); d = module_dict_for_exec(name); if (d == NULL) { return NULL; } - if (pathname != NULL) { - v = pathname; + if (pathname == NULL) { + pathname = ((PyCodeObject *)co)->co_filename; } - else { - v = ((PyCodeObject *)co)->co_filename; + res = _PyObject_CallMethodIdObjArgs(interp->importlib, + &PyId__fix_up_module, + d, name, pathname, cpathname, NULL); + if (res != NULL) { + res = exec_code_in_module(name, d, co); } - Py_INCREF(v); - if (PyDict_SetItemString(d, "__file__", v) != 0) - PyErr_Clear(); /* Not important enough to report */ - Py_DECREF(v); - - /* Remember the pyc path name as the __cached__ attribute. */ - if (cpathname != NULL) - v = cpathname; - else - v = Py_None; - if (PyDict_SetItemString(d, "__cached__", v) != 0) - PyErr_Clear(); /* Not important enough to report */ - - return exec_code_in_module(name, d, co); + return res; } -- cgit v1.2.1 From 8b0aa9261677bcd4b71c6a6fbb527bdc3dedbd48 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 29 May 2014 12:31:39 -0600 Subject: Issue #21226: fix a ref leak. --- Python/import.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 4c8f67f499..80e376483f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -904,6 +904,7 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, &PyId__fix_up_module, d, name, pathname, cpathname, NULL); if (res != NULL) { + Py_DECREF(res); res = exec_code_in_module(name, d, co); } return res; -- cgit v1.2.1 From da98b16411c32678422c4178cc58a17024974ac5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 7 Jul 2014 23:06:15 +0200 Subject: Issue #21925: PyImport_Cleanup(): Remove unused parameter in PySys_FormatStderr() call --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 80e376483f..7ee7ed9bf1 100644 --- a/Python/import.c +++ b/Python/import.c @@ -460,7 +460,7 @@ PyImport_Cleanup(void) while (PyDict_Next(modules, &pos, &key, &value)) { if (PyModule_Check(value)) { if (Py_VerboseFlag && PyUnicode_Check(key)) - PySys_FormatStderr("# cleanup[2] removing %U\n", key, value); + PySys_FormatStderr("# cleanup[2] removing %U\n", key); STORE_MODULE_WEAKREF(key, value); PyDict_SetItem(modules, key, Py_None); } -- cgit v1.2.1