diff options
| author | cpopa <devnull@localhost> | 2014-01-03 12:36:02 +0200 |
|---|---|---|
| committer | cpopa <devnull@localhost> | 2014-01-03 12:36:02 +0200 |
| commit | 74235c75b27806b639cdde8b0df81d916d843f0d (patch) | |
| tree | f72f8c81f7a3e1a1b559a9396170559fed2a5ccd | |
| parent | e099a5685de2fd625de831d060d0b4a91ed4481d (diff) | |
| parent | 74796a1eb4a79fc2f85e3208e74945b7a2db9af4 (diff) | |
| download | pylint-74235c75b27806b639cdde8b0df81d916d843f0d.tar.gz | |
Merge with default.
| -rw-r--r-- | ChangeLog | 5 | ||||
| -rw-r--r-- | checkers/exceptions.py | 26 | ||||
| -rw-r--r-- | test/input/func_bad_exception_context_py30.py | 17 | ||||
| -rw-r--r-- | test/messages/func_bad_exception_context_py30.txt | 2 |
4 files changed, 49 insertions, 1 deletions
@@ -1,6 +1,11 @@ ChangeLog for Pylint ==================== +-- + * Add new warning 'bad-exception-context', checking + that `raise ... from ...` uses a proper exception context + (None or an exception). + 2013-12-22 -- 1.1.0 * Add new check for use of deprecated pragma directives "pylint:disable-msg" or "pylint:enable-msg" (I0022, deprecated-pragma) which was previously diff --git a/checkers/exceptions.py b/checkers/exceptions.py index 5bb07ac..0895a8b 100644 --- a/checkers/exceptions.py +++ b/checkers/exceptions.py @@ -43,6 +43,7 @@ def infer_bases(klass): for base in infer_bases(inferit): yield base +PY3K = sys.version_info >= (3, 0) OVERGENERAL_EXCEPTIONS = ('Exception',) MSGS = { @@ -55,6 +56,13 @@ MSGS = { 'raising-bad-type', 'Used when something which is neither a class, an instance or a \ string is raised (i.e. a `TypeError` will be raised).'), + 'E0703': ('Exception context set to something which is not an ' + 'exception, nor None', + 'bad-exception-context', + 'Used when using the syntax "raise ... from ...", ' + 'where the exception context is not an exception, ' + 'nor None.', + {'minversion': (3, 0)}), 'E0710': ('Raising a new style class which doesn\'t inherit from BaseException', 'raising-non-exception', 'Used when a new style class which doesn\'t inherit from \ @@ -126,12 +134,28 @@ class ExceptionsChecker(BaseChecker): ), ) - @check_messages('W0701', 'W0710', 'E0702', 'E0710', 'E0711') + @check_messages('W0701', 'W0710', 'E0702', 'E0710', 'E0711', + 'bad-exception-context') def visit_raise(self, node): """visit raise possibly inferring value""" # ignore empty raise if node.exc is None: return + if PY3K and node.cause: + if isinstance(node.cause, astroid.Const): + if node.cause.value is not None: + self.add_message('bad-exception-context', + node=node) + else: + try: + cause = node.cause.infer().next() + except astroid.InferenceError: + pass + else: + if (not isinstance(cause, astroid.Class) and + not inherit_from_std_ex(cause)): + self.add_message('bad-exception-context', + node=node) expr = node.exc if self._check_raise_value(node, expr): return diff --git a/test/input/func_bad_exception_context_py30.py b/test/input/func_bad_exception_context_py30.py new file mode 100644 index 0000000..b520e68 --- /dev/null +++ b/test/input/func_bad_exception_context_py30.py @@ -0,0 +1,17 @@ +"""Check that raise ... from .. uses a proper exception context """ + +# pylint: disable=unreachable + +__revision__ = 0 + +class ExceptionSubclass(Exception): + """ subclass """ + +def test(): + """ docstring """ + raise IndexError from 1 + raise IndexError from None + raise IndexError from ZeroDivisionError + raise IndexError from object() + raise IndexError from ExceptionSubclass + diff --git a/test/messages/func_bad_exception_context_py30.txt b/test/messages/func_bad_exception_context_py30.txt new file mode 100644 index 0000000..0a4b3ec --- /dev/null +++ b/test/messages/func_bad_exception_context_py30.txt @@ -0,0 +1,2 @@ +E: 12:test: Exception context set to something which is not an exception, nor None
+E: 15:test: Exception context set to something which is not an exception, nor None
\ No newline at end of file |
