Merge pull request #8 from LazyImportsCabal/lazy_test

Lazy test
This commit is contained in:
Dino Viehland 2025-10-08 10:13:27 -07:00 committed by GitHub
commit 46b3b75a3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 58 additions and 9 deletions

View file

@ -2558,6 +2558,26 @@ def test_basic_unused(self):
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
def test_basic_unused_use_externally(self):
try:
from test.test_import.data.lazy_imports import basic_unused
except ImportError as e:
self.fail('lazy import failed')
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
x = basic_unused.test.test_import.data.lazy_imports.basic2
self.assertTrue("test.test_import.data.lazy_imports.basic2" in sys.modules)
def test_basic_from_unused_use_externally(self):
try:
from test.test_import.data.lazy_imports import basic_from_unused
except ImportError as e:
self.fail('lazy import failed')
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
x = basic_from_unused.basic2
self.assertTrue("test.test_import.data.lazy_imports.basic2" in sys.modules)
def test_basic_unused_dir(self):
try:
import test.test_import.data.lazy_imports.basic_unused
@ -2758,6 +2778,19 @@ def test_lazy_import_pkg(self):
self.assertTrue("test.test_import.data.lazy_imports.pkg" in sys.modules)
self.assertTrue("test.test_import.data.lazy_imports.pkg.bar" in sys.modules)
def test_lazy_import_pkg_cross_import(self):
try:
import test.test_import.data.lazy_imports.pkg.c
except ImportError as e:
self.fail('lazy import failed')
self.assertTrue("test.test_import.data.lazy_imports.pkg" in sys.modules)
self.assertTrue("test.test_import.data.lazy_imports.pkg.c" in sys.modules)
self.assertFalse("test.test_import.data.lazy_imports.pkg.b" in sys.modules)
g = test.test_import.data.lazy_imports.pkg.c.get_globals()
self.assertEqual(type(g["x"]), int)
self.assertEqual(type(g["b"]), importlib.lazy_import)
class TestSinglePhaseSnapshot(ModuleSnapshot):
"""A representation of a single-phase init module for testing.

View file

@ -0,0 +1 @@
lazy from test.test_import.data.lazy_imports import basic2

View file

@ -0,0 +1,3 @@
def foo():
return 'foo'

View file

@ -0,0 +1,4 @@
lazy from . import b, x
def get_globals():
return globals()

View file

@ -3304,6 +3304,22 @@ _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
assert(name && PyUnicode_Check(name));
PyObject *ret;
PyLazyImportObject *d = (PyLazyImportObject *)v;
PyObject *mod = PyImport_GetModule(d->lz_from);
if (mod != NULL) {
// Check if the module already has the attribute, if so, resolve it eagerly.
if (PyModule_Check(mod)) {
PyObject *mod_dict = PyModule_GetDict(mod);
if (mod_dict != NULL) {
if (PyDict_GetItemRef(mod_dict, name, &ret) < 0) {
return NULL;
} else if (ret != NULL) {
return ret;
}
}
}
Py_DECREF(mod);
}
if (d->lz_attr != NULL) {
if (PyUnicode_Check(d->lz_attr)) {
PyObject *from = PyUnicode_FromFormat("%U.%U", d->lz_from, d->lz_attr);

View file

@ -4221,16 +4221,8 @@ _PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
}
PyInterpreterState *interp = tstate->interp;
_PyInterpreterFrame *frame = _PyEval_GetFrame();
assert(frame->f_globals == frame->f_locals); // should only be called in global scope
PyObject *mod = PyImport_GetModule(abs_name);
bool already_exists = mod != NULL;
Py_XDECREF(mod);
if (mod != NULL) {
return PyImport_ImportModuleLevelObject(name, globals, locals, fromlist, level);
}
// Check if the filter disables the lazy import
PyObject *filter = LAZY_IMPORTS_FILTER(interp);
if (filter != NULL) {
@ -4262,7 +4254,7 @@ _PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
}
PyObject *res = _PyLazyImport_New(import_func, abs_name, fromlist);
if (!already_exists && register_lazy_on_parent(tstate, abs_name, import_func) < 0) {
if (register_lazy_on_parent(tstate, abs_name, import_func) < 0) {
Py_DECREF(res);
res = NULL;
}