mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
Flow import func through to lazy imports object and __lazy_import__
This commit is contained in:
parent
41ab092407
commit
058bc6e884
5 changed files with 64 additions and 33 deletions
|
|
@ -302,6 +302,9 @@ PyAPI_FUNC(PyObject *) _PyEval_LazyImportName(PyThreadState *tstate, PyObject *b
|
||||||
PyAPI_FUNC(PyObject *) _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name);
|
PyAPI_FUNC(PyObject *) _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name);
|
||||||
PyAPI_FUNC(PyObject *) _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals, PyObject *locals,
|
PyAPI_FUNC(PyObject *) _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals, PyObject *locals,
|
||||||
PyObject *name, PyObject *fromlist, PyObject *level);
|
PyObject *name, PyObject *fromlist, PyObject *level);
|
||||||
|
PyObject *
|
||||||
|
_PyEval_ImportNameWithImport(PyThreadState *tstate, PyObject *import_func, PyObject *globals, PyObject *locals,
|
||||||
|
PyObject *name, PyObject *fromlist, PyObject *level);
|
||||||
PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs);
|
PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs);
|
||||||
PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys);
|
PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys);
|
||||||
PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr);
|
PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr);
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ PyAPI_DATA(PyTypeObject) PyLazyImport_Type;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
PyObject *lz_builtins;
|
PyObject *lz_import_func;
|
||||||
PyObject *lz_from;
|
PyObject *lz_from;
|
||||||
PyObject *lz_attr;
|
PyObject *lz_attr;
|
||||||
} PyLazyImportObject;
|
} PyLazyImportObject;
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLazyImport_GetName(PyObject *lazy_import);
|
PyAPI_FUNC(PyObject *) _PyLazyImport_GetName(PyObject *lazy_import);
|
||||||
PyAPI_FUNC(PyObject *) _PyLazyImport_New(PyObject *builtins, PyObject *from, PyObject *attr);
|
PyAPI_FUNC(PyObject *) _PyLazyImport_New(PyObject *import_func, PyObject *from, PyObject *attr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "pycore_lazyimportobject.h"
|
#include "pycore_lazyimportobject.h"
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
_PyLazyImport_New(PyObject *builtins, PyObject *from, PyObject *attr)
|
_PyLazyImport_New(PyObject *import_func, PyObject *from, PyObject *attr)
|
||||||
{
|
{
|
||||||
PyLazyImportObject *m;
|
PyLazyImportObject *m;
|
||||||
if (!from || !PyUnicode_Check(from)) {
|
if (!from || !PyUnicode_Check(from)) {
|
||||||
|
|
@ -19,8 +19,8 @@ _PyLazyImport_New(PyObject *builtins, PyObject *from, PyObject *attr)
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Py_XINCREF(builtins);
|
Py_XINCREF(import_func);
|
||||||
m->lz_builtins = builtins;
|
m->lz_import_func = import_func;
|
||||||
Py_INCREF(from);
|
Py_INCREF(from);
|
||||||
m->lz_from = from;
|
m->lz_from = from;
|
||||||
Py_XINCREF(attr);
|
Py_XINCREF(attr);
|
||||||
|
|
@ -33,7 +33,7 @@ static void
|
||||||
lazy_import_dealloc(PyLazyImportObject *m)
|
lazy_import_dealloc(PyLazyImportObject *m)
|
||||||
{
|
{
|
||||||
PyObject_GC_UnTrack(m);
|
PyObject_GC_UnTrack(m);
|
||||||
Py_XDECREF(m->lz_builtins);
|
Py_XDECREF(m->lz_import_func);
|
||||||
Py_XDECREF(m->lz_from);
|
Py_XDECREF(m->lz_from);
|
||||||
Py_XDECREF(m->lz_attr);
|
Py_XDECREF(m->lz_attr);
|
||||||
Py_TYPE(m)->tp_free((PyObject *)m);
|
Py_TYPE(m)->tp_free((PyObject *)m);
|
||||||
|
|
@ -68,7 +68,7 @@ lazy_import_repr(PyLazyImportObject *m)
|
||||||
static int
|
static int
|
||||||
lazy_import_traverse(PyLazyImportObject *m, visitproc visit, void *arg)
|
lazy_import_traverse(PyLazyImportObject *m, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT(m->lz_builtins);
|
Py_VISIT(m->lz_import_func);
|
||||||
Py_VISIT(m->lz_from);
|
Py_VISIT(m->lz_from);
|
||||||
Py_VISIT(m->lz_attr);
|
Py_VISIT(m->lz_attr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -77,7 +77,7 @@ lazy_import_traverse(PyLazyImportObject *m, visitproc visit, void *arg)
|
||||||
static int
|
static int
|
||||||
lazy_import_clear(PyLazyImportObject *m)
|
lazy_import_clear(PyLazyImportObject *m)
|
||||||
{
|
{
|
||||||
Py_CLEAR(m->lz_builtins);
|
Py_CLEAR(m->lz_import_func);
|
||||||
Py_CLEAR(m->lz_from);
|
Py_CLEAR(m->lz_from);
|
||||||
Py_CLEAR(m->lz_attr);
|
Py_CLEAR(m->lz_attr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -2999,13 +2999,21 @@ _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *res = _PyEval_ImportNameWithImport(tstate, import_func, globals, locals, name, fromlist, level);
|
||||||
|
Py_DECREF(import_func);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_PyEval_ImportNameWithImport(PyThreadState *tstate, PyObject *import_func, PyObject *globals, PyObject *locals,
|
||||||
|
PyObject *name, PyObject *fromlist, PyObject *level)
|
||||||
|
{
|
||||||
if (locals == NULL) {
|
if (locals == NULL) {
|
||||||
locals = Py_None;
|
locals = Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fast path for not overloaded __import__. */
|
/* Fast path for not overloaded __import__. */
|
||||||
if (_PyImport_IsDefaultImportFunc(tstate->interp, import_func)) {
|
if (_PyImport_IsDefaultImportFunc(tstate->interp, import_func)) {
|
||||||
Py_DECREF(import_func);
|
|
||||||
int ilevel = PyLong_AsInt(level);
|
int ilevel = PyLong_AsInt(level);
|
||||||
if (ilevel == -1 && _PyErr_Occurred(tstate)) {
|
if (ilevel == -1 && _PyErr_Occurred(tstate)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -3020,7 +3028,6 @@ _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals,
|
||||||
|
|
||||||
PyObject* args[5] = {name, globals, locals, fromlist, level};
|
PyObject* args[5] = {name, globals, locals, fromlist, level};
|
||||||
PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL);
|
PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL);
|
||||||
Py_DECREF(import_func);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3029,6 +3036,7 @@ PyObject *
|
||||||
_PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals,
|
_PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals,
|
||||||
PyObject *locals, PyObject *name, PyObject *fromlist, PyObject *level, int lazy)
|
PyObject *locals, PyObject *name, PyObject *fromlist, PyObject *level, int lazy)
|
||||||
{
|
{
|
||||||
|
PyObject *res = NULL;
|
||||||
// Check if global policy overrides the local syntax
|
// Check if global policy overrides the local syntax
|
||||||
switch (PyImport_LazyImportsEnabled()) {
|
switch (PyImport_LazyImportsEnabled()) {
|
||||||
case PyLazyImportsMode_ForcedOff:
|
case PyLazyImportsMode_ForcedOff:
|
||||||
|
|
@ -3047,34 +3055,42 @@ _PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *glob
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *import_func;
|
PyObject *import_func;
|
||||||
if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__lazy_import__), &import_func) < 0) {
|
if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__import__), &import_func) < 0) {
|
||||||
return NULL;
|
goto error;
|
||||||
|
} else if (import_func == NULL) {
|
||||||
|
_PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found");
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
if (import_func == NULL) {
|
|
||||||
|
PyObject *lazy_import_func;
|
||||||
|
if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__lazy_import__), &lazy_import_func) < 0) {
|
||||||
|
goto error;
|
||||||
|
} else if (lazy_import_func == NULL) {
|
||||||
_PyErr_SetString(tstate, PyExc_ImportError, "__lazy_import__ not found");
|
_PyErr_SetString(tstate, PyExc_ImportError, "__lazy_import__ not found");
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locals == NULL) {
|
if (locals == NULL) {
|
||||||
locals = Py_None;
|
locals = Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_PyImport_IsDefaultLazyImportFunc(tstate->interp, import_func)) {
|
if (_PyImport_IsDefaultLazyImportFunc(tstate->interp, lazy_import_func)) {
|
||||||
Py_DECREF(import_func);
|
|
||||||
|
|
||||||
int ilevel = PyLong_AsInt(level);
|
int ilevel = PyLong_AsInt(level);
|
||||||
if (ilevel == -1 && PyErr_Occurred()) {
|
if (ilevel == -1 && PyErr_Occurred()) {
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _PyImport_LazyImportModuleLevelObject(
|
res = _PyImport_LazyImportModuleLevelObject(
|
||||||
tstate, name, builtins, globals, locals, fromlist, ilevel
|
tstate, name, import_func, globals, locals, fromlist, ilevel
|
||||||
);
|
);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* args[5] = {name, globals, locals, fromlist, level};
|
PyObject* args[6] = {name, globals, locals, fromlist, level, import_func};
|
||||||
PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL);
|
res = PyObject_Vectorcall(lazy_import_func, args, 6, NULL);
|
||||||
Py_DECREF(import_func);
|
error:
|
||||||
|
Py_XDECREF(lazy_import_func);
|
||||||
|
Py_XDECREF(import_func);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3256,7 +3272,7 @@ _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
|
||||||
if (d->lz_attr != NULL) {
|
if (d->lz_attr != NULL) {
|
||||||
if (PyUnicode_Check(d->lz_attr)) {
|
if (PyUnicode_Check(d->lz_attr)) {
|
||||||
PyObject *from = PyUnicode_FromFormat("%U.%U", d->lz_from, d->lz_attr);
|
PyObject *from = PyUnicode_FromFormat("%U.%U", d->lz_from, d->lz_attr);
|
||||||
ret = _PyLazyImport_New(d->lz_builtins, from, name);
|
ret = _PyLazyImport_New(d->lz_import_func, from, name);
|
||||||
Py_DECREF(from);
|
Py_DECREF(from);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -3264,12 +3280,12 @@ _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
|
||||||
Py_ssize_t dot = PyUnicode_FindChar(d->lz_from, '.', 0, PyUnicode_GET_LENGTH(d->lz_from), 1);
|
Py_ssize_t dot = PyUnicode_FindChar(d->lz_from, '.', 0, PyUnicode_GET_LENGTH(d->lz_from), 1);
|
||||||
if (dot >= 0) {
|
if (dot >= 0) {
|
||||||
PyObject *from = PyUnicode_Substring(d->lz_from, 0, dot);
|
PyObject *from = PyUnicode_Substring(d->lz_from, 0, dot);
|
||||||
ret = _PyLazyImport_New(d->lz_builtins, from, name);
|
ret = _PyLazyImport_New(d->lz_import_func, from, name);
|
||||||
Py_DECREF(from);
|
Py_DECREF(from);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = _PyLazyImport_New(d->lz_builtins, d->lz_from, name);
|
ret = _PyLazyImport_New(d->lz_import_func, d->lz_from, name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3737,8 +3737,8 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
|
||||||
PyObject *globals = PyEval_GetGlobals();
|
PyObject *globals = PyEval_GetGlobals();
|
||||||
|
|
||||||
if (full) {
|
if (full) {
|
||||||
obj = _PyEval_ImportName(tstate,
|
obj = _PyEval_ImportNameWithImport(tstate,
|
||||||
lz->lz_builtins,
|
lz->lz_import_func,
|
||||||
globals,
|
globals,
|
||||||
globals,
|
globals,
|
||||||
lz->lz_from,
|
lz->lz_from,
|
||||||
|
|
@ -3749,8 +3749,8 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
obj = _PyEval_ImportName(tstate,
|
obj = _PyEval_ImportNameWithImport(tstate,
|
||||||
lz->lz_builtins,
|
lz->lz_import_func,
|
||||||
globals,
|
globals,
|
||||||
globals,
|
globals,
|
||||||
name,
|
name,
|
||||||
|
|
@ -3906,8 +3906,20 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
PyErr_SetString(PyExc_RuntimeError, "no current frame");
|
PyErr_SetString(PyExc_RuntimeError, "no current frame");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
final_mod = _PyImport_LazyImportModuleLevelObject(tstate, name, frame->f_builtins, globals,
|
|
||||||
|
PyObject *import_func;
|
||||||
|
if (PyMapping_GetOptionalItem(frame->f_builtins, &_Py_ID(__import__), &import_func) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (import_func == NULL) {
|
||||||
|
_PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
final_mod = _PyImport_LazyImportModuleLevelObject(tstate, name, import_func, globals,
|
||||||
locals, fromlist, level);
|
locals, fromlist, level);
|
||||||
|
Py_DECREF(import_func);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4016,7 +4028,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
_PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
|
_PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
|
||||||
PyObject *name, PyObject *builtins,
|
PyObject *name, PyObject *import_func,
|
||||||
PyObject *globals, PyObject *locals,
|
PyObject *globals, PyObject *locals,
|
||||||
PyObject *fromlist, int level)
|
PyObject *fromlist, int level)
|
||||||
{
|
{
|
||||||
|
|
@ -4063,7 +4075,7 @@ _PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *res = _PyLazyImport_New(builtins, abs_name, fromlist);
|
PyObject *res = _PyLazyImport_New(import_func, abs_name, fromlist);
|
||||||
Py_DECREF(abs_name);
|
Py_DECREF(abs_name);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue