diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/frozen.c | 19 | ||||
-rw-r--r-- | Python/import.c | 159 |
2 files changed, 125 insertions, 53 deletions
diff --git a/Python/frozen.c b/Python/frozen.c index 499b3b99570..15baa97b9d0 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -63,14 +63,15 @@ /* Note that a negative size indicates a package. */ -static const struct _frozen _PyImport_FrozenModules[] = { - /* import system */ +static const struct _frozen bootstrap_modules[] = { {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap)}, {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external)}, {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport)}, - + {0, 0, 0} /* bootstrap sentinel */ +}; +static const struct _frozen stdlib_modules[] = { /* stdlib - startup, without site (python -S) */ {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc)}, {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs)}, @@ -87,8 +88,9 @@ static const struct _frozen _PyImport_FrozenModules[] = { {"os", _Py_M__os, (int)sizeof(_Py_M__os)}, {"site", _Py_M__site, (int)sizeof(_Py_M__site)}, {"stat", _Py_M__stat, (int)sizeof(_Py_M__stat)}, - - /* Test module */ + {0, 0, 0} /* stdlib sentinel */ +}; +static const struct _frozen test_modules[] = { {"__hello__", _Py_M____hello__, (int)sizeof(_Py_M____hello__)}, {"__hello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__)}, {"__phello_alias__", _Py_M____hello__, -(int)sizeof(_Py_M____hello__)}, @@ -103,8 +105,11 @@ static const struct _frozen _PyImport_FrozenModules[] = { {"__phello__.spam", _Py_M____phello___spam, (int)sizeof(_Py_M____phello___spam)}, {"__hello_only__", _Py_M__frozen_only, (int)sizeof(_Py_M__frozen_only)}, - {0, 0, 0} /* modules sentinel */ + {0, 0, 0} /* test sentinel */ }; +const struct _frozen *_PyImport_FrozenBootstrap = bootstrap_modules; +const struct _frozen *_PyImport_FrozenStdlib = stdlib_modules; +const struct _frozen *_PyImport_FrozenTest = test_modules; static const struct _module_alias aliases[] = { {"_frozen_importlib", "importlib._bootstrap"}, @@ -124,4 +129,4 @@ const struct _module_alias *_PyImport_FrozenAliases = aliases; /* Embedding apps may change this pointer to point to their favorite collection of frozen modules: */ -const struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules; +const struct _frozen *PyImport_FrozenModules = NULL; diff --git a/Python/import.c b/Python/import.c index 15b1956c102..48ea9129163 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1071,27 +1071,6 @@ resolve_module_alias(const char *name, const struct _module_alias *aliases, /* Frozen modules */ static bool -is_essential_frozen_module(const char *name) -{ - /* These modules are necessary to bootstrap the import system. */ - if (strcmp(name, "_frozen_importlib") == 0) { - return true; - } - if (strcmp(name, "_frozen_importlib_external") == 0) { - return true; - } - if (strcmp(name, "zipimport") == 0) { - return true; - } - /* This doesn't otherwise have anywhere to find the module. - See frozenmain.c. */ - if (strcmp(name, "__main__") == 0) { - return true; - } - return false; -} - -static bool use_frozen(void) { PyInterpreterState *interp = _PyInterpreterState_GET(); @@ -1115,26 +1094,76 @@ list_frozen_module_names() return NULL; } bool enabled = use_frozen(); - for (const struct _frozen *p = PyImport_FrozenModules; ; p++) { + const struct _frozen *p; +#define ADD_MODULE(name) \ + do { \ + PyObject *nameobj = PyUnicode_FromString(name); \ + if (nameobj == NULL) { \ + goto error; \ + } \ + int res = PyList_Append(names, nameobj); \ + Py_DECREF(nameobj); \ + if (res != 0) { \ + goto error; \ + } \ + } while(0) + // We always use the bootstrap modules. + for (p = _PyImport_FrozenBootstrap; ; p++) { if (p->name == NULL) { break; } - if (!enabled && !is_essential_frozen_module(p->name)) { - continue; + ADD_MODULE(p->name); + } + // Frozen stdlib modules may be disabled. + for (p = _PyImport_FrozenStdlib; ; p++) { + if (p->name == NULL) { + break; } - PyObject *name = PyUnicode_FromString(p->name); - if (name == NULL) { - Py_DECREF(names); - return NULL; + if (enabled) { + ADD_MODULE(p->name); } - int res = PyList_Append(names, name); - Py_DECREF(name); - if (res != 0) { - Py_DECREF(names); - return NULL; + } + for (p = _PyImport_FrozenTest; ; p++) { + if (p->name == NULL) { + break; + } + if (enabled) { + ADD_MODULE(p->name); + } + } +#undef ADD_MODULE + // Add any custom modules. + if (PyImport_FrozenModules != NULL) { + for (p = PyImport_FrozenModules; ; p++) { + if (p->name == NULL) { + break; + } + PyObject *nameobj = PyUnicode_FromString(p->name); + if (nameobj == NULL) { + goto error; + } + int found = PySequence_Contains(names, nameobj); + if (found < 0) { + Py_DECREF(nameobj); + goto error; + } + else if (found) { + Py_DECREF(nameobj); + } + else { + int res = PyList_Append(names, nameobj); + Py_DECREF(nameobj); + if (res != 0) { + goto error; + } + } } } return names; + +error: + Py_DECREF(names); + return NULL; } typedef enum { @@ -1180,6 +1209,54 @@ set_frozen_error(frozen_status status, PyObject *modname) } } +static const struct _frozen * +look_up_frozen(const char *name) +{ + const struct _frozen *p; + // We always use the bootstrap modules. + for (p = _PyImport_FrozenBootstrap; ; p++) { + if (p->name == NULL) { + // We hit the end-of-list sentinel value. + break; + } + if (strcmp(name, p->name) == 0) { + return p; + } + } + // Prefer custom modules, if any. Frozen stdlib modules can be + // disabled here by setting "code" to NULL in the array entry. + if (PyImport_FrozenModules != NULL) { + for (p = PyImport_FrozenModules; ; p++) { + if (p->name == NULL) { + break; + } + if (strcmp(name, p->name) == 0) { + return p; + } + } + } + // Frozen stdlib modules may be disabled. + if (use_frozen()) { + for (p = _PyImport_FrozenStdlib; ; p++) { + if (p->name == NULL) { + break; + } + if (strcmp(name, p->name) == 0) { + return p; + } + } + for (p = _PyImport_FrozenTest; ; p++) { + if (p->name == NULL) { + break; + } + if (strcmp(name, p->name) == 0) { + return p; + } + } + } + return NULL; +} + struct frozen_info { PyObject *nameobj; const char *data; @@ -1209,19 +1286,9 @@ find_frozen(PyObject *nameobj, struct frozen_info *info) return FROZEN_BAD_NAME; } - if (!use_frozen() && !is_essential_frozen_module(name)) { - return FROZEN_DISABLED; - } - - const struct _frozen *p; - for (p = PyImport_FrozenModules; ; p++) { - if (p->name == NULL) { - // We hit the end-of-list sentinel value. - return FROZEN_NOT_FOUND; - } - if (strcmp(name, p->name) == 0) { - break; - } + const struct _frozen *p = look_up_frozen(name); + if (p == NULL) { + return FROZEN_NOT_FOUND; } if (info != NULL) { info->nameobj = nameobj; // borrowed |