diff options
author | Brett Cannon <brett@python.org> | 2013-06-12 20:59:46 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2013-06-12 20:59:46 (GMT) |
commit | b1611e2772af2c6eb73a6b3d04b3dbb43308fa6c (patch) | |
tree | 7cd26cc5f09f341a69572c40f16638053ae86d08 /Lib/test | |
parent | 638ce0779b4dceea39c2f77346aeab9824e48548 (diff) | |
download | cpython-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.txt | 1 | ||||
-rw-r--r-- | Lib/test/test_exceptions.py | 3 | ||||
-rw-r--r-- | Lib/test/test_import.py | 25 | ||||
-rw-r--r-- | Lib/test/test_importlib/import_/test_api.py | 4 | ||||
-rw-r--r-- | Lib/test/test_importlib/import_/test_fromlist.py | 8 | ||||
-rw-r--r-- | Lib/test/test_pydoc.py | 2 | ||||
-rw-r--r-- | Lib/test/test_site.py | 2 |
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(' ', ' ') 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") |