mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
bpo-44486: Make sure that modules always have a dictionary. (GH-26847)
* Make sure that modules always have a dictionary.
This commit is contained in:
parent
35b773accb
commit
c3f52b4d70
4 changed files with 66 additions and 52 deletions
|
@ -64,8 +64,7 @@ module_init_dict(PyModuleObject *mod, PyObject *md_dict,
|
|||
_Py_IDENTIFIER(__package__);
|
||||
_Py_IDENTIFIER(__loader__);
|
||||
|
||||
if (md_dict == NULL)
|
||||
return -1;
|
||||
assert(md_dict != NULL);
|
||||
if (doc == NULL)
|
||||
doc = Py_None;
|
||||
|
||||
|
@ -87,12 +86,11 @@ module_init_dict(PyModuleObject *mod, PyObject *md_dict,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PyObject *
|
||||
PyModule_NewObject(PyObject *name)
|
||||
static PyModuleObject *
|
||||
new_module_notrack(PyTypeObject *mt)
|
||||
{
|
||||
PyModuleObject *m;
|
||||
m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
|
||||
m = PyObject_GC_New(PyModuleObject, mt);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
m->md_def = NULL;
|
||||
|
@ -100,6 +98,29 @@ PyModule_NewObject(PyObject *name)
|
|||
m->md_weaklist = NULL;
|
||||
m->md_name = NULL;
|
||||
m->md_dict = PyDict_New();
|
||||
if (m->md_dict != NULL) {
|
||||
return m;
|
||||
}
|
||||
Py_DECREF(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
new_module(PyTypeObject *mt, PyObject *args, PyObject *kws)
|
||||
{
|
||||
PyObject *m = (PyObject *)new_module_notrack(mt);
|
||||
if (m != NULL) {
|
||||
PyObject_GC_Track(m);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyModule_NewObject(PyObject *name)
|
||||
{
|
||||
PyModuleObject *m = new_module_notrack(&PyModule_Type);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
if (module_init_dict(m, m->md_dict, name, NULL) != 0)
|
||||
goto fail;
|
||||
PyObject_GC_Track(m);
|
||||
|
@ -728,43 +749,42 @@ module_getattro(PyModuleObject *m, PyObject *name)
|
|||
return attr;
|
||||
}
|
||||
PyErr_Clear();
|
||||
if (m->md_dict) {
|
||||
_Py_IDENTIFIER(__getattr__);
|
||||
getattr = _PyDict_GetItemIdWithError(m->md_dict, &PyId___getattr__);
|
||||
if (getattr) {
|
||||
return PyObject_CallOneArg(getattr, name);
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
mod_name = _PyDict_GetItemIdWithError(m->md_dict, &PyId___name__);
|
||||
if (mod_name && PyUnicode_Check(mod_name)) {
|
||||
Py_INCREF(mod_name);
|
||||
PyObject *spec = _PyDict_GetItemIdWithError(m->md_dict, &PyId___spec__);
|
||||
if (spec == NULL && PyErr_Occurred()) {
|
||||
Py_DECREF(mod_name);
|
||||
return NULL;
|
||||
}
|
||||
Py_XINCREF(spec);
|
||||
if (_PyModuleSpec_IsInitializing(spec)) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"partially initialized "
|
||||
"module '%U' has no attribute '%U' "
|
||||
"(most likely due to a circular import)",
|
||||
mod_name, name);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"module '%U' has no attribute '%U'",
|
||||
mod_name, name);
|
||||
}
|
||||
Py_XDECREF(spec);
|
||||
assert(m->md_dict != NULL);
|
||||
_Py_IDENTIFIER(__getattr__);
|
||||
getattr = _PyDict_GetItemIdWithError(m->md_dict, &PyId___getattr__);
|
||||
if (getattr) {
|
||||
return PyObject_CallOneArg(getattr, name);
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
mod_name = _PyDict_GetItemIdWithError(m->md_dict, &PyId___name__);
|
||||
if (mod_name && PyUnicode_Check(mod_name)) {
|
||||
Py_INCREF(mod_name);
|
||||
PyObject *spec = _PyDict_GetItemIdWithError(m->md_dict, &PyId___spec__);
|
||||
if (spec == NULL && PyErr_Occurred()) {
|
||||
Py_DECREF(mod_name);
|
||||
return NULL;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
Py_XINCREF(spec);
|
||||
if (_PyModuleSpec_IsInitializing(spec)) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"partially initialized "
|
||||
"module '%U' has no attribute '%U' "
|
||||
"(most likely due to a circular import)",
|
||||
mod_name, name);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"module '%U' has no attribute '%U'",
|
||||
mod_name, name);
|
||||
}
|
||||
Py_XDECREF(spec);
|
||||
Py_DECREF(mod_name);
|
||||
return NULL;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"module has no attribute '%U'", name);
|
||||
|
@ -948,7 +968,7 @@ PyTypeObject PyModule_Type = {
|
|||
0, /* tp_descr_set */
|
||||
offsetof(PyModuleObject, md_dict), /* tp_dictoffset */
|
||||
module___init__, /* tp_init */
|
||||
PyType_GenericAlloc, /* tp_alloc */
|
||||
PyType_GenericNew, /* tp_new */
|
||||
0, /* tp_alloc */
|
||||
new_module, /* tp_new */
|
||||
PyObject_GC_Del, /* tp_free */
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue