summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_import/__init__.py13
-rw-r--r--Misc/NEWS4
-rw-r--r--Python/ceval.c19
3 files changed, 29 insertions, 7 deletions
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 586478f..14a688d 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -324,6 +324,19 @@ class ImportTests(unittest.TestCase):
with self.assertRaisesRegex(ImportError, "^cannot import name 'bogus'"):
from re import bogus
+ def test_from_import_AttributeError(self):
+ # Issue #24492: trying to import an attribute that raises an
+ # AttributeError should lead to an ImportError.
+ class AlwaysAttributeError:
+ def __getattr__(self, _):
+ raise AttributeError
+
+ module_name = 'test_from_import_AttributeError'
+ self.addCleanup(unload, module_name)
+ sys.modules[module_name] = AlwaysAttributeError()
+ with self.assertRaises(ImportError):
+ from test_from_import_AttributeError import does_not_exist
+
@skip_if_dont_write_bytecode
class FilePermissionTests(unittest.TestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
index 9156c29..27a0564 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -23,6 +23,10 @@ Release date: 2015-08-09
Core and Builtins
-----------------
+- Issue #24492: A "package" lacking a __name__ attribute when trying to perform
+ a ``from .. import ...`` statement will trigger an ImportError instead of an
+ AttributeError.
+
- Issue #24667: Resize odict in all cases that the underlying dict resizes.
Library
diff --git a/Python/ceval.c b/Python/ceval.c
index ac52ad9..8d2cdc2 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5085,19 +5085,24 @@ import_from(PyObject *v, PyObject *name)
sys.modules. */
PyErr_Clear();
pkgname = _PyObject_GetAttrId(v, &PyId___name__);
- if (pkgname == NULL)
- return NULL;
+ if (pkgname == NULL) {
+ goto error;
+ }
fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name);
Py_DECREF(pkgname);
- if (fullmodname == NULL)
+ 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);
+ if (x == NULL) {
+ goto error;
+ }
+ Py_INCREF(x);
return x;
+ error:
+ PyErr_Format(PyExc_ImportError, "cannot import name %R", name);
+ return NULL;
}
static int