Skip to content

Commit 9407d50

Browse files
committed
Merge fix for issue #15111.
2 parents b36a050 + a6ce4fd commit 9407d50

File tree

4 files changed

+487
-467
lines changed

4 files changed

+487
-467
lines changed

Lib/importlib/_bootstrap.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1602,19 +1602,19 @@ def _handle_fromlist(module, fromlist, import_):
16021602
fromlist.extend(module.__all__)
16031603
for x in fromlist:
16041604
if not hasattr(module, x):
1605+
from_name = '{}.{}'.format(module.__name__, x)
16051606
try:
1606-
_call_with_frames_removed(import_,
1607-
'{}.{}'.format(module.__name__, x))
1607+
_call_with_frames_removed(import_, from_name)
16081608
except ImportError as exc:
16091609
# Backwards-compatibility dictates we ignore failed
16101610
# imports triggered by fromlist for modules that don't
16111611
# exist.
16121612
# TODO(brett): In Python 3.4, have import raise
16131613
# ModuleNotFound and catch that.
1614-
if hasattr(exc, '_not_found') and exc._not_found:
1615-
pass
1616-
else:
1617-
raise
1614+
if getattr(exc, '_not_found', False):
1615+
if exc.name == from_name:
1616+
continue
1617+
raise
16181618
return module
16191619

16201620

Lib/test/test_importlib/import_/test_fromlist.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_object(self):
5252
module = import_util.import_('module', fromlist=['attr'])
5353
self.assertEqual(module.__name__, 'module')
5454

55-
def test_unexistent_object(self):
55+
def test_nonexistent_object(self):
5656
# [bad object]
5757
with util.mock_modules('module') as importer:
5858
with util.import_state(meta_path=[importer]):
@@ -69,6 +69,19 @@ def test_module_from_package(self):
6969
self.assertTrue(hasattr(module, 'module'))
7070
self.assertEqual(module.module.__name__, 'pkg.module')
7171

72+
def test_module_from_package_triggers_ImportError(self):
73+
# If a submodule causes an ImportError because it tries to import
74+
# a module which doesn't exist, that should let the ImportError
75+
# propagate.
76+
def module_code():
77+
import i_do_not_exist
78+
with util.mock_modules('pkg.__init__', 'pkg.mod',
79+
module_code={'pkg.mod': module_code}) as importer:
80+
with util.import_state(meta_path=[importer]):
81+
with self.assertRaises(ImportError) as exc:
82+
import_util.import_('pkg', fromlist=['mod'])
83+
self.assertEquals('i_do_not_exist', exc.exception.name)
84+
7285
def test_empty_string(self):
7386
with util.mock_modules('pkg.__init__', 'pkg.mod') as importer:
7487
with util.import_state(meta_path=[importer]):

Misc/NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ Core and Builtins
3939
- Issue #15801: Make sure mappings passed to '%' formatting are actually
4040
subscriptable.
4141

42+
- Issue #15111: __import__ should propagate ImportError when raised as a
43+
side-effect of a module triggered from using fromlist.
44+
4245
Library
4346
-------
4447

0 commit comments

Comments
 (0)