diff options
author | Victor Stinner <vstinner@python.org> | 2021-01-25 12:24:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-25 12:24:42 (GMT) |
commit | db584bdad32d81e42b71871077a8008036f5c048 (patch) | |
tree | ef018339067b08456b55a083547f9427b817f1b3 /Python/pylifecycle.c | |
parent | 879986d8a932c4524cb6ff822afc9537de16e28d (diff) | |
download | cpython-db584bdad32d81e42b71871077a8008036f5c048.zip cpython-db584bdad32d81e42b71871077a8008036f5c048.tar.gz cpython-db584bdad32d81e42b71871077a8008036f5c048.tar.bz2 |
bpo-42955: Add sys.modules_names (GH-24238)
Add sys.module_names, containing the list of the standard library
module names.
Diffstat (limited to 'Python/pylifecycle.c')
-rw-r--r-- | Python/pylifecycle.c | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index e9df8fb..a97f45d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -18,8 +18,6 @@ #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() -#include "module_names.h" // _Py_module_names - #include <locale.h> // setlocale() #ifdef HAVE_SIGNAL_H @@ -2499,7 +2497,7 @@ fatal_error_exit(int status) // Dump the list of extension modules of sys.modules, excluding stdlib modules -// (_Py_module_names), into fd file descriptor. +// (sys.module_names), into fd file descriptor. // // This function is called by a signal handler in faulthandler: avoid memory // allocations and keep the implementation simple. For example, the list is not @@ -2515,10 +2513,31 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) return; } + Py_ssize_t pos; + PyObject *key, *value; + + // Avoid PyDict_GetItemString() which calls PyUnicode_FromString(), + // memory cannot be allocated on the heap in a signal handler. + // Iterate on the dict instead. + PyObject *module_names = NULL; + pos = 0; + while (PyDict_Next(interp->sysdict, &pos, &key, &value)) { + if (PyUnicode_Check(key) + && PyUnicode_CompareWithASCIIString(key, "module_names") == 0) { + module_names = value; + break; + } + } + // If we failed to get sys.module_names or it's not a frozenset, + // don't exclude stdlib modules. + if (module_names != NULL && !PyFrozenSet_Check(module_names)) { + module_names = NULL; + } + + // List extensions int header = 1; Py_ssize_t count = 0; - Py_ssize_t pos = 0; - PyObject *key, *value; + pos = 0; while (PyDict_Next(modules, &pos, &key, &value)) { if (!PyUnicode_Check(key)) { continue; @@ -2526,22 +2545,26 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) if (!_PyModule_IsExtension(value)) { continue; } - - // Check if it is a stdlib extension module. // Use the module name from the sys.modules key, // don't attempt to get the module object name. - const Py_ssize_t names_len = Py_ARRAY_LENGTH(_Py_module_names); - int is_stdlib_mod = 0; - for (Py_ssize_t i=0; i < names_len; i++) { - const char *name = _Py_module_names[i]; - if (PyUnicode_CompareWithASCIIString(key, name) == 0) { - is_stdlib_mod = 1; - break; + if (module_names != NULL) { + int is_stdlib_ext = 0; + + Py_ssize_t i; + PyObject *item; + Py_hash_t hash; + for (i=0; _PySet_NextEntry(module_names, &i, &item, &hash); ) { + if (PyUnicode_Check(item) + && PyUnicode_Compare(key, item) == 0) + { + is_stdlib_ext = 1; + break; + } + } + if (is_stdlib_ext) { + // Ignore stdlib extension + continue; } - } - if (is_stdlib_mod) { - // Ignore stdlib extension module. - continue; } if (header) { |