diff options
author | Filipe Laíns <lains@riseup.net> | 2021-07-24 09:50:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-24 09:50:17 (GMT) |
commit | 8072a1181dd64135f700b44372fbf7bf91e68072 (patch) | |
tree | 23ba5f22841e1f5a739d6d6d54ee0f29e094f997 /Objects | |
parent | 5370f0a82aaa4ba617070d5c71d2b18236096ac0 (diff) | |
download | cpython-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.c | 30 |
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'", |