diff options
author | Ceridwen <ceridwenv@gmail.com> | 2015-11-02 00:10:54 -0500 |
---|---|---|
committer | Ceridwen <ceridwenv@gmail.com> | 2015-11-02 00:10:54 -0500 |
commit | 1ba0f2d96fbc45ff0b6014b12db98716183e8277 (patch) | |
tree | 54b7c4d3ecad6fcda1211ea3a8e5f11f6b407287 /astroid/builder.py | |
parent | 83f6c45c343cae87f415268959b1056030a5e74c (diff) | |
download | astroid-1ba0f2d96fbc45ff0b6014b12db98716183e8277.tar.gz |
This bookmark adds structured exceptions to astroid.
Major changes:
* AstroidError has an __init__ that accepts arbitrary keyword-only
arguments for adding information to exceptions, and a __str__ that
lazily uses exception attributes to generate a message. The first
positional argument to an exception is assigned to .message. The new
API should be fully backwards compatible in general.
* Some exceptions are combined or renamed; the old names are still
available.
* The OperationErrors used by pylint are now BadOperationMessages and
located in util.py.
* The AstroidBuildingException in _data_build stores the SyntaxError
in its .error attribute rather than args[0].
* Many places where exceptions are raised have new, hopefully more
useful error messages.
The only major issue remaining is how to propagate information into decorators.
Diffstat (limited to 'astroid/builder.py')
-rw-r--r-- | astroid/builder.py | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/astroid/builder.py b/astroid/builder.py index 9bb78b1..4db4051 100644 --- a/astroid/builder.py +++ b/astroid/builder.py @@ -51,8 +51,9 @@ if sys.version_info >= (3, 0): data = stream.read() except UnicodeError: # wrong encoding # detect_encoding returns utf-8 if no encoding specified - msg = 'Wrong (%s) or no encoding specified' % encoding - util.reraise(exceptions.AstroidBuildingException(msg)) + util.reraise(exceptions.AstroidBuildingException( + 'Wrong ({encoding}) or no encoding specified for {filename}.', + encoding=encoding, filename=filename)) return stream, encoding, data else: @@ -123,11 +124,13 @@ class AstroidBuilder(raw_building.InspectBuilder): try: stream, encoding, data = open_source_file(path) except IOError as exc: - msg = 'Unable to load file %r (%s)' % (path, exc) - util.reraise(exceptions.AstroidBuildingException(msg)) + util.reraise(exceptions.AstroidBuildingException( + 'Unable to load file {path}:\n{error}', + modname=modname, path=path, error=exc)) except (SyntaxError, LookupError) as exc: - # Python 3 encoding specification error or unknown encoding - util.reraise(exceptions.AstroidBuildingException(*exc.args)) + util.reraise(exceptions.AstroidBuildingException( + 'Python 3 encoding specification error or unknown encoding:\n' + '{error}', modname=modname, path=path, error=exc)) with stream: # get module name if necessary if modname is None: @@ -169,12 +172,16 @@ class AstroidBuilder(raw_building.InspectBuilder): try: node = _parse(data + '\n') except (TypeError, ValueError) as exc: - util.reraise(exceptions.AstroidBuildingException(*exc.args)) + util.reraise(exceptions.AstroidBuildingException( + '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(exc)) + 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: |