From 8684e59c5cccd5aac7b1f582048a78f37b9b8a82 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 6 Apr 2018 18:35:59 +0300 Subject: [PATCH] bpo-33237: Improve AttributeError message for partially initialized module. --- Objects/moduleobject.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 5fad4474be0f7c..4d4f4de7aee107 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -718,8 +718,36 @@ module_getattro(PyModuleObject *m, PyObject *name) _Py_IDENTIFIER(__name__); mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__); if (mod_name && PyUnicode_Check(mod_name)) { - PyErr_Format(PyExc_AttributeError, - "module '%U' has no attribute '%U'", mod_name, name); + _Py_IDENTIFIER(__spec__); + _Py_IDENTIFIER(_initializing); + PyObject *value = NULL; + PyObject *spec; + int initializing = 0; + Py_INCREF(mod_name); + spec = _PyDict_GetItemId(m->md_dict, &PyId___spec__); + if (spec != NULL && spec != Py_None) { + value = _PyObject_GetAttrId(spec, &PyId__initializing); + } + if (value == NULL) + PyErr_Clear(); + else { + initializing = PyObject_IsTrue(value); + Py_DECREF(value); + if (initializing < 0) + PyErr_Clear(); + } + if (initializing > 0) { + PyErr_Format(PyExc_AttributeError, + "partially initialized " + "module '%U' has no attribute '%U'", + mod_name, name); + } + else { + PyErr_Format(PyExc_AttributeError, + "module '%U' has no attribute '%U'", + mod_name, name); + } + Py_DECREF(mod_name); return NULL; } }