diff options
author | Mark Shannon <mark@hotpy.org> | 2021-06-23 09:00:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-23 09:00:43 (GMT) |
commit | c3f52b4d707a78eb342372a2be00f3eb846a05b9 (patch) | |
tree | 1d5d5e7d4fe5cf7da492ed6eb79f019a43cb1946 /Objects | |
parent | 35b773accb41f09e40bf17bfaa5f0bc80796a26c (diff) | |
download | cpython-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.c | 102 |
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 */ }; |