diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | doc/whatsnew/1.8.rst | 4 | ||||
-rw-r--r-- | pylint/checkers/refactoring.py | 5 | ||||
-rw-r--r-- | pylint/checkers/utils.py | 25 | ||||
-rw-r--r-- | pylint/test/functional/inconsistent_returns.py | 16 | ||||
-rw-r--r-- | pylint/test/functional/inconsistent_returns.txt | 26 |
6 files changed, 61 insertions, 20 deletions
@@ -12,6 +12,11 @@ Release date: - Close #1794 + * Fix false positive ``inconsistent-return-statements`` message by + avoiding useless exception inference if the exception is not handled. + + Close #1794 (second part) + What's New in Pylint 1.8.2? ========================== diff --git a/doc/whatsnew/1.8.rst b/doc/whatsnew/1.8.rst index a0cf7d3ac..422aa70f6 100644 --- a/doc/whatsnew/1.8.rst +++ b/doc/whatsnew/1.8.rst @@ -381,3 +381,7 @@ Other Changes * Fix false positive ``inconsistent-return-statements`` message when a function is defined under an if statement. (backport from 2.0) + +* Fix false positive ``inconsistent-return-statements`` message by + avoiding useless exception inference if the exception is not handled. + (backport from 2.0) diff --git a/pylint/checkers/refactoring.py b/pylint/checkers/refactoring.py index 1f437799d..75a36af06 100644 --- a/pylint/checkers/refactoring.py +++ b/pylint/checkers/refactoring.py @@ -568,6 +568,11 @@ class RefactoringChecker(checkers.BaseTokenChecker): if not node.exc: # Ignore bare raises return True + if not utils.is_node_inside_try_except(node): + # If the raise statement is not inside a try/except statement + # then the exception is raised and cannot be caught. No need + # to infer it. + return True exc = utils.safe_infer(node.exc) if exc is None or exc is astroid.Uninferable: return False diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 9d8a18ba5..5b9525dfe 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -596,6 +596,7 @@ def unimplemented_abstract_methods(node, is_abstract_cb=None): def _import_node_context(node): + """Return the ExceptHandler or the TryExcept node in which the node is.""" current = node ignores = (astroid.ExceptHandler, astroid.TryExcept) while current and not isinstance(current.parent, ignores): @@ -642,17 +643,27 @@ def get_exception_handlers(node, exception): generator: the collection of handlers that are handling the exception or None. """ - current = node - ignores = (astroid.ExceptHandler, astroid.TryExcept) - while current and not isinstance(current.parent, ignores): - current = current.parent - - if current and isinstance(current.parent, astroid.TryExcept): - return (_handler for _handler in current.parent.handlers + context = _import_node_context(node) + if isinstance(context, astroid.TryExcept): + return (_handler for _handler in context.handlers if error_of_type(_handler, exception)) return None +def is_node_inside_try_except(node): + """Check if the node is directly under a Try/Except statement. + (but not under an ExceptHandler!) + + Args: + node (astroid.Raise): the node raising the exception. + + Returns: + bool: True if the node is inside a try/except statement, False otherwise. + """ + context = _import_node_context(node) + return isinstance(context, astroid.TryExcept) + + def node_ignores_exception(node, exception): """Check if the node is in a TryExcept which handles the given exception.""" managing_handlers = get_exception_handlers(node, exception) diff --git a/pylint/test/functional/inconsistent_returns.py b/pylint/test/functional/inconsistent_returns.py index a6ec2cd1f..0524cd575 100644 --- a/pylint/test/functional/inconsistent_returns.py +++ b/pylint/test/functional/inconsistent_returns.py @@ -130,6 +130,22 @@ def bug_1794_inner_func_in_if(var): else: return None +try: + import ConfigParser as configparser +except ImportError: + import configparser + +# Due to the try/except import above, astroid cannot safely +# infer the exception type. It doesn't matter here, because +# as the raise statement is not inside a try/except one, there +# is no need to infer the exception type. It is just an exception +# that is raised. +def bug_1794(a): + for x in range(a): + if x == 100: + return a + raise configparser.NoSectionError('toto') + # Next ones are not consistent def explicit_implicit_returns(var): # [inconsistent-return-statements] if var >= 0: diff --git a/pylint/test/functional/inconsistent_returns.txt b/pylint/test/functional/inconsistent_returns.txt index 08ce9d7d9..8bc9c5eda 100644 --- a/pylint/test/functional/inconsistent_returns.txt +++ b/pylint/test/functional/inconsistent_returns.txt @@ -1,13 +1,13 @@ -inconsistent-return-statements:134:explicit_implicit_returns:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:138:empty_explicit_returns:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:143:explicit_implicit_returns2:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:151:explicit_implicit_returns3:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:159:returns_missing_in_catched_exceptions:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:169:complex_func:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:177:inconsistent_returns_in_nested_function.not_consistent_returns_inner:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:198:bug_1772_counter_example:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:206:bug_1771_counter_example:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:212:bug_1794_inner_func_in_if_counter_example_1:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:221:bug_1794_inner_func_in_if_counter_example_2:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:230:bug_1794_inner_func_in_if_counter_example_3:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:237:bug_1794_inner_func_in_if_counter_example_3._inner2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:150:explicit_implicit_returns:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:154:empty_explicit_returns:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:159:explicit_implicit_returns2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:167:explicit_implicit_returns3:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:175:returns_missing_in_catched_exceptions:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:185:complex_func:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:193:inconsistent_returns_in_nested_function.not_consistent_returns_inner:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:214:bug_1772_counter_example:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:222:bug_1771_counter_example:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:228:bug_1794_inner_func_in_if_counter_example_1:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:237:bug_1794_inner_func_in_if_counter_example_2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:246:bug_1794_inner_func_in_if_counter_example_3:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:253:bug_1794_inner_func_in_if_counter_example_3._inner2:Either all return statements in a function should return an expression, or none of them should. |