summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-11-12 14:14:13 (GMT)
committerGitHub <noreply@github.com>2020-11-12 14:14:13 (GMT)
commitef75a625cdf8377d687a04948b4db9bc1917bf19 (patch)
treef9a979741790c9647b53e3f7c8f2c5fd66b6e56a /Python
parentd19fa7a337d829e3dab3e9f919f5dcf09cf6f6ba (diff)
downloadcpython-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.c30
-rw-r--r--Python/import.c37
-rw-r--r--Python/pylifecycle.c120
-rw-r--r--Python/sysmodule.c5
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;
}