Skip to content

Commit 058bc6e

Browse files
committed
Flow import func through to lazy imports object and __lazy_import__
1 parent 41ab092 commit 058bc6e

File tree

5 files changed

+64
-33
lines changed

5 files changed

+64
-33
lines changed

Include/internal/pycore_ceval.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ PyAPI_FUNC(PyObject *) _PyEval_LazyImportName(PyThreadState *tstate, PyObject *b
302302
PyAPI_FUNC(PyObject *) _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name);
303303
PyAPI_FUNC(PyObject *) _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals, PyObject *locals,
304304
PyObject *name, PyObject *fromlist, PyObject *level);
305+
PyObject *
306+
_PyEval_ImportNameWithImport(PyThreadState *tstate, PyObject *import_func, PyObject *globals, PyObject *locals,
307+
PyObject *name, PyObject *fromlist, PyObject *level);
305308
PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs);
306309
PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys);
307310
PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr);

Include/internal/pycore_lazyimportobject.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ PyAPI_DATA(PyTypeObject) PyLazyImport_Type;
1414

1515
typedef struct {
1616
PyObject_HEAD
17-
PyObject *lz_builtins;
17+
PyObject *lz_import_func;
1818
PyObject *lz_from;
1919
PyObject *lz_attr;
2020
} PyLazyImportObject;
2121

2222

2323
PyAPI_FUNC(PyObject *) _PyLazyImport_GetName(PyObject *lazy_import);
24-
PyAPI_FUNC(PyObject *) _PyLazyImport_New(PyObject *builtins, PyObject *from, PyObject *attr);
24+
PyAPI_FUNC(PyObject *) _PyLazyImport_New(PyObject *import_func, PyObject *from, PyObject *attr);
2525

2626
#ifdef __cplusplus
2727
}

Objects/lazyimportobject.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "pycore_lazyimportobject.h"
55

66
PyObject *
7-
_PyLazyImport_New(PyObject *builtins, PyObject *from, PyObject *attr)
7+
_PyLazyImport_New(PyObject *import_func, PyObject *from, PyObject *attr)
88
{
99
PyLazyImportObject *m;
1010
if (!from || !PyUnicode_Check(from)) {
@@ -19,8 +19,8 @@ _PyLazyImport_New(PyObject *builtins, PyObject *from, PyObject *attr)
1919
if (m == NULL) {
2020
return NULL;
2121
}
22-
Py_XINCREF(builtins);
23-
m->lz_builtins = builtins;
22+
Py_XINCREF(import_func);
23+
m->lz_import_func = import_func;
2424
Py_INCREF(from);
2525
m->lz_from = from;
2626
Py_XINCREF(attr);
@@ -33,7 +33,7 @@ static void
3333
lazy_import_dealloc(PyLazyImportObject *m)
3434
{
3535
PyObject_GC_UnTrack(m);
36-
Py_XDECREF(m->lz_builtins);
36+
Py_XDECREF(m->lz_import_func);
3737
Py_XDECREF(m->lz_from);
3838
Py_XDECREF(m->lz_attr);
3939
Py_TYPE(m)->tp_free((PyObject *)m);
@@ -68,7 +68,7 @@ lazy_import_repr(PyLazyImportObject *m)
6868
static int
6969
lazy_import_traverse(PyLazyImportObject *m, visitproc visit, void *arg)
7070
{
71-
Py_VISIT(m->lz_builtins);
71+
Py_VISIT(m->lz_import_func);
7272
Py_VISIT(m->lz_from);
7373
Py_VISIT(m->lz_attr);
7474
return 0;
@@ -77,7 +77,7 @@ lazy_import_traverse(PyLazyImportObject *m, visitproc visit, void *arg)
7777
static int
7878
lazy_import_clear(PyLazyImportObject *m)
7979
{
80-
Py_CLEAR(m->lz_builtins);
80+
Py_CLEAR(m->lz_import_func);
8181
Py_CLEAR(m->lz_from);
8282
Py_CLEAR(m->lz_attr);
8383
return 0;

Python/ceval.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,13 +2999,21 @@ _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals,
29992999
return NULL;
30003000
}
30013001

3002+
PyObject *res = _PyEval_ImportNameWithImport(tstate, import_func, globals, locals, name, fromlist, level);
3003+
Py_DECREF(import_func);
3004+
return res;
3005+
}
3006+
3007+
PyObject *
3008+
_PyEval_ImportNameWithImport(PyThreadState *tstate, PyObject *import_func, PyObject *globals, PyObject *locals,
3009+
PyObject *name, PyObject *fromlist, PyObject *level)
3010+
{
30023011
if (locals == NULL) {
30033012
locals = Py_None;
30043013
}
30053014

30063015
/* Fast path for not overloaded __import__. */
30073016
if (_PyImport_IsDefaultImportFunc(tstate->interp, import_func)) {
3008-
Py_DECREF(import_func);
30093017
int ilevel = PyLong_AsInt(level);
30103018
if (ilevel == -1 && _PyErr_Occurred(tstate)) {
30113019
return NULL;
@@ -3020,7 +3028,6 @@ _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals,
30203028

30213029
PyObject* args[5] = {name, globals, locals, fromlist, level};
30223030
PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL);
3023-
Py_DECREF(import_func);
30243031
return res;
30253032
}
30263033

@@ -3029,6 +3036,7 @@ PyObject *
30293036
_PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals,
30303037
PyObject *locals, PyObject *name, PyObject *fromlist, PyObject *level, int lazy)
30313038
{
3039+
PyObject *res = NULL;
30323040
// Check if global policy overrides the local syntax
30333041
switch (PyImport_LazyImportsEnabled()) {
30343042
case PyLazyImportsMode_ForcedOff:
@@ -3047,34 +3055,42 @@ _PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *glob
30473055
}
30483056

30493057
PyObject *import_func;
3050-
if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__lazy_import__), &import_func) < 0) {
3051-
return NULL;
3058+
if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__import__), &import_func) < 0) {
3059+
goto error;
3060+
} else if (import_func == NULL) {
3061+
_PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found");
3062+
goto error;
30523063
}
3053-
if (import_func == NULL) {
3064+
3065+
PyObject *lazy_import_func;
3066+
if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__lazy_import__), &lazy_import_func) < 0) {
3067+
goto error;
3068+
} else if (lazy_import_func == NULL) {
30543069
_PyErr_SetString(tstate, PyExc_ImportError, "__lazy_import__ not found");
3055-
return NULL;
3070+
goto error;
30563071
}
30573072

30583073
if (locals == NULL) {
30593074
locals = Py_None;
30603075
}
30613076

3062-
if (_PyImport_IsDefaultLazyImportFunc(tstate->interp, import_func)) {
3063-
Py_DECREF(import_func);
3064-
3077+
if (_PyImport_IsDefaultLazyImportFunc(tstate->interp, lazy_import_func)) {
30653078
int ilevel = PyLong_AsInt(level);
30663079
if (ilevel == -1 && PyErr_Occurred()) {
3067-
return NULL;
3080+
goto error;
30683081
}
30693082

3070-
return _PyImport_LazyImportModuleLevelObject(
3071-
tstate, name, builtins, globals, locals, fromlist, ilevel
3083+
res = _PyImport_LazyImportModuleLevelObject(
3084+
tstate, name, import_func, globals, locals, fromlist, ilevel
30723085
);
3086+
goto error;
30733087
}
30743088

3075-
PyObject* args[5] = {name, globals, locals, fromlist, level};
3076-
PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL);
3077-
Py_DECREF(import_func);
3089+
PyObject* args[6] = {name, globals, locals, fromlist, level, import_func};
3090+
res = PyObject_Vectorcall(lazy_import_func, args, 6, NULL);
3091+
error:
3092+
Py_XDECREF(lazy_import_func);
3093+
Py_XDECREF(import_func);
30783094
return res;
30793095
}
30803096

@@ -3256,20 +3272,20 @@ _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
32563272
if (d->lz_attr != NULL) {
32573273
if (PyUnicode_Check(d->lz_attr)) {
32583274
PyObject *from = PyUnicode_FromFormat("%U.%U", d->lz_from, d->lz_attr);
3259-
ret = _PyLazyImport_New(d->lz_builtins, from, name);
3275+
ret = _PyLazyImport_New(d->lz_import_func, from, name);
32603276
Py_DECREF(from);
32613277
return ret;
32623278
}
32633279
} else {
32643280
Py_ssize_t dot = PyUnicode_FindChar(d->lz_from, '.', 0, PyUnicode_GET_LENGTH(d->lz_from), 1);
32653281
if (dot >= 0) {
32663282
PyObject *from = PyUnicode_Substring(d->lz_from, 0, dot);
3267-
ret = _PyLazyImport_New(d->lz_builtins, from, name);
3283+
ret = _PyLazyImport_New(d->lz_import_func, from, name);
32683284
Py_DECREF(from);
32693285
return ret;
32703286
}
32713287
}
3272-
ret = _PyLazyImport_New(d->lz_builtins, d->lz_from, name);
3288+
ret = _PyLazyImport_New(d->lz_import_func, d->lz_from, name);
32733289
return ret;
32743290
}
32753291

Python/import.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3737,8 +3737,8 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
37373737
PyObject *globals = PyEval_GetGlobals();
37383738

37393739
if (full) {
3740-
obj = _PyEval_ImportName(tstate,
3741-
lz->lz_builtins,
3740+
obj = _PyEval_ImportNameWithImport(tstate,
3741+
lz->lz_import_func,
37423742
globals,
37433743
globals,
37443744
lz->lz_from,
@@ -3749,8 +3749,8 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
37493749
if (name == NULL) {
37503750
goto error;
37513751
}
3752-
obj = _PyEval_ImportName(tstate,
3753-
lz->lz_builtins,
3752+
obj = _PyEval_ImportNameWithImport(tstate,
3753+
lz->lz_import_func,
37543754
globals,
37553755
globals,
37563756
name,
@@ -3906,8 +3906,20 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
39063906
PyErr_SetString(PyExc_RuntimeError, "no current frame");
39073907
goto error;
39083908
}
3909-
final_mod = _PyImport_LazyImportModuleLevelObject(tstate, name, frame->f_builtins, globals,
3909+
3910+
PyObject *import_func;
3911+
if (PyMapping_GetOptionalItem(frame->f_builtins, &_Py_ID(__import__), &import_func) < 0) {
3912+
return NULL;
3913+
}
3914+
3915+
if (import_func == NULL) {
3916+
_PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found");
3917+
return NULL;
3918+
}
3919+
3920+
final_mod = _PyImport_LazyImportModuleLevelObject(tstate, name, import_func, globals,
39103921
locals, fromlist, level);
3922+
Py_DECREF(import_func);
39113923
goto error;
39123924
}
39133925
}
@@ -4016,7 +4028,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
40164028

40174029
PyObject *
40184030
_PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
4019-
PyObject *name, PyObject *builtins,
4031+
PyObject *name, PyObject *import_func,
40204032
PyObject *globals, PyObject *locals,
40214033
PyObject *fromlist, int level)
40224034
{
@@ -4063,7 +4075,7 @@ _PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
40634075
}
40644076
}
40654077

4066-
PyObject *res = _PyLazyImport_New(builtins, abs_name, fromlist);
4078+
PyObject *res = _PyLazyImport_New(import_func, abs_name, fromlist);
40674079
Py_DECREF(abs_name);
40684080
return res;
40694081
}

0 commit comments

Comments
 (0)