summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorFilipe Laíns <lains@riseup.net>2021-07-24 09:50:17 (GMT)
committerGitHub <noreply@github.com>2021-07-24 09:50:17 (GMT)
commit8072a1181dd64135f700b44372fbf7bf91e68072 (patch)
tree23ba5f22841e1f5a739d6d6d54ee0f29e094f997 /Objects
parent5370f0a82aaa4ba617070d5c71d2b18236096ac0 (diff)
downloadcpython-8072a1181dd64135f700b44372fbf7bf91e68072.zip
cpython-8072a1181dd64135f700b44372fbf7bf91e68072.tar.gz
cpython-8072a1181dd64135f700b44372fbf7bf91e68072.tar.bz2
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>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/moduleobject.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index ef39bde..1c37eb0 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -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'",