summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-07-12 03:50:03 (GMT)
committerGitHub <noreply@github.com>2017-07-12 03:50:03 (GMT)
commit8a9cd20edca7d01b68292036029ae3735ce65edd (patch)
treef4df7b29b7d32eb5a860e325f2114beea561e57b /Lib
parent6d13b22e3ab262c6b1f068259aebd705e7da316c (diff)
downloadcpython-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.py4
-rw-r--r--Lib/test/test_import/__init__.py21
-rw-r--r--Lib/test/test_import/data/package2/submodule1.py3
-rw-r--r--Lib/test/test_import/data/package2/submodule2.py0
-rw-r--r--Lib/test/test_importlib/import_/test___package__.py2
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):