diff options
Diffstat (limited to 'astroid')
-rw-r--r-- | astroid/builder.py | 28 | ||||
-rw-r--r-- | astroid/exceptions.py | 10 | ||||
-rw-r--r-- | astroid/inference.py | 24 | ||||
-rw-r--r-- | astroid/manager.py | 12 | ||||
-rw-r--r-- | astroid/mixins.py | 20 | ||||
-rw-r--r-- | astroid/tests/testdata/python2/data/invalid_encoding.py | 1 | ||||
-rw-r--r-- | astroid/tests/testdata/python3/data/invalid_encoding.py | 1 | ||||
-rw-r--r-- | astroid/tests/unittest_builder.py | 8 |
8 files changed, 55 insertions, 49 deletions
diff --git a/astroid/builder.py b/astroid/builder.py index 9e06ef7..089cdd0 100644 --- a/astroid/builder.py +++ b/astroid/builder.py @@ -47,13 +47,7 @@ if sys.version_info >= (3, 0): with open(filename, 'rb') as byte_stream: encoding = detect_encoding(byte_stream.readline)[0] stream = open(filename, 'r', newline=None, encoding=encoding) - try: - data = stream.read() - except UnicodeError: # wrong encoding - # detect_encoding returns utf-8 if no encoding specified - util.reraise(exceptions.AstroidBuildingException( - 'Wrong ({encoding}) or no encoding specified for {filename}.', - encoding=encoding, filename=filename)) + data = stream.read() return stream, encoding, data else: @@ -128,9 +122,14 @@ class AstroidBuilder(raw_building.InspectBuilder): 'Unable to load file {path}:\n{error}', modname=modname, path=path, error=exc)) except (SyntaxError, LookupError) as exc: - util.reraise(exceptions.AstroidBuildingException( + util.reraise(exceptions.AstroidSyntaxError( 'Python 3 encoding specification error or unknown encoding:\n' '{error}', modname=modname, path=path, error=exc)) + except UnicodeError: # wrong encoding + # detect_encoding returns utf-8 if no encoding specified + util.reraise(exceptions.AstroidBuildingException( + 'Wrong ({encoding}) or no encoding specified for {filename}.', + encoding=encoding, filename=filename)) with stream: # get module name if necessary if modname is None: @@ -171,17 +170,10 @@ class AstroidBuilder(raw_building.InspectBuilder): """Build tree node from data and add some informations""" try: node = _parse(data + '\n') - except (TypeError, ValueError) as exc: - util.reraise(exceptions.AstroidBuildingException( + except (TypeError, ValueError, SyntaxError) as exc: + util.reraise(exceptions.AstroidSyntaxError( 'Parsing Python code failed:\n{error}', source=data, modname=modname, path=path, error=exc)) - except SyntaxError as exc: - # Pass the entire exception object to AstroidBuildingException, - # since pylint uses this as an introspection method, - # in order to find what error happened. - util.reraise(exceptions.AstroidBuildingException( - 'Syntax error in Python source: {error}', - source=data, modname=modname, path=path, error=exc)) if path is not None: node_file = os.path.abspath(path) else: @@ -210,7 +202,7 @@ class AstroidBuilder(raw_building.InspectBuilder): if name == '*': try: imported = node.do_import_module() - except exceptions.InferenceError: + except exceptions.AstroidBuildingException: continue for name in imported.wildcard_import_names(): node.parent.set_local(name, node) diff --git a/astroid/exceptions.py b/astroid/exceptions.py index e92abc5..3437a1f 100644 --- a/astroid/exceptions.py +++ b/astroid/exceptions.py @@ -54,6 +54,14 @@ class AstroidBuildingException(AstroidError): super(AstroidBuildingException, self).__init__(message, **kws) +class AstroidImportError(AstroidBuildingException): + """Exception class used when a module can't be imported by astroid.""" + + +class AstroidSyntaxError(AstroidBuildingException): + """Exception class used when a module can't be parsed.""" + + class NoDefault(AstroidError): """raised by function's `default_value` method when an argument has no default value @@ -96,9 +104,11 @@ class MroError(ResolveError): for m in self.mros) return self.message.format(mros=mro_names, cls=self.cls) + class DuplicateBasesError(MroError): """Error raised when there are duplicate bases in the same class bases.""" + class InconsistentMroError(MroError): """Error raised when a class's MRO is inconsistent.""" diff --git a/astroid/inference.py b/astroid/inference.py index 45f31ff..7b2aa6b 100644 --- a/astroid/inference.py +++ b/astroid/inference.py @@ -130,10 +130,16 @@ def infer_import(self, context=None, asname=True): name = context.lookupname if name is None: raise exceptions.InferenceError(node=self, context=context) - if asname: - yield self.do_import_module(self.real_name(name)) - else: - yield self.do_import_module(name) + + try: + if asname: + yield self.do_import_module(self.real_name(name)) + else: + yield self.do_import_module(name) + except exceptions.AstroidBuildingException as exc: + util.reraise(exceptions.InferenceError(node=self, error=exc, + context=context)) + nodes.Import._infer = infer_import @@ -152,7 +158,13 @@ def infer_import_from(self, context=None, asname=True): raise exceptions.InferenceError(node=self, context=context) if asname: name = self.real_name(name) - module = self.do_import_module() + + try: + module = self.do_import_module() + except exceptions.AstroidBuildingException as exc: + util.reraise(exceptions.InferenceError(node=self, error=exc, + context=context)) + try: context = contextmod.copy_context(context) context.lookupname = name @@ -277,7 +289,7 @@ def infer_subscript(self, context=None): except (IndexError, TypeError, AttributeError) as exc: util.reraise(exceptions.InferenceError(node=self, error=exc, context=context)) - + # Prevent inferring if the inferred subscript # is the same as the original subscripted object. if self is assigned or assigned is util.Uninferable: diff --git a/astroid/manager.py b/astroid/manager.py index 55a09be..f2aa9d2 100644 --- a/astroid/manager.py +++ b/astroid/manager.py @@ -127,16 +127,16 @@ class AstroidManager(object): try: module = modutils.load_module_from_name(modname) except Exception as ex: # pylint: disable=broad-except - util.reraise(exceptions.AstroidBuildingException( + util.reraise(exceptions.AstroidImportError( 'Loading {modname} failed with:\n{error}', modname=modname, path=filepath, error=ex)) return self.ast_from_module(module, modname) elif mp_type == imp.PY_COMPILED: - raise exceptions.AstroidBuildingException( + raise exceptions.AstroidImportError( "Unable to load compiled module {modname}.", modname=modname, path=filepath) if filepath is None: - raise exceptions.AstroidBuildingException( + raise exceptions.AstroidImportError( "Can't find a file for module {modname}.", modname=modname) return self.ast_from_file(filepath, modname, fallback=False) @@ -182,7 +182,7 @@ class AstroidManager(object): modname.split('.'), context_file=contextfile) traceback = sys.exc_info()[2] except ImportError as ex: - value = exceptions.AstroidBuildingException( + value = exceptions.AstroidImportError( 'Failed to import module {modname} with error:\n{error}.', modname=modname, error=ex) traceback = sys.exc_info()[2] @@ -232,7 +232,7 @@ class AstroidManager(object): 'Unable to get module for {class_repr}.', cls=klass, class_repr=safe_repr(klass))) except Exception as ex: # pylint: disable=broad-except - util.reraise(exceptions.AstroidBuildingException( + util.reraise(exceptions.AstroidImportError( 'Unexpected error while retrieving module for {class_repr}:\n' '{error}', cls=klass, class_repr=safe_repr(klass), error=ex)) try: @@ -242,7 +242,7 @@ class AstroidManager(object): 'Unable to get name for {class_repr}:\n', cls=klass, class_repr=safe_repr(klass))) except Exception as ex: # pylint: disable=broad-except - util.reraise(exceptions.AstroidBuildingException( + util.reraise(exceptions.AstroidImportError( 'Unexpected error while retrieving name for {class_repr}:\n' '{error}', cls=klass, class_repr=safe_repr(klass), error=ex)) # take care, on living object __module__ is regularly wrong :( diff --git a/astroid/mixins.py b/astroid/mixins.py index 6ee7b4d..e67c9af 100644 --- a/astroid/mixins.py +++ b/astroid/mixins.py @@ -125,23 +125,9 @@ class ImportFromMixin(FilterStmtsMixin): if mymodule.relative_to_absolute_name(modname, level) == mymodule.name: # FIXME: we used to raise InferenceError here, but why ? return mymodule - try: - return mymodule.import_module(modname, level=level, - relative_only=level and level >= 1) - except exceptions.AstroidBuildingException as ex: - if isinstance(getattr(ex, 'error', None), SyntaxError): - util.reraise(exceptions.InferenceError( - 'Could not import {modname} because of SyntaxError:\n' - '{syntax_error}', modname=modname, syntax_error=ex.error, - import_node=self)) - util.reraise(exceptions.InferenceError('Could not import {modname}.', - modname=modname, - import_node=self)) - except SyntaxError as ex: - util.reraise(exceptions.InferenceError( - 'Could not import {modname} because of SyntaxError:\n' - '{syntax_error}', modname=modname, syntax_error=ex, - import_node=self)) + + return mymodule.import_module(modname, level=level, + relative_only=level and level >= 1) def real_name(self, asname): """get name from 'as' name""" diff --git a/astroid/tests/testdata/python2/data/invalid_encoding.py b/astroid/tests/testdata/python2/data/invalid_encoding.py new file mode 100644 index 0000000..dddd208 --- /dev/null +++ b/astroid/tests/testdata/python2/data/invalid_encoding.py @@ -0,0 +1 @@ +# -*- coding: lala -*-
\ No newline at end of file diff --git a/astroid/tests/testdata/python3/data/invalid_encoding.py b/astroid/tests/testdata/python3/data/invalid_encoding.py new file mode 100644 index 0000000..dddd208 --- /dev/null +++ b/astroid/tests/testdata/python3/data/invalid_encoding.py @@ -0,0 +1 @@ +# -*- coding: lala -*-
\ No newline at end of file diff --git a/astroid/tests/unittest_builder.py b/astroid/tests/unittest_builder.py index dc161d0..cb5bba9 100644 --- a/astroid/tests/unittest_builder.py +++ b/astroid/tests/unittest_builder.py @@ -255,11 +255,11 @@ class BuilderTest(unittest.TestCase): self.builder = builder.AstroidBuilder() def test_data_build_null_bytes(self): - with self.assertRaises(exceptions.AstroidBuildingException): + with self.assertRaises(exceptions.AstroidSyntaxError): self.builder.string_build('\x00') def test_data_build_invalid_x_escape(self): - with self.assertRaises(exceptions.AstroidBuildingException): + with self.assertRaises(exceptions.AstroidSyntaxError): self.builder.string_build('"\\x1"') def test_missing_newline(self): @@ -705,6 +705,10 @@ class FileBuildTest(unittest.TestCase): self.assertEqual(len(_locals), 3) self.assertEqual(keys, ['autre', 'local', 'self']) + def test_unknown_encoding(self): + with self.assertRaises(exceptions.AstroidSyntaxError): + resources.build_file('data/invalid_encoding.py') + class ModuleBuildTest(resources.SysPathSetup, FileBuildTest): |