mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
Add compatiblity mode
This commit is contained in:
parent
de281fd894
commit
41ab092407
8 changed files with 53 additions and 7 deletions
|
|
@ -1433,6 +1433,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__itruediv__));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__itruediv__));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ixor__));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ixor__));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lazy_import__));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lazy_import__));
|
||||||
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lazy_modules__));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__le__));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__le__));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__len__));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__len__));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__length_hint__));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__length_hint__));
|
||||||
|
|
@ -1851,7 +1852,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_type));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_type));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_value));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_value));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(latin1));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(latin1));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lazy));
|
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(leaf_size));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(leaf_size));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(legacy));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(legacy));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(len));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(len));
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ struct _Py_global_strings {
|
||||||
STRUCT_FOR_ID(__itruediv__)
|
STRUCT_FOR_ID(__itruediv__)
|
||||||
STRUCT_FOR_ID(__ixor__)
|
STRUCT_FOR_ID(__ixor__)
|
||||||
STRUCT_FOR_ID(__lazy_import__)
|
STRUCT_FOR_ID(__lazy_import__)
|
||||||
|
STRUCT_FOR_ID(__lazy_modules__)
|
||||||
STRUCT_FOR_ID(__le__)
|
STRUCT_FOR_ID(__le__)
|
||||||
STRUCT_FOR_ID(__len__)
|
STRUCT_FOR_ID(__len__)
|
||||||
STRUCT_FOR_ID(__length_hint__)
|
STRUCT_FOR_ID(__length_hint__)
|
||||||
|
|
@ -574,7 +575,6 @@ struct _Py_global_strings {
|
||||||
STRUCT_FOR_ID(last_type)
|
STRUCT_FOR_ID(last_type)
|
||||||
STRUCT_FOR_ID(last_value)
|
STRUCT_FOR_ID(last_value)
|
||||||
STRUCT_FOR_ID(latin1)
|
STRUCT_FOR_ID(latin1)
|
||||||
STRUCT_FOR_ID(lazy)
|
|
||||||
STRUCT_FOR_ID(leaf_size)
|
STRUCT_FOR_ID(leaf_size)
|
||||||
STRUCT_FOR_ID(legacy)
|
STRUCT_FOR_ID(legacy)
|
||||||
STRUCT_FOR_ID(len)
|
STRUCT_FOR_ID(len)
|
||||||
|
|
|
||||||
2
Include/internal/pycore_runtime_init_generated.h
generated
2
Include/internal/pycore_runtime_init_generated.h
generated
|
|
@ -1431,6 +1431,7 @@ extern "C" {
|
||||||
INIT_ID(__itruediv__), \
|
INIT_ID(__itruediv__), \
|
||||||
INIT_ID(__ixor__), \
|
INIT_ID(__ixor__), \
|
||||||
INIT_ID(__lazy_import__), \
|
INIT_ID(__lazy_import__), \
|
||||||
|
INIT_ID(__lazy_modules__), \
|
||||||
INIT_ID(__le__), \
|
INIT_ID(__le__), \
|
||||||
INIT_ID(__len__), \
|
INIT_ID(__len__), \
|
||||||
INIT_ID(__length_hint__), \
|
INIT_ID(__length_hint__), \
|
||||||
|
|
@ -1849,7 +1850,6 @@ extern "C" {
|
||||||
INIT_ID(last_type), \
|
INIT_ID(last_type), \
|
||||||
INIT_ID(last_value), \
|
INIT_ID(last_value), \
|
||||||
INIT_ID(latin1), \
|
INIT_ID(latin1), \
|
||||||
INIT_ID(lazy), \
|
|
||||||
INIT_ID(leaf_size), \
|
INIT_ID(leaf_size), \
|
||||||
INIT_ID(legacy), \
|
INIT_ID(legacy), \
|
||||||
INIT_ID(len), \
|
INIT_ID(len), \
|
||||||
|
|
|
||||||
|
|
@ -412,6 +412,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
|
||||||
_PyUnicode_InternStatic(interp, &string);
|
_PyUnicode_InternStatic(interp, &string);
|
||||||
assert(_PyUnicode_CheckConsistency(string, 1));
|
assert(_PyUnicode_CheckConsistency(string, 1));
|
||||||
assert(PyUnicode_GET_LENGTH(string) != 1);
|
assert(PyUnicode_GET_LENGTH(string) != 1);
|
||||||
|
string = &_Py_ID(__lazy_modules__);
|
||||||
|
_PyUnicode_InternStatic(interp, &string);
|
||||||
|
assert(_PyUnicode_CheckConsistency(string, 1));
|
||||||
|
assert(PyUnicode_GET_LENGTH(string) != 1);
|
||||||
string = &_Py_ID(__le__);
|
string = &_Py_ID(__le__);
|
||||||
_PyUnicode_InternStatic(interp, &string);
|
_PyUnicode_InternStatic(interp, &string);
|
||||||
assert(_PyUnicode_CheckConsistency(string, 1));
|
assert(_PyUnicode_CheckConsistency(string, 1));
|
||||||
|
|
@ -2084,10 +2088,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
|
||||||
_PyUnicode_InternStatic(interp, &string);
|
_PyUnicode_InternStatic(interp, &string);
|
||||||
assert(_PyUnicode_CheckConsistency(string, 1));
|
assert(_PyUnicode_CheckConsistency(string, 1));
|
||||||
assert(PyUnicode_GET_LENGTH(string) != 1);
|
assert(PyUnicode_GET_LENGTH(string) != 1);
|
||||||
string = &_Py_ID(lazy);
|
|
||||||
_PyUnicode_InternStatic(interp, &string);
|
|
||||||
assert(_PyUnicode_CheckConsistency(string, 1));
|
|
||||||
assert(PyUnicode_GET_LENGTH(string) != 1);
|
|
||||||
string = &_Py_ID(leaf_size);
|
string = &_Py_ID(leaf_size);
|
||||||
_PyUnicode_InternStatic(interp, &string);
|
_PyUnicode_InternStatic(interp, &string);
|
||||||
assert(_PyUnicode_CheckConsistency(string, 1));
|
assert(_PyUnicode_CheckConsistency(string, 1));
|
||||||
|
|
|
||||||
|
|
@ -2614,6 +2614,23 @@ def test_global_filter_from_true(self):
|
||||||
|
|
||||||
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
|
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
|
||||||
|
|
||||||
|
def test_compatibility_mode(self):
|
||||||
|
try:
|
||||||
|
import test.test_import.data.lazy_imports.basic_compatibility_mode
|
||||||
|
except ImportError as e:
|
||||||
|
self.fail('lazy import failed')
|
||||||
|
|
||||||
|
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
|
||||||
|
|
||||||
|
def test_compatibility_mode_relative(self):
|
||||||
|
try:
|
||||||
|
import test.test_import.data.lazy_imports.basic_compatibility_mode_relative
|
||||||
|
except ImportError as e:
|
||||||
|
self.fail('lazy import failed')
|
||||||
|
|
||||||
|
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestSinglePhaseSnapshot(ModuleSnapshot):
|
class TestSinglePhaseSnapshot(ModuleSnapshot):
|
||||||
"""A representation of a single-phase init module for testing.
|
"""A representation of a single-phase init module for testing.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2']
|
||||||
|
import test.test_import.data.lazy_imports.basic2
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2']
|
||||||
|
lazy from .basic2 import f
|
||||||
|
|
@ -3862,6 +3862,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
PyObject *final_mod = NULL;
|
PyObject *final_mod = NULL;
|
||||||
PyObject *mod = NULL;
|
PyObject *mod = NULL;
|
||||||
PyObject *package = NULL;
|
PyObject *package = NULL;
|
||||||
|
PyObject *lazy_modules = NULL;
|
||||||
PyInterpreterState *interp = tstate->interp;
|
PyInterpreterState *interp = tstate->interp;
|
||||||
int has_from;
|
int has_from;
|
||||||
|
|
||||||
|
|
@ -3870,6 +3871,11 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (globals != NULL &&
|
||||||
|
PyMapping_GetOptionalItem(globals, &_Py_ID(__lazy_modules__), &lazy_modules) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* The below code is importlib.__import__() & _gcd_import(), ported to C
|
/* The below code is importlib.__import__() & _gcd_import(), ported to C
|
||||||
for added performance. */
|
for added performance. */
|
||||||
|
|
||||||
|
|
@ -3888,6 +3894,24 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lazy_modules != NULL) {
|
||||||
|
// Check and see if the module is opting in w/o syntax for backwards compatibility
|
||||||
|
// with older Python versions.
|
||||||
|
int contains = PySequence_Contains(lazy_modules, name);
|
||||||
|
if (contains < 0) {
|
||||||
|
goto error;
|
||||||
|
} else if (contains == 1) {
|
||||||
|
_PyInterpreterFrame *frame = _PyEval_GetFrame();
|
||||||
|
if (frame == NULL) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "no current frame");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
final_mod = _PyImport_LazyImportModuleLevelObject(tstate, name, frame->f_builtins, globals,
|
||||||
|
locals, fromlist, level);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod = import_get_module(tstate, abs_name);
|
mod = import_get_module(tstate, abs_name);
|
||||||
if (mod == NULL && _PyErr_Occurred(tstate)) {
|
if (mod == NULL && _PyErr_Occurred(tstate)) {
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -3980,6 +4004,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
Py_XDECREF(lazy_modules);
|
||||||
Py_XDECREF(abs_name);
|
Py_XDECREF(abs_name);
|
||||||
Py_XDECREF(mod);
|
Py_XDECREF(mod);
|
||||||
Py_XDECREF(package);
|
Py_XDECREF(package);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue