diff options
author | Victor Stinner <vstinner@python.org> | 2020-11-12 14:14:13 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-12 14:14:13 (GMT) |
commit | ef75a625cdf8377d687a04948b4db9bc1917bf19 (patch) | |
tree | f9a979741790c9647b53e3f7c8f2c5fd66b6e56a /Python | |
parent | d19fa7a337d829e3dab3e9f919f5dcf09cf6f6ba (diff) | |
download | cpython-ef75a625cdf8377d687a04948b4db9bc1917bf19.zip cpython-ef75a625cdf8377d687a04948b4db9bc1917bf19.tar.gz cpython-ef75a625cdf8377d687a04948b4db9bc1917bf19.tar.bz2 |
bpo-42260: Initialize time and warnings earlier at startup (GH-23249)
* Call _PyTime_Init() and _PyWarnings_InitState() earlier during the
Python initialization.
* Inline _PyImportHooks_Init() into _PySys_InitCore().
* The _warnings initialization function no longer call
_PyWarnings_InitState() to prevent resetting filters_version to 0.
* _PyWarnings_InitState() now returns an int and no longer clear the
state in case of error (it's done anyway at Python exit).
* Rework init_importlib(), fix refleaks on errors.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/_warnings.c | 30 | ||||
-rw-r--r-- | Python/import.c | 37 | ||||
-rw-r--r-- | Python/pylifecycle.c | 120 | ||||
-rw-r--r-- | Python/sysmodule.c | 5 |
4 files changed, 62 insertions, 130 deletions
diff --git a/Python/_warnings.c b/Python/_warnings.c index e42b7c3..8d33fbe 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -114,37 +114,34 @@ init_filters(void) } /* Initialize the given warnings module state. */ -static int -warnings_init_state(WarningsState *st) +int +_PyWarnings_InitState(PyThreadState *tstate) { + WarningsState *st = &tstate->interp->warnings; + if (st->filters == NULL) { st->filters = init_filters(); if (st->filters == NULL) { - goto error; + return -1; } } if (st->once_registry == NULL) { st->once_registry = PyDict_New(); if (st->once_registry == NULL) { - goto error; + return -1; } } if (st->default_action == NULL) { st->default_action = PyUnicode_FromString("default"); if (st->default_action == NULL) { - goto error; + return -1; } } st->filters_version = 0; - return 0; - -error: - warnings_clear_state(st); - return -1; } @@ -1367,16 +1364,6 @@ static struct PyModuleDef warningsmodule = { }; -PyStatus -_PyWarnings_InitState(PyThreadState *tstate) -{ - if (warnings_init_state(&tstate->interp->warnings) < 0) { - return _PyStatus_ERR("can't initialize warnings"); - } - return _PyStatus_OK(); -} - - PyMODINIT_FUNC _PyWarnings_Init(void) { @@ -1391,9 +1378,6 @@ _PyWarnings_Init(void) if (st == NULL) { goto error; } - if (warnings_init_state(st) < 0) { - goto error; - } if (PyModule_AddObjectRef(m, "filters", st->filters) < 0) { goto error; diff --git a/Python/import.c b/Python/import.c index 77e6bae..51630c3 100644 --- a/Python/import.c +++ b/Python/import.c @@ -52,43 +52,6 @@ module _imp /* Initialize things */ PyStatus -_PyImportHooks_Init(PyThreadState *tstate) -{ - PyObject *v, *path_hooks = NULL; - int err = 0; - - /* adding sys.path_hooks and sys.path_importer_cache */ - v = PyList_New(0); - if (v == NULL) - goto error; - err = PySys_SetObject("meta_path", v); - Py_DECREF(v); - if (err) - goto error; - v = PyDict_New(); - if (v == NULL) - goto error; - err = PySys_SetObject("path_importer_cache", v); - Py_DECREF(v); - if (err) - goto error; - path_hooks = PyList_New(0); - if (path_hooks == NULL) - goto error; - err = PySys_SetObject("path_hooks", path_hooks); - if (err) { - goto error; - } - Py_DECREF(path_hooks); - return _PyStatus_OK(); - - error: - _PyErr_Print(tstate); - return _PyStatus_ERR("initializing sys.meta_path, sys.path_hooks, " - "or path_importer_cache failed"); -} - -PyStatus _PyImportZip_Init(PyThreadState *tstate) { PyObject *path_hooks, *zipimport; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 93bce49..2d43e01 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -135,59 +135,61 @@ Py_IsInitialized(void) having the lock, but you cannot use multiple threads.) */ - -static PyStatus +static int init_importlib(PyThreadState *tstate, PyObject *sysmod) { - PyObject *importlib; - PyObject *impmod; - PyObject *value; + assert(!_PyErr_Occurred(tstate)); + PyInterpreterState *interp = tstate->interp; int verbose = _PyInterpreterState_GetConfig(interp)->verbose; - /* Import _importlib through its frozen version, _frozen_importlib. */ - if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { - return _PyStatus_ERR("can't import _frozen_importlib"); - } - else if (verbose) { + // Import _importlib through its frozen version, _frozen_importlib. + if (verbose) { PySys_FormatStderr("import _frozen_importlib # frozen\n"); } - importlib = PyImport_AddModule("_frozen_importlib"); + if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { + return -1; + } + PyObject *importlib = PyImport_AddModule("_frozen_importlib"); // borrowed if (importlib == NULL) { - return _PyStatus_ERR("couldn't get _frozen_importlib from sys.modules"); + return -1; } - interp->importlib = importlib; - Py_INCREF(interp->importlib); - - interp->import_func = _PyDict_GetItemStringWithError(interp->builtins, "__import__"); - if (interp->import_func == NULL) - return _PyStatus_ERR("__import__ not found"); - Py_INCREF(interp->import_func); + interp->importlib = Py_NewRef(importlib); - /* Import the _imp module */ - impmod = PyInit__imp(); - if (impmod == NULL) { - return _PyStatus_ERR("can't import _imp"); + PyObject *import_func = _PyDict_GetItemStringWithError(interp->builtins, + "__import__"); + if (import_func == NULL) { + return -1; } - else if (verbose) { + interp->import_func = Py_NewRef(import_func); + + // Import the _imp module + if (verbose) { PySys_FormatStderr("import _imp # builtin\n"); } - if (_PyImport_SetModuleString("_imp", impmod) < 0) { - return _PyStatus_ERR("can't save _imp to sys.modules"); + PyObject *imp_mod = PyInit__imp(); + if (imp_mod == NULL) { + return -1; + } + if (_PyImport_SetModuleString("_imp", imp_mod) < 0) { + Py_DECREF(imp_mod); + return -1; } - /* Install importlib as the implementation of import */ - value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); + // Install importlib as the implementation of import + PyObject *value = PyObject_CallMethod(importlib, "_install", + "OO", sysmod, imp_mod); + Py_DECREF(imp_mod); if (value == NULL) { - _PyErr_Print(tstate); - return _PyStatus_ERR("importlib install failed"); + return -1; } Py_DECREF(value); - Py_DECREF(impmod); - return _PyStatus_OK(); + assert(!_PyErr_Occurred(tstate)); + return 0; } + static PyStatus init_importlib_external(PyThreadState *tstate) { @@ -700,6 +702,9 @@ pycore_init_types(PyThreadState *tstate) } } + if (_PyWarnings_InitState(tstate) < 0) { + return _PyStatus_ERR("can't initialize warnings"); + } return _PyStatus_OK(); } @@ -748,37 +753,6 @@ error: static PyStatus -pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) -{ - assert(!_PyErr_Occurred(tstate)); - - PyStatus status = _PyImportHooks_Init(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* Initialize _warnings. */ - status = _PyWarnings_InitState(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); - if (config->_install_importlib) { - /* This call sets up builtin and frozen import support */ - status = init_importlib(tstate, sysmod); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - assert(!_PyErr_Occurred(tstate)); - - return _PyStatus_OK(); -} - - -static PyStatus pycore_interp_init(PyThreadState *tstate) { PyStatus status; @@ -789,6 +763,12 @@ pycore_interp_init(PyThreadState *tstate) goto done; } + if (_Py_IsMainInterpreter(tstate)) { + if (_PyTime_Init() < 0) { + return _PyStatus_ERR("can't initialize time"); + } + } + status = _PySys_Create(tstate, &sysmod); if (_PyStatus_EXCEPTION(status)) { goto done; @@ -799,7 +779,13 @@ pycore_interp_init(PyThreadState *tstate) goto done; } - status = pycore_init_import_warnings(tstate, sysmod); + const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); + if (config->_install_importlib) { + /* This call sets up builtin and frozen import support */ + if (init_importlib(tstate, sysmod) < 0) { + return _PyStatus_ERR("failed to initialize importlib"); + } + } done: /* sys.modules['sys'] contains a strong reference to the module */ @@ -1044,12 +1030,6 @@ init_interp_main(PyThreadState *tstate) return status; } - if (is_main_interp) { - if (_PyTime_Init() < 0) { - return _PyStatus_ERR("can't initialize time"); - } - } - if (interpreter_update_config(tstate, 1) < 0) { return _PyStatus_ERR("failed to update the Python config"); } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 61741f7..f05b33a 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2841,6 +2841,11 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) } } + /* adding sys.path_hooks and sys.path_importer_cache */ + SET_SYS("meta_path", PyList_New(0)); + SET_SYS("path_importer_cache", PyDict_New()); + SET_SYS("path_hooks", PyList_New(0)); + if (_PyErr_Occurred(tstate)) { goto err_occurred; } |