mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-28411: Support other mappings in PyInterpreterState.modules. (#3593)
The concrete PyDict_* API is used to interact with PyInterpreterState.modules in a number of places. This isn't compatible with all dict subclasses, nor with other Mapping implementations. This patch switches the concrete API usage to the corresponding abstract API calls. We also add a PyImport_GetModule() function (and some other helpers) to reduce a bunch of code duplication.
This commit is contained in:
parent
e82c034496
commit
3f9eee6eb4
11 changed files with 216 additions and 113 deletions
|
@ -204,6 +204,13 @@ Importing Modules
|
||||||
Return the dictionary used for the module administration (a.k.a.
|
Return the dictionary used for the module administration (a.k.a.
|
||||||
``sys.modules``). Note that this is a per-interpreter variable.
|
``sys.modules``). Note that this is a per-interpreter variable.
|
||||||
|
|
||||||
|
.. c:function:: PyObject* PyImport_GetModule(PyObject *name)
|
||||||
|
|
||||||
|
Return the already imported module with the given name. If the
|
||||||
|
module has not been imported yet then returns NULL but does not set
|
||||||
|
an error. Returns NULL and sets an error if the lookup failed.
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
.. c:function:: PyObject* PyImport_GetImporter(PyObject *path)
|
.. c:function:: PyObject* PyImport_GetImporter(PyObject *path)
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,14 @@ PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject(
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
|
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
|
||||||
|
PyAPI_FUNC(PyObject *) PyImport_GetModule(PyObject *name);
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *);
|
PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *);
|
||||||
|
PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(struct _Py_Identifier *name);
|
||||||
|
PyAPI_FUNC(PyObject *) _PyImport_AddModuleObject(PyObject *name,
|
||||||
|
PyObject *modules);
|
||||||
|
PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module);
|
||||||
|
PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module);
|
||||||
#endif
|
#endif
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
||||||
PyAPI_FUNC(PyObject *) PyImport_AddModuleObject(
|
PyAPI_FUNC(PyObject *) PyImport_AddModuleObject(
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Switch to the abstract API when dealing with ``PyInterpreterState.modules``.
|
||||||
|
This allows later support for all dict subclasses and other Mapping
|
||||||
|
implementations. Also add a ``PyImport_GetModule()`` function to reduce
|
||||||
|
a bunch of duplicated code.
|
|
@ -1649,13 +1649,40 @@ getattribute(PyObject *obj, PyObject *name, int allow_qualname)
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_checkmodule(PyObject *module_name, PyObject *module,
|
||||||
|
PyObject *global, PyObject *dotted_path)
|
||||||
|
{
|
||||||
|
if (module == Py_None) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (PyUnicode_Check(module_name) &&
|
||||||
|
_PyUnicode_EqualToASCIIString(module_name, "__main__")) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *candidate = get_deep_attribute(module, dotted_path, NULL);
|
||||||
|
if (candidate == NULL) {
|
||||||
|
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (candidate != global) {
|
||||||
|
Py_DECREF(candidate);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Py_DECREF(candidate);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
whichmodule(PyObject *global, PyObject *dotted_path)
|
whichmodule(PyObject *global, PyObject *dotted_path)
|
||||||
{
|
{
|
||||||
PyObject *module_name;
|
PyObject *module_name;
|
||||||
PyObject *modules_dict;
|
PyObject *module = NULL;
|
||||||
PyObject *module;
|
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
PyObject *modules;
|
||||||
_Py_IDENTIFIER(__module__);
|
_Py_IDENTIFIER(__module__);
|
||||||
_Py_IDENTIFIER(modules);
|
_Py_IDENTIFIER(modules);
|
||||||
_Py_IDENTIFIER(__main__);
|
_Py_IDENTIFIER(__main__);
|
||||||
|
@ -1678,35 +1705,48 @@ whichmodule(PyObject *global, PyObject *dotted_path)
|
||||||
assert(module_name == NULL);
|
assert(module_name == NULL);
|
||||||
|
|
||||||
/* Fallback on walking sys.modules */
|
/* Fallback on walking sys.modules */
|
||||||
modules_dict = _PySys_GetObjectId(&PyId_modules);
|
modules = _PySys_GetObjectId(&PyId_modules);
|
||||||
if (modules_dict == NULL) {
|
if (modules == NULL) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");
|
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (PyDict_CheckExact(modules)) {
|
||||||
i = 0;
|
i = 0;
|
||||||
while (PyDict_Next(modules_dict, &i, &module_name, &module)) {
|
while (PyDict_Next(modules, &i, &module_name, &module)) {
|
||||||
PyObject *candidate;
|
if (_checkmodule(module_name, module, global, dotted_path) == 0) {
|
||||||
if (PyUnicode_Check(module_name) &&
|
Py_INCREF(module_name);
|
||||||
_PyUnicode_EqualToASCIIString(module_name, "__main__"))
|
return module_name;
|
||||||
continue;
|
}
|
||||||
if (module == Py_None)
|
if (PyErr_Occurred()) {
|
||||||
continue;
|
|
||||||
|
|
||||||
candidate = get_deep_attribute(module, dotted_path, NULL);
|
|
||||||
if (candidate == NULL) {
|
|
||||||
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
PyErr_Clear();
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (candidate == global) {
|
else {
|
||||||
Py_INCREF(module_name);
|
PyObject *iterator = PyObject_GetIter(modules);
|
||||||
Py_DECREF(candidate);
|
if (iterator == NULL) {
|
||||||
return module_name;
|
return NULL;
|
||||||
}
|
}
|
||||||
Py_DECREF(candidate);
|
while ((module_name = PyIter_Next(iterator))) {
|
||||||
|
module = PyObject_GetItem(modules, module_name);
|
||||||
|
if (module == NULL) {
|
||||||
|
Py_DECREF(module_name);
|
||||||
|
Py_DECREF(iterator);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (_checkmodule(module_name, module, global, dotted_path) == 0) {
|
||||||
|
Py_DECREF(module);
|
||||||
|
Py_DECREF(iterator);
|
||||||
|
return module_name;
|
||||||
|
}
|
||||||
|
Py_DECREF(module);
|
||||||
|
Py_DECREF(module_name);
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
Py_DECREF(iterator);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_DECREF(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no module is found, use __main__. */
|
/* If no module is found, use __main__. */
|
||||||
|
@ -6424,9 +6464,7 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self,
|
||||||
/*[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]*/
|
/*[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]*/
|
||||||
{
|
{
|
||||||
PyObject *global;
|
PyObject *global;
|
||||||
PyObject *modules_dict;
|
|
||||||
PyObject *module;
|
PyObject *module;
|
||||||
_Py_IDENTIFIER(modules);
|
|
||||||
|
|
||||||
/* Try to map the old names used in Python 2.x to the new ones used in
|
/* Try to map the old names used in Python 2.x to the new ones used in
|
||||||
Python 3.x. We do this only with old pickle protocols and when the
|
Python 3.x. We do this only with old pickle protocols and when the
|
||||||
|
@ -6483,25 +6521,16 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modules_dict = _PySys_GetObjectId(&PyId_modules);
|
module = PyImport_GetModule(module_name);
|
||||||
if (modules_dict == NULL) {
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
module = PyDict_GetItemWithError(modules_dict, module_name);
|
|
||||||
if (module == NULL) {
|
if (module == NULL) {
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
module = PyImport_Import(module_name);
|
module = PyImport_Import(module_name);
|
||||||
if (module == NULL)
|
if (module == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
global = getattribute(module, global_name, self->proto >= 4);
|
|
||||||
Py_DECREF(module);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
global = getattribute(module, global_name, self->proto >= 4);
|
|
||||||
}
|
}
|
||||||
|
global = getattribute(module, global_name, self->proto >= 4);
|
||||||
|
Py_DECREF(module);
|
||||||
return global;
|
return global;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1643,7 +1643,6 @@ MODULE_INITFUNC(void)
|
||||||
PyObject *errors_module;
|
PyObject *errors_module;
|
||||||
PyObject *modelmod_name;
|
PyObject *modelmod_name;
|
||||||
PyObject *model_module;
|
PyObject *model_module;
|
||||||
PyObject *sys_modules;
|
|
||||||
PyObject *tmpnum, *tmpstr;
|
PyObject *tmpnum, *tmpstr;
|
||||||
PyObject *codes_dict;
|
PyObject *codes_dict;
|
||||||
PyObject *rev_codes_dict;
|
PyObject *rev_codes_dict;
|
||||||
|
@ -1693,11 +1692,6 @@ MODULE_INITFUNC(void)
|
||||||
*/
|
*/
|
||||||
PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
|
PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
|
||||||
|
|
||||||
sys_modules = PySys_GetObject("modules");
|
|
||||||
if (sys_modules == NULL) {
|
|
||||||
Py_DECREF(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
d = PyModule_GetDict(m);
|
d = PyModule_GetDict(m);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
Py_DECREF(m);
|
Py_DECREF(m);
|
||||||
|
@ -1707,7 +1701,7 @@ MODULE_INITFUNC(void)
|
||||||
if (errors_module == NULL) {
|
if (errors_module == NULL) {
|
||||||
errors_module = PyModule_New(MODULE_NAME ".errors");
|
errors_module = PyModule_New(MODULE_NAME ".errors");
|
||||||
if (errors_module != NULL) {
|
if (errors_module != NULL) {
|
||||||
PyDict_SetItem(sys_modules, errmod_name, errors_module);
|
_PyImport_SetModule(errmod_name, errors_module);
|
||||||
/* gives away the reference to errors_module */
|
/* gives away the reference to errors_module */
|
||||||
PyModule_AddObject(m, "errors", errors_module);
|
PyModule_AddObject(m, "errors", errors_module);
|
||||||
}
|
}
|
||||||
|
@ -1717,7 +1711,7 @@ MODULE_INITFUNC(void)
|
||||||
if (model_module == NULL) {
|
if (model_module == NULL) {
|
||||||
model_module = PyModule_New(MODULE_NAME ".model");
|
model_module = PyModule_New(MODULE_NAME ".model");
|
||||||
if (model_module != NULL) {
|
if (model_module != NULL) {
|
||||||
PyDict_SetItem(sys_modules, modelmod_name, model_module);
|
_PyImport_SetModule(modelmod_name, model_module);
|
||||||
/* gives away the reference to model_module */
|
/* gives away the reference to model_module */
|
||||||
PyModule_AddObject(m, "model", model_module);
|
PyModule_AddObject(m, "model", model_module);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3913,10 +3913,8 @@ import_copyreg(void)
|
||||||
by storing a reference to the cached module in a static variable, but
|
by storing a reference to the cached module in a static variable, but
|
||||||
this broke when multiple embedded interpreters were in use (see issue
|
this broke when multiple embedded interpreters were in use (see issue
|
||||||
#17408 and #19088). */
|
#17408 and #19088). */
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
copyreg_module = PyImport_GetModule(copyreg_str);
|
||||||
copyreg_module = PyDict_GetItemWithError(modules, copyreg_str);
|
|
||||||
if (copyreg_module != NULL) {
|
if (copyreg_module != NULL) {
|
||||||
Py_INCREF(copyreg_module);
|
|
||||||
return copyreg_module;
|
return copyreg_module;
|
||||||
}
|
}
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
|
|
|
@ -38,7 +38,6 @@ static PyObject *
|
||||||
get_warnings_attr(const char *attr, int try_import)
|
get_warnings_attr(const char *attr, int try_import)
|
||||||
{
|
{
|
||||||
static PyObject *warnings_str = NULL;
|
static PyObject *warnings_str = NULL;
|
||||||
PyObject *all_modules;
|
|
||||||
PyObject *warnings_module, *obj;
|
PyObject *warnings_module, *obj;
|
||||||
|
|
||||||
if (warnings_str == NULL) {
|
if (warnings_str == NULL) {
|
||||||
|
@ -58,13 +57,9 @@ get_warnings_attr(const char *attr, int try_import)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
all_modules = PyImport_GetModuleDict();
|
warnings_module = PyImport_GetModule(warnings_str);
|
||||||
|
|
||||||
warnings_module = PyDict_GetItem(all_modules, warnings_str);
|
|
||||||
if (warnings_module == NULL)
|
if (warnings_module == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_INCREF(warnings_module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PyObject_HasAttrString(warnings_module, attr)) {
|
if (!PyObject_HasAttrString(warnings_module, attr)) {
|
||||||
|
|
|
@ -4935,13 +4935,12 @@ import_from(PyObject *v, PyObject *name)
|
||||||
Py_DECREF(pkgname);
|
Py_DECREF(pkgname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname);
|
x = PyImport_GetModule(fullmodname);
|
||||||
Py_DECREF(fullmodname);
|
Py_DECREF(fullmodname);
|
||||||
if (x == NULL) {
|
if (x == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
Py_DECREF(pkgname);
|
Py_DECREF(pkgname);
|
||||||
Py_INCREF(x);
|
|
||||||
return x;
|
return x;
|
||||||
error:
|
error:
|
||||||
pkgpath = PyModule_GetFilenameObject(v);
|
pkgpath = PyModule_GetFilenameObject(v);
|
||||||
|
|
164
Python/import.c
164
Python/import.c
|
@ -291,8 +291,9 @@ PyObject *
|
||||||
PyImport_GetModuleDict(void)
|
PyImport_GetModuleDict(void)
|
||||||
{
|
{
|
||||||
PyInterpreterState *interp = PyThreadState_GET()->interp;
|
PyInterpreterState *interp = PyThreadState_GET()->interp;
|
||||||
if (interp->modules == NULL)
|
if (interp->modules == NULL) {
|
||||||
Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
|
Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
|
||||||
|
}
|
||||||
return interp->modules;
|
return interp->modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +309,55 @@ _PyImport_IsInitialized(PyInterpreterState *interp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_PyImport_GetModuleId(struct _Py_Identifier *nameid)
|
||||||
|
{
|
||||||
|
PyObject *name = _PyUnicode_FromId(nameid); /* borrowed */
|
||||||
|
if (name == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyImport_GetModule(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_PyImport_SetModule(PyObject *name, PyObject *m)
|
||||||
|
{
|
||||||
|
PyObject *modules = PyImport_GetModuleDict();
|
||||||
|
return PyObject_SetItem(modules, name, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_PyImport_SetModuleString(const char *name, PyObject *m)
|
||||||
|
{
|
||||||
|
PyObject *modules = PyImport_GetModuleDict();
|
||||||
|
return PyMapping_SetItemString(modules, name, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
PyImport_GetModule(PyObject *name)
|
||||||
|
{
|
||||||
|
PyObject *m;
|
||||||
|
PyObject *modules = PyImport_GetModuleDict();
|
||||||
|
if (modules == NULL) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_INCREF(modules);
|
||||||
|
if (PyDict_CheckExact(modules)) {
|
||||||
|
m = PyDict_GetItemWithError(modules, name); /* borrowed */
|
||||||
|
Py_XINCREF(m);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m = PyObject_GetItem(modules, name);
|
||||||
|
if (PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_DECREF(modules);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* List of names to clear in sys */
|
/* List of names to clear in sys */
|
||||||
static const char * const sys_deletes[] = {
|
static const char * const sys_deletes[] = {
|
||||||
"path", "argv", "ps1", "ps2",
|
"path", "argv", "ps1", "ps2",
|
||||||
|
@ -387,21 +437,51 @@ PyImport_Cleanup(void)
|
||||||
if (PyErr_Occurred()) \
|
if (PyErr_Occurred()) \
|
||||||
PyErr_Clear(); \
|
PyErr_Clear(); \
|
||||||
}
|
}
|
||||||
|
#define CLEAR_MODULE(name, mod) \
|
||||||
|
if (PyModule_Check(mod)) { \
|
||||||
|
if (Py_VerboseFlag && PyUnicode_Check(name)) \
|
||||||
|
PySys_FormatStderr("# cleanup[2] removing %U\n", name); \
|
||||||
|
STORE_MODULE_WEAKREF(name, mod); \
|
||||||
|
PyObject_SetItem(modules, name, Py_None); \
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove all modules from sys.modules, hoping that garbage collection
|
/* Remove all modules from sys.modules, hoping that garbage collection
|
||||||
can reclaim most of them. */
|
can reclaim most of them. */
|
||||||
pos = 0;
|
if (PyDict_CheckExact(modules)) {
|
||||||
while (PyDict_Next(modules, &pos, &key, &value)) {
|
pos = 0;
|
||||||
if (PyModule_Check(value)) {
|
while (PyDict_Next(modules, &pos, &key, &value)) {
|
||||||
if (Py_VerboseFlag && PyUnicode_Check(key))
|
CLEAR_MODULE(key, value);
|
||||||
PySys_FormatStderr("# cleanup[2] removing %U\n", key);
|
}
|
||||||
STORE_MODULE_WEAKREF(key, value);
|
}
|
||||||
PyDict_SetItem(modules, key, Py_None);
|
else {
|
||||||
|
PyObject *iterator = PyObject_GetIter(modules);
|
||||||
|
if (iterator == NULL) {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while ((key = PyIter_Next(iterator))) {
|
||||||
|
value = PyObject_GetItem(modules, key);
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_Clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CLEAR_MODULE(key, value);
|
||||||
|
Py_DECREF(value);
|
||||||
|
Py_DECREF(key);
|
||||||
|
}
|
||||||
|
Py_DECREF(iterator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the modules dict. */
|
/* Clear the modules dict. */
|
||||||
PyDict_Clear(modules);
|
if (PyDict_CheckExact(modules)) {
|
||||||
|
PyDict_Clear(modules);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_Py_IDENTIFIER(clear);
|
||||||
|
if (_PyObject_CallMethodId(modules, &PyId_clear, "") == NULL)
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
/* Restore the original builtins dict, to ensure that any
|
/* Restore the original builtins dict, to ensure that any
|
||||||
user data gets cleared. */
|
user data gets cleared. */
|
||||||
dict = PyDict_Copy(interp->builtins);
|
dict = PyDict_Copy(interp->builtins);
|
||||||
|
@ -541,10 +621,10 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name,
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (PyDict_SetItem(modules, name, mod) < 0)
|
if (PyObject_SetItem(modules, name, mod) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (_PyState_AddModule(mod, def) < 0) {
|
if (_PyState_AddModule(mod, def) < 0) {
|
||||||
PyDict_DelItem(modules, name);
|
PyMapping_DelItem(modules, name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (def->m_size == -1) {
|
if (def->m_size == -1) {
|
||||||
|
@ -625,14 +705,14 @@ _PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename,
|
||||||
mod = def->m_base.m_init();
|
mod = def->m_base.m_init();
|
||||||
if (mod == NULL)
|
if (mod == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (PyDict_SetItem(modules, name, mod) == -1) {
|
if (PyObject_SetItem(modules, name, mod) == -1) {
|
||||||
Py_DECREF(mod);
|
Py_DECREF(mod);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Py_DECREF(mod);
|
Py_DECREF(mod);
|
||||||
}
|
}
|
||||||
if (_PyState_AddModule(mod, def) < 0) {
|
if (_PyState_AddModule(mod, def) < 0) {
|
||||||
PyDict_DelItem(modules, name);
|
PyMapping_DelItem(modules, name);
|
||||||
Py_DECREF(mod);
|
Py_DECREF(mod);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -672,18 +752,27 @@ PyObject *
|
||||||
_PyImport_AddModuleObject(PyObject *name, PyObject *modules)
|
_PyImport_AddModuleObject(PyObject *name, PyObject *modules)
|
||||||
{
|
{
|
||||||
PyObject *m;
|
PyObject *m;
|
||||||
|
if (PyDict_CheckExact(modules)) {
|
||||||
if ((m = PyDict_GetItemWithError(modules, name)) != NULL &&
|
m = PyDict_GetItemWithError(modules, name);
|
||||||
PyModule_Check(m)) {
|
}
|
||||||
return m;
|
else {
|
||||||
|
m = PyObject_GetItem(modules, name);
|
||||||
|
// For backward-comaptibility we copy the behavior
|
||||||
|
// of PyDict_GetItemWithError().
|
||||||
|
if (PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (m != NULL && PyModule_Check(m)) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
m = PyModule_NewObject(name);
|
m = PyModule_NewObject(name);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (PyDict_SetItem(modules, name, m) != 0) {
|
if (PyObject_SetItem(modules, name, m) != 0) {
|
||||||
Py_DECREF(m);
|
Py_DECREF(m);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -710,11 +799,13 @@ static void
|
||||||
remove_module(PyObject *name)
|
remove_module(PyObject *name)
|
||||||
{
|
{
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
PyObject *modules = PyImport_GetModuleDict();
|
||||||
if (PyDict_GetItem(modules, name) == NULL)
|
if (PyMapping_DelItem(modules, name) < 0) {
|
||||||
return;
|
if (!PyMapping_HasKey(modules, name)) {
|
||||||
if (PyDict_DelItem(modules, name) < 0)
|
return;
|
||||||
|
}
|
||||||
Py_FatalError("import: deleting existing key in"
|
Py_FatalError("import: deleting existing key in"
|
||||||
"sys.modules failed");
|
"sys.modules failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -823,7 +914,6 @@ module_dict_for_exec(PyObject *name)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object)
|
exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object)
|
||||||
{
|
{
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
|
||||||
PyObject *v, *m;
|
PyObject *v, *m;
|
||||||
|
|
||||||
v = PyEval_EvalCode(code_object, module_dict, module_dict);
|
v = PyEval_EvalCode(code_object, module_dict, module_dict);
|
||||||
|
@ -833,15 +923,14 @@ exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object
|
||||||
}
|
}
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
|
|
||||||
if ((m = PyDict_GetItem(modules, name)) == NULL) {
|
m = PyImport_GetModule(name);
|
||||||
|
if (m == NULL) {
|
||||||
PyErr_Format(PyExc_ImportError,
|
PyErr_Format(PyExc_ImportError,
|
||||||
"Loaded module %R not found in sys.modules",
|
"Loaded module %R not found in sys.modules",
|
||||||
name);
|
name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(m);
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1540,8 +1629,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
Py_INCREF(abs_name);
|
Py_INCREF(abs_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
mod = PyImport_GetModule(abs_name);
|
||||||
mod = PyDict_GetItem(modules, abs_name);
|
|
||||||
if (mod != NULL && mod != Py_None) {
|
if (mod != NULL && mod != Py_None) {
|
||||||
_Py_IDENTIFIER(__spec__);
|
_Py_IDENTIFIER(__spec__);
|
||||||
_Py_IDENTIFIER(_initializing);
|
_Py_IDENTIFIER(_initializing);
|
||||||
|
@ -1550,7 +1638,6 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
PyObject *spec;
|
PyObject *spec;
|
||||||
int initializing = 0;
|
int initializing = 0;
|
||||||
|
|
||||||
Py_INCREF(mod);
|
|
||||||
/* Optimization: only call _bootstrap._lock_unlock_module() if
|
/* Optimization: only call _bootstrap._lock_unlock_module() if
|
||||||
__spec__._initializing is true.
|
__spec__._initializing is true.
|
||||||
NOTE: because of this, initializing must be set *before*
|
NOTE: because of this, initializing must be set *before*
|
||||||
|
@ -1579,6 +1666,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Py_XDECREF(mod);
|
||||||
mod = _PyObject_CallMethodIdObjArgs(interp->importlib,
|
mod = _PyObject_CallMethodIdObjArgs(interp->importlib,
|
||||||
&PyId__find_and_load, abs_name,
|
&PyId__find_and_load, abs_name,
|
||||||
interp->import_func, NULL);
|
interp->import_func, NULL);
|
||||||
|
@ -1628,8 +1716,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
final_mod = PyImport_GetModule(to_return);
|
||||||
final_mod = PyDict_GetItem(modules, to_return);
|
|
||||||
Py_DECREF(to_return);
|
Py_DECREF(to_return);
|
||||||
if (final_mod == NULL) {
|
if (final_mod == NULL) {
|
||||||
PyErr_Format(PyExc_KeyError,
|
PyErr_Format(PyExc_KeyError,
|
||||||
|
@ -1637,7 +1724,6 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
to_return);
|
to_return);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
Py_INCREF(final_mod);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1682,19 +1768,16 @@ PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImport_ReloadModule(PyObject *m)
|
PyImport_ReloadModule(PyObject *m)
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(imp);
|
||||||
_Py_IDENTIFIER(reload);
|
_Py_IDENTIFIER(reload);
|
||||||
PyObject *reloaded_module = NULL;
|
PyObject *reloaded_module = NULL;
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
PyObject *imp = _PyImport_GetModuleId(&PyId_imp);
|
||||||
PyObject *imp = PyDict_GetItemString(modules, "imp");
|
|
||||||
if (imp == NULL) {
|
if (imp == NULL) {
|
||||||
imp = PyImport_ImportModule("imp");
|
imp = PyImport_ImportModule("imp");
|
||||||
if (imp == NULL) {
|
if (imp == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Py_INCREF(imp);
|
|
||||||
}
|
|
||||||
|
|
||||||
reloaded_module = _PyObject_CallMethodIdObjArgs(imp, &PyId_reload, m, NULL);
|
reloaded_module = _PyObject_CallMethodIdObjArgs(imp, &PyId_reload, m, NULL);
|
||||||
Py_DECREF(imp);
|
Py_DECREF(imp);
|
||||||
|
@ -1720,7 +1803,6 @@ PyImport_Import(PyObject *module_name)
|
||||||
PyObject *globals = NULL;
|
PyObject *globals = NULL;
|
||||||
PyObject *import = NULL;
|
PyObject *import = NULL;
|
||||||
PyObject *builtins = NULL;
|
PyObject *builtins = NULL;
|
||||||
PyObject *modules = NULL;
|
|
||||||
PyObject *r = NULL;
|
PyObject *r = NULL;
|
||||||
|
|
||||||
/* Initialize constant string objects */
|
/* Initialize constant string objects */
|
||||||
|
@ -1775,12 +1857,8 @@ PyImport_Import(PyObject *module_name)
|
||||||
goto err;
|
goto err;
|
||||||
Py_DECREF(r);
|
Py_DECREF(r);
|
||||||
|
|
||||||
modules = PyImport_GetModuleDict();
|
r = PyImport_GetModule(module_name);
|
||||||
r = PyDict_GetItemWithError(modules, module_name);
|
if (r == NULL && !PyErr_Occurred()) {
|
||||||
if (r != NULL) {
|
|
||||||
Py_INCREF(r);
|
|
||||||
}
|
|
||||||
else if (!PyErr_Occurred()) {
|
|
||||||
PyErr_SetObject(PyExc_KeyError, module_name);
|
PyErr_SetObject(PyExc_KeyError, module_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ _Py_IDENTIFIER(name);
|
||||||
_Py_IDENTIFIER(stdin);
|
_Py_IDENTIFIER(stdin);
|
||||||
_Py_IDENTIFIER(stdout);
|
_Py_IDENTIFIER(stdout);
|
||||||
_Py_IDENTIFIER(stderr);
|
_Py_IDENTIFIER(stderr);
|
||||||
|
_Py_IDENTIFIER(threading);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -283,7 +284,6 @@ initimport(PyInterpreterState *interp, PyObject *sysmod)
|
||||||
{
|
{
|
||||||
PyObject *importlib;
|
PyObject *importlib;
|
||||||
PyObject *impmod;
|
PyObject *impmod;
|
||||||
PyObject *sys_modules;
|
|
||||||
PyObject *value;
|
PyObject *value;
|
||||||
|
|
||||||
/* Import _importlib through its frozen version, _frozen_importlib. */
|
/* Import _importlib through its frozen version, _frozen_importlib. */
|
||||||
|
@ -314,11 +314,7 @@ initimport(PyInterpreterState *interp, PyObject *sysmod)
|
||||||
else if (Py_VerboseFlag) {
|
else if (Py_VerboseFlag) {
|
||||||
PySys_FormatStderr("import _imp # builtin\n");
|
PySys_FormatStderr("import _imp # builtin\n");
|
||||||
}
|
}
|
||||||
sys_modules = PyImport_GetModuleDict();
|
if (_PyImport_SetModuleString("_imp", impmod) < 0) {
|
||||||
if (Py_VerboseFlag) {
|
|
||||||
PySys_FormatStderr("import sys # builtin\n");
|
|
||||||
}
|
|
||||||
if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) {
|
|
||||||
Py_FatalError("Py_Initialize: can't save _imp to sys.modules");
|
Py_FatalError("Py_Initialize: can't save _imp to sys.modules");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1916,8 +1912,7 @@ wait_for_thread_shutdown(void)
|
||||||
{
|
{
|
||||||
_Py_IDENTIFIER(_shutdown);
|
_Py_IDENTIFIER(_shutdown);
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
PyObject *threading = _PyImport_GetModuleId(&PyId_threading);
|
||||||
PyObject *threading = PyMapping_GetItemString(modules, "threading");
|
|
||||||
if (threading == NULL) {
|
if (threading == NULL) {
|
||||||
/* threading not imported */
|
/* threading not imported */
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
|
|
@ -162,18 +162,16 @@ static PyObject *
|
||||||
sys_displayhook(PyObject *self, PyObject *o)
|
sys_displayhook(PyObject *self, PyObject *o)
|
||||||
{
|
{
|
||||||
PyObject *outf;
|
PyObject *outf;
|
||||||
PyObject *modules = PyImport_GetModuleDict();
|
|
||||||
if (modules == NULL)
|
|
||||||
return NULL;
|
|
||||||
PyObject *builtins;
|
PyObject *builtins;
|
||||||
static PyObject *newline = NULL;
|
static PyObject *newline = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
builtins = _PyDict_GetItemId(modules, &PyId_builtins);
|
builtins = _PyImport_GetModuleId(&PyId_builtins);
|
||||||
if (builtins == NULL) {
|
if (builtins == NULL) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "lost builtins module");
|
PyErr_SetString(PyExc_RuntimeError, "lost builtins module");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Py_DECREF(builtins);
|
||||||
|
|
||||||
/* Print value except if None */
|
/* Print value except if None */
|
||||||
/* After printing, also assign to '_' */
|
/* After printing, also assign to '_' */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue