diff options
author | Brett Cannon <brett@python.org> | 2012-04-13 01:09:01 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2012-04-13 01:09:01 (GMT) |
commit | bbb6680ee5650ad1096eba0c86286342c3d08468 (patch) | |
tree | 2b17a1b8beb11db23edf34adbc5684fadc829139 /Lib | |
parent | 79ec55e980d7b205bbc78d44e0892d0ef37d3abb (diff) | |
download | cpython-bbb6680ee5650ad1096eba0c86286342c3d08468.zip cpython-bbb6680ee5650ad1096eba0c86286342c3d08468.tar.gz cpython-bbb6680ee5650ad1096eba0c86286342c3d08468.tar.bz2 |
Have importlib take advantage of ImportError's new 'name' and 'path'
attributes.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 42 | ||||
-rw-r--r-- | Lib/importlib/abc.py | 18 | ||||
-rw-r--r-- | Lib/importlib/test/builtin/test_loader.py | 9 | ||||
-rw-r--r-- | Lib/importlib/test/extension/test_loader.py | 6 | ||||
-rw-r--r-- | Lib/importlib/test/frozen/test_loader.py | 6 | ||||
-rw-r--r-- | Lib/importlib/test/import_/test_caching.py | 3 | ||||
-rw-r--r-- | Lib/importlib/test/import_/test_packages.py | 6 | ||||
-rw-r--r-- | Lib/importlib/test/source/test_abc_loader.py | 11 | ||||
-rw-r--r-- | Lib/importlib/test/source/test_file_loader.py | 16 |
9 files changed, 76 insertions, 41 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index d81e949..7bf07eb 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -227,7 +227,7 @@ def _check_name(method): """ def _check_name_wrapper(self, name, *args, **kwargs): if self._name != name: - raise ImportError("loader cannot handle %s" % name) + raise ImportError("loader cannot handle %s" % name, name=name) return method(self, name, *args, **kwargs) _wrap(_check_name_wrapper, method) return _check_name_wrapper @@ -237,7 +237,8 @@ def _requires_builtin(fxn): """Decorator to verify the named module is built-in.""" def _requires_builtin_wrapper(self, fullname): if fullname not in sys.builtin_module_names: - raise ImportError("{0} is not a built-in module".format(fullname)) + raise ImportError("{0} is not a built-in module".format(fullname), + name=fullname) return fxn(self, fullname) _wrap(_requires_builtin_wrapper, fxn) return _requires_builtin_wrapper @@ -247,7 +248,8 @@ def _requires_frozen(fxn): """Decorator to verify the named module is frozen.""" def _requires_frozen_wrapper(self, fullname): if not imp.is_frozen(fullname): - raise ImportError("{0} is not a frozen module".format(fullname)) + raise ImportError("{0} is not a frozen module".format(fullname), + name=fullname) return fxn(self, fullname) _wrap(_requires_frozen_wrapper, fxn) return _requires_frozen_wrapper @@ -372,7 +374,7 @@ class _LoaderBasics: filename = self.get_filename(fullname).rpartition(path_sep)[2] return filename.rsplit('.', 1)[0] == '__init__' - def _bytes_from_bytecode(self, fullname, data, source_stats): + def _bytes_from_bytecode(self, fullname, data, bytecode_path, source_stats): """Return the marshalled bytes from bytecode, verifying the magic number, timestamp and source size along the way. @@ -383,7 +385,8 @@ class _LoaderBasics: raw_timestamp = data[4:8] raw_size = data[8:12] if len(magic) != 4 or magic != imp.get_magic(): - raise ImportError("bad magic number in {}".format(fullname)) + raise ImportError("bad magic number in {}".format(fullname), + name=fullname, path=bytecode_path) elif len(raw_timestamp) != 4: raise EOFError("bad timestamp in {}".format(fullname)) elif len(raw_size) != 4: @@ -396,7 +399,8 @@ class _LoaderBasics: else: if _r_long(raw_timestamp) != source_mtime: raise ImportError( - "bytecode is stale for {}".format(fullname)) + "bytecode is stale for {}".format(fullname), + name=fullname, path=bytecode_path) try: source_size = source_stats['size'] & 0xFFFFFFFF except KeyError: @@ -404,7 +408,8 @@ class _LoaderBasics: else: if _r_long(raw_size) != source_size: raise ImportError( - "bytecode is stale for {}".format(fullname)) + "bytecode is stale for {}".format(fullname), + name=fullname, path=bytecode_path) # Can't return the code object as errors from marshal loading need to # propagate even when source is available. return data[12:] @@ -466,7 +471,8 @@ class SourceLoader(_LoaderBasics): try: source_bytes = self.get_data(path) except IOError: - raise ImportError("source not available through get_data()") + raise ImportError("source not available through get_data()", + name=fullname) encoding = tokenize.detect_encoding(_io.BytesIO(source_bytes).readline) newline_decoder = _io.IncrementalNewlineDecoder(None, True) return newline_decoder.decode(source_bytes.decode(encoding[0])) @@ -495,6 +501,7 @@ class SourceLoader(_LoaderBasics): else: try: bytes_data = self._bytes_from_bytecode(fullname, data, + bytecode_path, st) except (ImportError, EOFError): pass @@ -505,7 +512,8 @@ class SourceLoader(_LoaderBasics): return found else: msg = "Non-code object in {}" - raise ImportError(msg.format(bytecode_path)) + raise ImportError(msg.format(bytecode_path), + name=fullname, path=bytecode_path) source_bytes = self.get_data(source_path) code_object = compile(source_bytes, source_path, 'exec', dont_inherit=True) @@ -604,12 +612,13 @@ class _SourcelessFileLoader(_FileLoader, _LoaderBasics): def get_code(self, fullname): path = self.get_filename(fullname) data = self.get_data(path) - bytes_data = self._bytes_from_bytecode(fullname, data, None) + bytes_data = self._bytes_from_bytecode(fullname, data, path, None) found = marshal.loads(bytes_data) if isinstance(found, code_type): return found else: - raise ImportError("Non-code object in {}".format(path)) + raise ImportError("Non-code object in {}".format(path), + name=fullname, path=path) def get_source(self, fullname): """Return None as there is no source code.""" @@ -678,7 +687,8 @@ class PathFinder: except ImportError: continue else: - raise ImportError("no path hook found for {0}".format(path)) + raise ImportError("no path hook found for {0}".format(path), + path=path) @classmethod def _path_importer_cache(cls, path, default=None): @@ -836,7 +846,7 @@ def _file_path_hook(path): _SourceFinderDetails(), _SourcelessFinderDetails()) else: - raise ImportError("only directories are supported") + raise ImportError("only directories are supported", path=path) _DEFAULT_PATH_HOOK = _file_path_hook @@ -936,10 +946,10 @@ def _find_and_load(name, import_): path = parent_module.__path__ except AttributeError: msg = (_ERR_MSG + '; {} is not a package').format(name, parent) - raise ImportError(msg) + raise ImportError(msg, name=name) loader = _find_module(name, path) if loader is None: - raise ImportError(_ERR_MSG.format(name)) + raise ImportError(_ERR_MSG.format(name), name=name) elif name not in sys.modules: # The parent import may have already imported this module. loader.load_module(name) @@ -978,7 +988,7 @@ def _gcd_import(name, package=None, level=0): if module is None: message = ("import of {} halted; " "None in sys.modules".format(name)) - raise ImportError(message) + raise ImportError(message, name=name) return module except KeyError: pass # Don't want to chain the exception diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 22a7c1a..43e4866 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -207,7 +207,7 @@ class PyLoader(SourceLoader): DeprecationWarning) path = self.source_path(fullname) if path is None: - raise ImportError + raise ImportError(name=fullname) else: return path @@ -235,7 +235,7 @@ class PyPycLoader(PyLoader): if path is not None: return path raise ImportError("no source or bytecode path available for " - "{0!r}".format(fullname)) + "{0!r}".format(fullname), name=fullname) def get_code(self, fullname): """Get a code object from source or bytecode.""" @@ -253,7 +253,8 @@ class PyPycLoader(PyLoader): magic = data[:4] if len(magic) < 4: raise ImportError( - "bad magic number in {}".format(fullname)) + "bad magic number in {}".format(fullname), + name=fullname, path=bytecode_path) raw_timestamp = data[4:8] if len(raw_timestamp) < 4: raise EOFError("bad timestamp in {}".format(fullname)) @@ -262,12 +263,14 @@ class PyPycLoader(PyLoader): # Verify that the magic number is valid. if imp.get_magic() != magic: raise ImportError( - "bad magic number in {}".format(fullname)) + "bad magic number in {}".format(fullname), + name=fullname, path=bytecode_path) # Verify that the bytecode is not stale (only matters when # there is source to fall back on. if source_timestamp: if pyc_timestamp < source_timestamp: - raise ImportError("bytecode is stale") + raise ImportError("bytecode is stale", name=fullname, + path=bytecode_path) except (ImportError, EOFError): # If source is available give it a shot. if source_timestamp is not None: @@ -279,12 +282,13 @@ class PyPycLoader(PyLoader): return marshal.loads(bytecode) elif source_timestamp is None: raise ImportError("no source or bytecode available to create code " - "object for {0!r}".format(fullname)) + "object for {0!r}".format(fullname), + name=fullname) # Use the source. source_path = self.source_path(fullname) if source_path is None: message = "a source path must exist to load {0}".format(fullname) - raise ImportError(message) + raise ImportError(message, name=fullname) source = self.get_data(source_path) code_object = compile(source, source_path, 'exec', dont_inherit=True) # Generate bytecode and write it out. diff --git a/Lib/importlib/test/builtin/test_loader.py b/Lib/importlib/test/builtin/test_loader.py index 1a8539b..ec126c9 100644 --- a/Lib/importlib/test/builtin/test_loader.py +++ b/Lib/importlib/test/builtin/test_loader.py @@ -54,15 +54,17 @@ class LoaderTests(abc.LoaderTests): def test_unloadable(self): name = 'dssdsdfff' assert name not in sys.builtin_module_names - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.load_module(name) + self.assertEqual(cm.exception.name, name) def test_already_imported(self): # Using the name of a module already imported but not a built-in should # still fail. assert hasattr(importlib, '__file__') # Not a built-in. - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.load_module('importlib') + self.assertEqual(cm.exception.name, 'importlib') class InspectLoaderTests(unittest.TestCase): @@ -88,8 +90,9 @@ class InspectLoaderTests(unittest.TestCase): # Modules not built-in should raise ImportError. for meth_name in ('get_code', 'get_source', 'is_package'): method = getattr(machinery.BuiltinImporter, meth_name) - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: method(builtin_util.BAD_NAME) + self.assertRaises(builtin_util.BAD_NAME) diff --git a/Lib/importlib/test/extension/test_loader.py b/Lib/importlib/test/extension/test_loader.py index 4a783db..9e5edad 100644 --- a/Lib/importlib/test/extension/test_loader.py +++ b/Lib/importlib/test/extension/test_loader.py @@ -46,8 +46,10 @@ class LoaderTests(abc.LoaderTests): pass def test_unloadable(self): - with self.assertRaises(ImportError): - self.load_module('asdfjkl;') + name = 'asdfjkl;' + with self.assertRaises(ImportError) as cm: + self.load_module(name) + self.assertEqual(cm.exception.name, name) def test_main(): diff --git a/Lib/importlib/test/frozen/test_loader.py b/Lib/importlib/test/frozen/test_loader.py index b685ef5..91d73fa 100644 --- a/Lib/importlib/test/frozen/test_loader.py +++ b/Lib/importlib/test/frozen/test_loader.py @@ -57,8 +57,9 @@ class LoaderTests(abc.LoaderTests): def test_unloadable(self): assert machinery.FrozenImporter.find_module('_not_real') is None - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: machinery.FrozenImporter.load_module('_not_real') + self.assertEqual(cm.exception.name, '_not_real') class InspectLoaderTests(unittest.TestCase): @@ -92,8 +93,9 @@ class InspectLoaderTests(unittest.TestCase): # Raise ImportError for modules that are not frozen. for meth_name in ('get_code', 'get_source', 'is_package'): method = getattr(machinery.FrozenImporter, meth_name) - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: method('importlib') + self.assertEqual(cm.exception.name, 'importlib') def test_main(): diff --git a/Lib/importlib/test/import_/test_caching.py b/Lib/importlib/test/import_/test_caching.py index 48dc643..3baff55 100644 --- a/Lib/importlib/test/import_/test_caching.py +++ b/Lib/importlib/test/import_/test_caching.py @@ -34,8 +34,9 @@ class UseCache(unittest.TestCase): name = 'using_None' with util.uncache(name): sys.modules[name] = None - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: import_util.import_(name) + self.assertEqual(cm.exception.name, name) def create_mock(self, *names, return_=None): mock = util.mock_modules(*names) diff --git a/Lib/importlib/test/import_/test_packages.py b/Lib/importlib/test/import_/test_packages.py index 58be433..e756ee4 100644 --- a/Lib/importlib/test/import_/test_packages.py +++ b/Lib/importlib/test/import_/test_packages.py @@ -19,14 +19,16 @@ class ParentModuleTests(unittest.TestCase): def test_bad_parent(self): with util.mock_modules('pkg.module') as mock: with util.import_state(meta_path=[mock]): - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: import_util.import_('pkg.module') + self.assertEqual(cm.exception.name, 'pkg') def test_module_not_package(self): # Try to import a submodule from a non-package should raise ImportError. assert not hasattr(sys, '__path__') - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: import_util.import_('sys.no_submodules_here') + self.assertEqual(cm.exception.name, 'sys.no_submodules_here') def test_module_not_package_but_side_effects(self): # If a module injects something into sys.modules as a side-effect, then diff --git a/Lib/importlib/test/source/test_abc_loader.py b/Lib/importlib/test/source/test_abc_loader.py index 01acda4..b1b1204 100644 --- a/Lib/importlib/test/source/test_abc_loader.py +++ b/Lib/importlib/test/source/test_abc_loader.py @@ -471,8 +471,9 @@ class BadBytecodeFailureTests(unittest.TestCase): {'path': os.path.join('path', 'to', 'mod'), 'magic': bad_magic}} mock = PyPycLoaderMock({name: None}, bc) - with util.uncache(name), self.assertRaises(ImportError): + with util.uncache(name), self.assertRaises(ImportError) as cm: mock.load_module(name) + self.assertEqual(cm.exception.name, name) def test_no_bytecode(self): # Missing code object bytecode should lead to an EOFError. @@ -516,8 +517,9 @@ class MissingPathsTests(unittest.TestCase): # If all *_path methods return None, raise ImportError. name = 'mod' mock = PyPycLoaderMock({name: None}) - with util.uncache(name), self.assertRaises(ImportError): + with util.uncache(name), self.assertRaises(ImportError) as cm: mock.load_module(name) + self.assertEqual(cm.exception.name, name) def test_source_path_ImportError(self): # An ImportError from source_path should trigger an ImportError. @@ -533,7 +535,7 @@ class MissingPathsTests(unittest.TestCase): mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) bad_meth = types.MethodType(raise_ImportError, mock) mock.bytecode_path = bad_meth - with util.uncache(name), self.assertRaises(ImportError): + with util.uncache(name), self.assertRaises(ImportError) as cm: mock.load_module(name) @@ -594,8 +596,9 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness): def raise_IOError(path): raise IOError self.loader.get_data = raise_IOError - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.loader.get_source(self.name) + self.assertEqual(cm.exception.name, self.name) def test_is_package(self): # Properly detect when loading a package. diff --git a/Lib/importlib/test/source/test_file_loader.py b/Lib/importlib/test/source/test_file_loader.py index 21e718f..cb1c317 100644 --- a/Lib/importlib/test/source/test_file_loader.py +++ b/Lib/importlib/test/source/test_file_loader.py @@ -232,8 +232,10 @@ class BadBytecodeTest(unittest.TestCase): lambda bc: bc[:12] + marshal.dumps(b'abcd'), del_source=del_source) file_path = mapping['_temp'] if not del_source else bytecode_path - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(file_path, '_temp') + self.assertEqual(cm.exception.name, '_temp') + self.assertEqual(cm.exception.path, bytecode_path) def _test_bad_marshal(self, *, del_source=False): with source_util.create_modules('_temp') as mapping: @@ -381,15 +383,19 @@ class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): def test_empty_file(self): def test(name, mapping, bytecode_path): - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(bytecode_path, name) + self.assertEqual(cm.exception.name, name) + self.assertEqual(cm.exception.path, bytecode_path) self._test_empty_file(test, del_source=True) def test_partial_magic(self): def test(name, mapping, bytecode_path): - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(bytecode_path, name) + self.assertEqual(cm.exception.name, name) + self.assertEqual(cm.exception.path, bytecode_path) self._test_partial_magic(test, del_source=True) def test_magic_only(self): @@ -401,8 +407,10 @@ class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): def test_bad_magic(self): def test(name, mapping, bytecode_path): - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(bytecode_path, name) + self.assertEqual(cm.exception.name, name) + self.assertEqual(cm.exception.path, bytecode_path) self._test_bad_magic(test, del_source=True) |