bpo-31415: Improve error handling and caching of the importtime optio… · python/cpython@088929c
@@ -1667,45 +1667,52 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16671667 }
16681668 }
16691669else {
1670-static int ximporttime = 0;
1670+/* 1 -- true, 0 -- false, -1 -- not initialized */
1671+static int ximporttime = -1;
16711672static int import_level;
16721673static _PyTime_t accumulated;
16731674_Py_IDENTIFIER(importtime);
1674167516751676_PyTime_t t1 = 0, accumulated_copy = accumulated;
167616771677-Py_XDECREF(mod);
1678-16791678/* XOptions is initialized after first some imports.
1680- * So we can't have negative cache.
1681- * Anyway, importlib.__find_and_load is much slower than
1682- * _PyDict_GetItemId()
1679+ * So we can't have negative cache before completed initialization.
1680+ * Anyway, importlib._find_and_load is much slower than
1681+ * _PyDict_GetItemIdWithError().
16831682 */
1684-if (ximporttime == 0) {
1685-char *envoption = Py_GETENV("PYTHONPROFILEIMPORTTIME");
1686-if (envoption != NULL && strlen(envoption) > 0) {
1683+if (ximporttime < 0) {
1684+const char *envoption = Py_GETENV("PYTHONPROFILEIMPORTTIME");
1685+if (envoption != NULL && *envoption != '\0') {
16871686ximporttime = 1;
16881687 }
16891688else {
16901689PyObject *xoptions = PySys_GetXOptions();
1690+PyObject *value = NULL;
16911691if (xoptions) {
1692-PyObject *value = _PyDict_GetItemId(
1692+value = _PyDict_GetItemIdWithError(
16931693xoptions, &PyId_importtime);
1694+ }
1695+if (value == NULL && PyErr_Occurred()) {
1696+ goto error;
1697+ }
1698+if (value != NULL || Py_IsInitialized()) {
16941699ximporttime = (value == Py_True);
16951700 }
16961701 }
1697-if (ximporttime) {
1702+if (ximporttime > 0) {
16981703fputs("import time: self [us] | cumulative | imported package\n",
16991704stderr);
17001705 }
17011706 }
170217071703-if (ximporttime) {
1708+if (ximporttime > 0) {
17041709import_level++;
17051710t1 = _PyTime_GetPerfCounter();
17061711accumulated = 0;
17071712 }
170817131714+Py_XDECREF(mod);
1715+17091716if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
17101717PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));
17111718@@ -1717,7 +1724,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
17171724PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
17181725mod != NULL);
171917261720-if (ximporttime) {
1727+if (ximporttime > 0) {
17211728_PyTime_t cum = _PyTime_GetPerfCounter() - t1;
1722172917231730import_level--;