Merged in brettcannon/cpython350/3.5 (pull request #2)

Issue #24492: make sure that ``from ... import ...` raises an ImportError if __name__ is not defined on a package.
This commit is contained in:
larry 2015-08-11 18:59:15 -07:00
commit 6707906ea5
3 changed files with 29 additions and 7 deletions

View File

@ -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):

View File

@ -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

View File

@ -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