diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-07-12 03:50:03 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-12 03:50:03 (GMT) |
commit | 8a9cd20edca7d01b68292036029ae3735ce65edd (patch) | |
tree | f4df7b29b7d32eb5a860e325f2114beea561e57b /Lib | |
parent | 6d13b22e3ab262c6b1f068259aebd705e7da316c (diff) | |
download | cpython-8a9cd20edca7d01b68292036029ae3735ce65edd.zip cpython-8a9cd20edca7d01b68292036029ae3735ce65edd.tar.gz cpython-8a9cd20edca7d01b68292036029ae3735ce65edd.tar.bz2 |
bpo-30876: Relative import from unloaded package now reimports the package (#2639)
instead of failing with SystemError.
Relative import from non-package now fails with ImportError rather than
SystemError.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 4 | ||||
-rw-r--r-- | Lib/test/test_import/__init__.py | 21 | ||||
-rw-r--r-- | Lib/test/test_import/data/package2/submodule1.py | 3 | ||||
-rw-r--r-- | Lib/test/test_import/data/package2/submodule2.py | 0 | ||||
-rw-r--r-- | Lib/test/test_importlib/import_/test___package__.py | 2 |
5 files changed, 22 insertions, 8 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 21e8c4b..a269eee 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -919,10 +919,6 @@ def _sanity_check(name, package, level): elif not package: raise ImportError('attempted relative import with no known parent ' 'package') - elif package not in sys.modules: - msg = ('Parent module {!r} not loaded, cannot perform relative ' - 'import') - raise SystemError(msg.format(package)) if not name and level == 0: raise ValueError('Empty module name') diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 8424ed7..1b04de2 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -23,8 +23,9 @@ from test.support import ( EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython, make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask, unlink, unload, create_empty_file, cpython_only, TESTFN_UNENCODABLE, - temp_dir) + temp_dir, DirsOnSysPath) from test.support import script_helper +from test.test_importlib.util import uncache skip_if_dont_write_bytecode = unittest.skipIf( @@ -670,11 +671,11 @@ class RelativeImportTests(unittest.TestCase): # Check relative import fails with only __package__ wrong ns = dict(__package__='foo', __name__='test.notarealmodule') - self.assertRaises(SystemError, check_relative) + self.assertRaises(ModuleNotFoundError, check_relative) # Check relative import fails with __package__ and __name__ wrong ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule') - self.assertRaises(SystemError, check_relative) + self.assertRaises(ModuleNotFoundError, check_relative) # Check relative import fails with package set to a non-string ns = dict(__package__=object()) @@ -689,6 +690,20 @@ class RelativeImportTests(unittest.TestCase): self.fail("explicit relative import triggered an " "implicit absolute import") + def test_import_from_non_package(self): + path = os.path.join(os.path.dirname(__file__), 'data', 'package2') + with uncache('submodule1', 'submodule2'), DirsOnSysPath(path): + with self.assertRaises(ImportError): + import submodule1 + self.assertNotIn('submodule1', sys.modules) + self.assertNotIn('submodule2', sys.modules) + + def test_import_from_unloaded_package(self): + with uncache('package2', 'package2.submodule1', 'package2.submodule2'), \ + DirsOnSysPath(os.path.join(os.path.dirname(__file__), 'data')): + import package2.submodule1 + package2.submodule1.submodule2 + class OverridingImportBuiltinTests(unittest.TestCase): def test_override_builtin(self): diff --git a/Lib/test/test_import/data/package2/submodule1.py b/Lib/test/test_import/data/package2/submodule1.py new file mode 100644 index 0000000..0698ed6 --- /dev/null +++ b/Lib/test/test_import/data/package2/submodule1.py @@ -0,0 +1,3 @@ +import sys +sys.modules.pop(__package__, None) +from . import submodule2 diff --git a/Lib/test/test_import/data/package2/submodule2.py b/Lib/test/test_import/data/package2/submodule2.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Lib/test/test_import/data/package2/submodule2.py diff --git a/Lib/test/test_importlib/import_/test___package__.py b/Lib/test/test_importlib/import_/test___package__.py index 7f64548..b26634e 100644 --- a/Lib/test/test_importlib/import_/test___package__.py +++ b/Lib/test/test_importlib/import_/test___package__.py @@ -81,7 +81,7 @@ class Using__package__: def test_bad__package__(self): globals = {'__package__': '<not real>'} - with self.assertRaises(SystemError): + with self.assertRaises(ModuleNotFoundError): self.__import__('', globals, {}, ['relimport'], 1) def test_bunk__package__(self): |