diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2014-10-13 18:19:45 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2014-10-13 18:19:45 (GMT) |
commit | 0373a106a1ca9ce67cd99bf0a93ab7c3abd15cb6 (patch) | |
tree | 40f497501c02e44276169e02db55c0ef2df30159 /Python/ceval.c | |
parent | dfbeb160de829d16d3668dec5bc902a31ad25835 (diff) | |
download | cpython-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.c | 22 |
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; } |