diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2012-05-07 19:41:59 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2012-05-07 19:41:59 (GMT) |
commit | 6efa50a384f61155cd5315cd32f0f8775fe124c5 (patch) | |
tree | 2cc831c060e953beb452ec4b33e199e2c06f25d9 /Lib | |
parent | 943cab2fec8e7fb3232e72d9f1ca6535674e746a (diff) | |
download | cpython-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.py | 2 | ||||
-rw-r--r-- | Lib/importlib/test/import_/test_packages.py | 56 | ||||
-rw-r--r-- | Lib/importlib/test/util.py | 6 |
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): |