diff options
author | Shantanu <12621235+hauntsaninja@users.noreply.github.com> | 2023-12-21 21:24:10 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-21 21:24:10 (GMT) |
commit | 61e818409567ce452af60605937cdedf582f6293 (patch) | |
tree | 7ebe7cb8d398d3f8f5a645b4a47da7471036aefe /Objects | |
parent | 2d91409c690b113493e3e81efc880301d2949f5f (diff) | |
download | cpython-61e818409567ce452af60605937cdedf582f6293.zip cpython-61e818409567ce452af60605937cdedf582f6293.tar.gz cpython-61e818409567ce452af60605937cdedf582f6293.tar.bz2 |
gh-95754: Better AttributeError on partially initialised module (#112577)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/moduleobject.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index e2741fe..3a1c516 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -788,7 +788,7 @@ PyObject* _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress) { // When suppress=1, this function suppresses AttributeError. - PyObject *attr, *mod_name, *getattr; + PyObject *attr, *mod_name, *getattr, *origin; attr = _PyObject_GenericGetAttrWithDict((PyObject *)m, name, NULL, suppress); if (attr) { return attr; @@ -831,11 +831,31 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress) if (suppress != 1) { int rc = _PyModuleSpec_IsInitializing(spec); if (rc > 0) { - PyErr_Format(PyExc_AttributeError, + int valid_spec = PyObject_GetOptionalAttr(spec, &_Py_ID(origin), &origin); + if (valid_spec == -1) { + Py_XDECREF(spec); + Py_DECREF(mod_name); + return NULL; + } + if (valid_spec == 1 && !PyUnicode_Check(origin)) { + valid_spec = 0; + Py_DECREF(origin); + } + if (valid_spec == 1) { + PyErr_Format(PyExc_AttributeError, + "partially initialized " + "module '%U' from '%U' has no attribute '%U' " + "(most likely due to a circular import)", + mod_name, origin, name); + Py_DECREF(origin); + } + else { + PyErr_Format(PyExc_AttributeError, "partially initialized " "module '%U' has no attribute '%U' " "(most likely due to a circular import)", mod_name, name); + } } else if (rc == 0) { rc = _PyModuleSpec_IsUninitializedSubmodule(spec, name); |