Skip to content

Commit eea3cc1

Browse files
authored
Refactor PyImport_ImportModuleLevelObject(). (#4680)
Add import_find_and_load() helper function. The addition of the importtime option has made PyImport_ImportModuleLevelObject() large and so using a helper seems worthwhile. It also makes it clearer that abs_name is the only argument needed by _find_and_load().
1 parent 078f181 commit eea3cc1

File tree

1 file changed

+57
-50
lines changed

1 file changed

+57
-50
lines changed

Python/import.c

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,12 +1589,67 @@ resolve_name(PyObject *name, PyObject *globals, int level)
15891589
return NULL;
15901590
}
15911591

1592+
static PyObject *
1593+
import_find_and_load(PyObject *abs_name)
1594+
{
1595+
_Py_IDENTIFIER(_find_and_load);
1596+
PyObject *mod = NULL;
1597+
PyInterpreterState *interp = PyThreadState_GET()->interp;
1598+
int import_time = interp->core_config.import_time;
1599+
static int import_level;
1600+
static _PyTime_t accumulated;
1601+
1602+
_PyTime_t t1 = 0, accumulated_copy = accumulated;
1603+
1604+
/* XOptions is initialized after first some imports.
1605+
* So we can't have negative cache before completed initialization.
1606+
* Anyway, importlib._find_and_load is much slower than
1607+
* _PyDict_GetItemIdWithError().
1608+
*/
1609+
if (import_time) {
1610+
static int header = 1;
1611+
if (header) {
1612+
fputs("import time: self [us] | cumulative | imported package\n",
1613+
stderr);
1614+
header = 0;
1615+
}
1616+
1617+
import_level++;
1618+
t1 = _PyTime_GetPerfCounter();
1619+
accumulated = 0;
1620+
}
1621+
1622+
if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
1623+
PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));
1624+
1625+
mod = _PyObject_CallMethodIdObjArgs(interp->importlib,
1626+
&PyId__find_and_load, abs_name,
1627+
interp->import_func, NULL);
1628+
1629+
if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED())
1630+
PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
1631+
mod != NULL);
1632+
1633+
if (import_time) {
1634+
_PyTime_t cum = _PyTime_GetPerfCounter() - t1;
1635+
1636+
import_level--;
1637+
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
1638+
(long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
1639+
(long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
1640+
import_level*2, "", PyUnicode_AsUTF8(abs_name));
1641+
1642+
accumulated = accumulated_copy + cum;
1643+
}
1644+
1645+
return mod;
1646+
}
1647+
15921648
PyObject *
15931649
PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
15941650
PyObject *locals, PyObject *fromlist,
15951651
int level)
15961652
{
1597-
_Py_IDENTIFIER(_find_and_load);
15981653
_Py_IDENTIFIER(_handle_fromlist);
15991654
PyObject *abs_name = NULL;
16001655
PyObject *final_mod = NULL;
@@ -1674,55 +1729,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16741729
}
16751730
}
16761731
else {
1677-
int import_time = interp->core_config.import_time;
1678-
static int import_level;
1679-
static _PyTime_t accumulated;
1680-
1681-
_PyTime_t t1 = 0, accumulated_copy = accumulated;
1682-
1683-
/* XOptions is initialized after first some imports.
1684-
* So we can't have negative cache before completed initialization.
1685-
* Anyway, importlib._find_and_load is much slower than
1686-
* _PyDict_GetItemIdWithError().
1687-
*/
1688-
if (import_time) {
1689-
static int header = 1;
1690-
if (header) {
1691-
fputs("import time: self [us] | cumulative | imported package\n",
1692-
stderr);
1693-
header = 0;
1694-
}
1695-
1696-
import_level++;
1697-
t1 = _PyTime_GetPerfCounter();
1698-
accumulated = 0;
1699-
}
1700-
1701-
Py_XDECREF(mod);
1702-
1703-
if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
1704-
PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));
1705-
1706-
mod = _PyObject_CallMethodIdObjArgs(interp->importlib,
1707-
&PyId__find_and_load, abs_name,
1708-
interp->import_func, NULL);
1709-
1710-
if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED())
1711-
PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
1712-
mod != NULL);
1713-
1714-
if (import_time) {
1715-
_PyTime_t cum = _PyTime_GetPerfCounter() - t1;
1716-
1717-
import_level--;
1718-
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
1719-
(long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
1720-
(long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
1721-
import_level*2, "", PyUnicode_AsUTF8(abs_name));
1722-
1723-
accumulated = accumulated_copy + cum;
1724-
}
1725-
1732+
mod = import_find_and_load(abs_name);
17261733
if (mod == NULL) {
17271734
goto error;
17281735
}

0 commit comments

Comments
 (0)