bpo-44717: improve AttributeError on circular imports of submodules (GH-27299)

Signed-off-by: Filipe Laíns <lains@riseup.net>

Co-authored-by: Łukasz Langa <lukasz@langa.pl>
This commit is contained in:
Filipe Laíns 2021-07-24 10:50:17 +01:00 committed by GitHub
parent 5370f0a82a
commit 8072a1181d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 1807 additions and 1734 deletions

View file

@ -739,6 +739,30 @@ _PyModuleSpec_IsInitializing(PyObject *spec)
return 0;
}
/* Check if the submodule name is in the "_uninitialized_submodules" attribute
of the module spec.
*/
int
_PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name)
{
if (spec == NULL) {
return 0;
}
_Py_IDENTIFIER(_uninitialized_submodules);
PyObject *value = _PyObject_GetAttrId(spec, &PyId__uninitialized_submodules);
if (value == NULL) {
return 0;
}
int is_uninitialized = PySequence_Contains(value, name);
Py_DECREF(value);
if (is_uninitialized == -1) {
return 0;
}
return is_uninitialized;
}
static PyObject*
module_getattro(PyModuleObject *m, PyObject *name)
{
@ -773,6 +797,12 @@ module_getattro(PyModuleObject *m, PyObject *name)
"(most likely due to a circular import)",
mod_name, name);
}
else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
PyErr_Format(PyExc_AttributeError,
"cannot access submodule '%U' of module '%U' "
"(most likely due to a circular import)",
name, mod_name);
}
else {
PyErr_Format(PyExc_AttributeError,
"module '%U' has no attribute '%U'",