summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2014-10-13 18:19:45 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2014-10-13 18:19:45 (GMT)
commit0373a106a1ca9ce67cd99bf0a93ab7c3abd15cb6 (patch)
tree40f497501c02e44276169e02db55c0ef2df30159 /Python/ceval.c
parentdfbeb160de829d16d3668dec5bc902a31ad25835 (diff)
downloadcpython-0373a106a1ca9ce67cd99bf0a93ab7c3abd15cb6.zip
cpython-0373a106a1ca9ce67cd99bf0a93ab7c3abd15cb6.tar.gz
cpython-0373a106a1ca9ce67cd99bf0a93ab7c3abd15cb6.tar.bz2
Issue #17636: Circular imports involving relative imports are now supported.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 2dbf591..4b1d6ca 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4693,11 +4693,29 @@ static PyObject *
import_from(PyObject *v, PyObject *name)
{
PyObject *x;
+ _Py_IDENTIFIER(__name__);
+ PyObject *fullmodname, *pkgname;
x = PyObject_GetAttr(v, name);
- if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
+ return x;
+ /* Issue #17636: in case this failed because of a circular relative
+ import, try to fallback on reading the module directly from
+ sys.modules. */
+ PyErr_Clear();
+ pkgname = _PyObject_GetAttrId(v, &PyId___name__);
+ if (pkgname == NULL)
+ return NULL;
+ fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name);
+ Py_DECREF(pkgname);
+ if (fullmodname == NULL)
+ return NULL;
+ x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname);
+ if (x == NULL)
PyErr_Format(PyExc_ImportError, "cannot import name %R", name);
- }
+ else
+ Py_INCREF(x);
+ Py_DECREF(fullmodname);
return x;
}