Kaydet (Commit) a6ce4fd4 authored tarafından Brett Cannon's avatar Brett Cannon

Closes issue #15111: Calling __import__ with a module specified in

fromlist which causes its own ImportError (e.g. the module tries to
import a non-existent module) should have that exception propagate.
üst 3fa8c590
...@@ -1602,19 +1602,19 @@ def _handle_fromlist(module, fromlist, import_): ...@@ -1602,19 +1602,19 @@ def _handle_fromlist(module, fromlist, import_):
fromlist.extend(module.__all__) fromlist.extend(module.__all__)
for x in fromlist: for x in fromlist:
if not hasattr(module, x): if not hasattr(module, x):
from_name = '{}.{}'.format(module.__name__, x)
try: try:
_call_with_frames_removed(import_, _call_with_frames_removed(import_, from_name)
'{}.{}'.format(module.__name__, x))
except ImportError as exc: except ImportError as exc:
# Backwards-compatibility dictates we ignore failed # Backwards-compatibility dictates we ignore failed
# imports triggered by fromlist for modules that don't # imports triggered by fromlist for modules that don't
# exist. # exist.
# TODO(brett): In Python 3.4, have import raise # TODO(brett): In Python 3.4, have import raise
# ModuleNotFound and catch that. # ModuleNotFound and catch that.
if hasattr(exc, '_not_found') and exc._not_found: if getattr(exc, '_not_found', False):
pass if exc.name == from_name:
else: continue
raise raise
return module return module
......
...@@ -52,7 +52,7 @@ class HandlingFromlist(unittest.TestCase): ...@@ -52,7 +52,7 @@ class HandlingFromlist(unittest.TestCase):
module = import_util.import_('module', fromlist=['attr']) module = import_util.import_('module', fromlist=['attr'])
self.assertEqual(module.__name__, 'module') self.assertEqual(module.__name__, 'module')
def test_unexistent_object(self): def test_nonexistent_object(self):
# [bad object] # [bad object]
with util.mock_modules('module') as importer: with util.mock_modules('module') as importer:
with util.import_state(meta_path=[importer]): with util.import_state(meta_path=[importer]):
...@@ -69,6 +69,19 @@ class HandlingFromlist(unittest.TestCase): ...@@ -69,6 +69,19 @@ class HandlingFromlist(unittest.TestCase):
self.assertTrue(hasattr(module, 'module')) self.assertTrue(hasattr(module, 'module'))
self.assertEqual(module.module.__name__, 'pkg.module') self.assertEqual(module.module.__name__, 'pkg.module')
def test_module_from_package_triggers_ImportError(self):
# If a submodule causes an ImportError because it tries to import
# a module which doesn't exist, that should let the ImportError
# propagate.
def module_code():
import i_do_not_exist
with util.mock_modules('pkg.__init__', 'pkg.mod',
module_code={'pkg.mod': module_code}) as importer:
with util.import_state(meta_path=[importer]):
with self.assertRaises(ImportError) as exc:
import_util.import_('pkg', fromlist=['mod'])
self.assertEquals('i_do_not_exist', exc.exception.name)
def test_empty_string(self): def test_empty_string(self):
with util.mock_modules('pkg.__init__', 'pkg.mod') as importer: with util.mock_modules('pkg.__init__', 'pkg.mod') as importer:
with util.import_state(meta_path=[importer]): with util.import_state(meta_path=[importer]):
......
...@@ -33,6 +33,10 @@ Core and Builtins ...@@ -33,6 +33,10 @@ Core and Builtins
- Issue #15801: Make sure mappings passed to '%' formatting are actually - Issue #15801: Make sure mappings passed to '%' formatting are actually
subscriptable. subscriptable.
- Issue #15111: __import__ should let ImportError propagate when a module that
is imported as a side-effect of using fromlist tries to import a module
that cannot be found.
Library Library
------- -------
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment