summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-05-07 19:41:59 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2012-05-07 19:41:59 (GMT)
commit6efa50a384f61155cd5315cd32f0f8775fe124c5 (patch)
tree2cc831c060e953beb452ec4b33e199e2c06f25d9 /Lib
parent943cab2fec8e7fb3232e72d9f1ca6535674e746a (diff)
downloadcpython-6efa50a384f61155cd5315cd32f0f8775fe124c5.zip
cpython-6efa50a384f61155cd5315cd32f0f8775fe124c5.tar.gz
cpython-6efa50a384f61155cd5315cd32f0f8775fe124c5.tar.bz2
Issue #14583: Fix importlib bug when a package's __init__.py would first import one of its modules then raise an error.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/importlib/_bootstrap.py2
-rw-r--r--Lib/importlib/test/import_/test_packages.py56
-rw-r--r--Lib/importlib/test/util.py6
3 files changed, 62 insertions, 2 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 1e6a05a..9952b06 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -1082,7 +1082,7 @@ def __import__(name, globals={}, locals={}, fromlist=[], level=0):
# Return up to the first dot in 'name'. This is complicated by the fact
# that 'name' may be relative.
if level == 0:
- return sys.modules[name.partition('.')[0]]
+ return _gcd_import(name.partition('.')[0])
elif not name:
return module
else:
diff --git a/Lib/importlib/test/import_/test_packages.py b/Lib/importlib/test/import_/test_packages.py
index e756ee4..931494d 100644
--- a/Lib/importlib/test/import_/test_packages.py
+++ b/Lib/importlib/test/import_/test_packages.py
@@ -23,6 +23,62 @@ class ParentModuleTests(unittest.TestCase):
import_util.import_('pkg.module')
self.assertEqual(cm.exception.name, 'pkg')
+ def test_raising_parent_after_importing_child(self):
+ def __init__():
+ import pkg.module
+ 1/0
+ mock = util.mock_modules('pkg.__init__', 'pkg.module',
+ module_code={'pkg': __init__})
+ with mock:
+ with util.import_state(meta_path=[mock]):
+ with self.assertRaises(ZeroDivisionError):
+ import_util.import_('pkg')
+ self.assertFalse('pkg' in sys.modules)
+ self.assertTrue('pkg.module' in sys.modules)
+ with self.assertRaises(ZeroDivisionError):
+ import_util.import_('pkg.module')
+ self.assertFalse('pkg' in sys.modules)
+ self.assertTrue('pkg.module' in sys.modules)
+
+ def test_raising_parent_after_relative_importing_child(self):
+ def __init__():
+ from . import module
+ 1/0
+ mock = util.mock_modules('pkg.__init__', 'pkg.module',
+ module_code={'pkg': __init__})
+ with mock:
+ with util.import_state(meta_path=[mock]):
+ with self.assertRaises((ZeroDivisionError, ImportError)):
+ # This raises ImportError on the "from . import module"
+ # line, not sure why.
+ import_util.import_('pkg')
+ self.assertFalse('pkg' in sys.modules)
+ with self.assertRaises((ZeroDivisionError, ImportError)):
+ import_util.import_('pkg.module')
+ self.assertFalse('pkg' in sys.modules)
+ # XXX False
+ #self.assertTrue('pkg.module' in sys.modules)
+
+ def test_raising_parent_after_double_relative_importing_child(self):
+ def __init__():
+ from ..subpkg import module
+ 1/0
+ mock = util.mock_modules('pkg.__init__', 'pkg.subpkg.__init__',
+ 'pkg.subpkg.module',
+ module_code={'pkg.subpkg': __init__})
+ with mock:
+ with util.import_state(meta_path=[mock]):
+ with self.assertRaises((ZeroDivisionError, ImportError)):
+ # This raises ImportError on the "from ..subpkg import module"
+ # line, not sure why.
+ import_util.import_('pkg.subpkg')
+ self.assertFalse('pkg.subpkg' in sys.modules)
+ with self.assertRaises((ZeroDivisionError, ImportError)):
+ import_util.import_('pkg.subpkg.module')
+ self.assertFalse('pkg.subpkg' in sys.modules)
+ # XXX False
+ #self.assertTrue('pkg.subpkg.module' in sys.modules)
+
def test_module_not_package(self):
# Try to import a submodule from a non-package should raise ImportError.
assert not hasattr(sys, '__path__')
diff --git a/Lib/importlib/test/util.py b/Lib/importlib/test/util.py
index 7ba7a97..ef32f7d 100644
--- a/Lib/importlib/test/util.py
+++ b/Lib/importlib/test/util.py
@@ -124,7 +124,11 @@ class mock_modules:
else:
sys.modules[fullname] = self.modules[fullname]
if fullname in self.module_code:
- self.module_code[fullname]()
+ try:
+ self.module_code[fullname]()
+ except Exception:
+ del sys.modules[fullname]
+ raise
return self.modules[fullname]
def __enter__(self):