summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2013-06-12 20:59:46 (GMT)
committerBrett Cannon <brett@python.org>2013-06-12 20:59:46 (GMT)
commitb1611e2772af2c6eb73a6b3d04b3dbb43308fa6c (patch)
tree7cd26cc5f09f341a69572c40f16638053ae86d08 /Lib/test
parent638ce0779b4dceea39c2f77346aeab9824e48548 (diff)
downloadcpython-b1611e2772af2c6eb73a6b3d04b3dbb43308fa6c.zip
cpython-b1611e2772af2c6eb73a6b3d04b3dbb43308fa6c.tar.gz
cpython-b1611e2772af2c6eb73a6b3d04b3dbb43308fa6c.tar.bz2
Issue #15767: Introduce ModuleNotFoundError, a subclass of
ImportError. The exception is raised by import when a module could not be found. Technically this is defined as no viable loader could be found for the specified module. This includes ``from ... import`` statements so that the module usage is consistent for all situations where import couldn't find what was requested. This should allow for the common idiom of:: try: import something except ImportError: pass to be updated to using ModuleNotFoundError and not accidentally mask ImportError messages that should propagate (e.g. issues with a loader). This work was driven by the fact that the ``from ... import`` statement needed to be able to tell the difference between an ImportError that simply couldn't find a module (and thus silence the exception so that ceval can raise it) and an ImportError that represented an actual problem.
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/exception_hierarchy.txt1
-rw-r--r--Lib/test/test_exceptions.py3
-rw-r--r--Lib/test/test_import.py25
-rw-r--r--Lib/test/test_importlib/import_/test_api.py4
-rw-r--r--Lib/test/test_importlib/import_/test_fromlist.py8
-rw-r--r--Lib/test/test_pydoc.py2
-rw-r--r--Lib/test/test_site.py2
7 files changed, 22 insertions, 23 deletions
diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt
index 1c1f69f..88e1b81 100644
--- a/Lib/test/exception_hierarchy.txt
+++ b/Lib/test/exception_hierarchy.txt
@@ -13,6 +13,7 @@ BaseException
+-- BufferError
+-- EOFError
+-- ImportError
+ +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 2f39d4b..f0851bd 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -953,8 +953,5 @@ class ImportErrorTests(unittest.TestCase):
self.assertEqual(str(arg), str(exc))
-def test_main():
- run_unittest(ExceptionTests, ImportErrorTests)
-
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index 9c14e15..805e9ed 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -68,7 +68,15 @@ class ImportTests(unittest.TestCase):
def tearDown(self):
unload(TESTFN)
- setUp = tearDown
+ def test_import_raises_ModuleNotFoundError(self):
+ with self.assertRaises(ModuleNotFoundError):
+ import something_that_should_not_exist_anywhere
+
+ def test_from_import_raises_ModuleNotFoundError(self):
+ with self.assertRaises(ModuleNotFoundError):
+ from something_that_should_not_exist_anywhere import blah
+ with self.assertRaises(ModuleNotFoundError):
+ from importlib import something_that_should_not_exist_anywhere
def test_case_sensitivity(self):
# Brief digression to test that import is case-sensitive: if we got
@@ -487,7 +495,7 @@ func_filename = func.__code__.co_filename
header = f.read(12)
code = marshal.load(f)
constants = list(code.co_consts)
- foreign_code = test_main.__code__
+ foreign_code = importlib.import_module.__code__
pos = constants.index(1)
constants[pos] = foreign_code
code = type(code)(code.co_argcount, code.co_kwonlyargcount,
@@ -1014,16 +1022,5 @@ class ImportTracebackTests(unittest.TestCase):
importlib.SourceLoader.load_module = old_load_module
-def test_main(verbose=None):
- run_unittest(ImportTests, PycacheTests, FilePermissionTests,
- PycRewritingTests, PathsTests, RelativeImportTests,
- OverridingImportBuiltinTests,
- ImportlibBootstrapTests,
- TestSymbolicallyLinkedPackage,
- ImportTracebackTests)
-
-
if __name__ == '__main__':
- # Test needs to be a package, so we can do relative imports.
- from test.test_import import test_main
- test_main()
+ unittest.main()
diff --git a/Lib/test/test_importlib/import_/test_api.py b/Lib/test/test_importlib/import_/test_api.py
index 3d4cd94..6aca6dc 100644
--- a/Lib/test/test_importlib/import_/test_api.py
+++ b/Lib/test/test_importlib/import_/test_api.py
@@ -22,6 +22,10 @@ class APITest(unittest.TestCase):
"""Test API-specific details for __import__ (e.g. raising the right
exception when passing in an int for the module name)."""
+ def test_raises_ModuleNotFoundError(self):
+ with self.assertRaises(ModuleNotFoundError):
+ util.import_('some module that does not exist')
+
def test_name_requires_rparition(self):
# Raise TypeError if a non-string is passed in for the module name.
with self.assertRaises(TypeError):
diff --git a/Lib/test/test_importlib/import_/test_fromlist.py b/Lib/test/test_importlib/import_/test_fromlist.py
index c16c337..9aa27a0 100644
--- a/Lib/test/test_importlib/import_/test_fromlist.py
+++ b/Lib/test/test_importlib/import_/test_fromlist.py
@@ -69,16 +69,16 @@ class HandlingFromlist(unittest.TestCase):
self.assertTrue(hasattr(module, 'module'))
self.assertEqual(module.module.__name__, 'pkg.module')
- def test_module_from_package_triggers_ImportError(self):
- # If a submodule causes an ImportError because it tries to import
- # a module which doesn't exist, that should let the ImportError
+ def test_module_from_package_triggers_ModuleNotFoundError(self):
+ # If a submodule causes an ModuleNotFoundError because it tries to import
+ # a module which doesn't exist, that should let the ModuleNotFoundError
# propagate.
def module_code():
import i_do_not_exist
with util.mock_modules('pkg.__init__', 'pkg.mod',
module_code={'pkg.mod': module_code}) as importer:
with util.import_state(meta_path=[importer]):
- with self.assertRaises(ImportError) as exc:
+ with self.assertRaises(ModuleNotFoundError) as exc:
import_util.import_('pkg', fromlist=['mod'])
self.assertEqual('i_do_not_exist', exc.exception.name)
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 399f818..95ef115 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -206,7 +206,7 @@ expected_html_data_docstrings = tuple(s.replace(' ', '&nbsp;')
missing_pattern = "no Python documentation found for '%s'"
# output pattern for module with bad imports
-badimport_pattern = "problem in %s - ImportError: No module named %r"
+badimport_pattern = "problem in %s - ModuleNotFoundError: No module named %r"
def run_pydoc(module_name, *args, **env):
"""
diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
index 9c7840f..06d7bd7 100644
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -131,7 +131,7 @@ class HelperFunctionsTests(unittest.TestCase):
re.escape(os.path.join(pth_dir, pth_fn)))
# XXX: ditto previous XXX comment.
self.assertRegex(err_out.getvalue(), 'Traceback')
- self.assertRegex(err_out.getvalue(), 'ImportError')
+ self.assertRegex(err_out.getvalue(), 'ModuleNotFoundError')
@unittest.skipIf(sys.platform == "win32", "Windows does not raise an "
"error for file paths containing null characters")