summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-06-23 09:00:43 (GMT)
committerGitHub <noreply@github.com>2021-06-23 09:00:43 (GMT)
commitc3f52b4d707a78eb342372a2be00f3eb846a05b9 (patch)
tree1d5d5e7d4fe5cf7da492ed6eb79f019a43cb1946 /Objects
parent35b773accb41f09e40bf17bfaa5f0bc80796a26c (diff)
downloadcpython-c3f52b4d707a78eb342372a2be00f3eb846a05b9.zip
cpython-c3f52b4d707a78eb342372a2be00f3eb846a05b9.tar.gz
cpython-c3f52b4d707a78eb342372a2be00f3eb846a05b9.tar.bz2
bpo-44486: Make sure that modules always have a dictionary. (GH-26847)
* Make sure that modules always have a dictionary.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/moduleobject.c102
1 files changed, 61 insertions, 41 deletions
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index b69e5ce..61478a1 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -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 */
};