summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhippo91 <guillaume.peillex@gmail.com>2018-01-28 20:01:38 +0100
committerhippo91 <guillaume.peillex@gmail.com>2018-01-28 20:01:38 +0100
commitccf2261d7fae2fd988fa40dd39abbbcae1a5c344 (patch)
tree9f52fe15cb760ba9fd494fb0c3520bee3fabb3cd
parent9e17f0c3864feb800ab19d4513d1fc63927d8e4f (diff)
downloadpylint-git-ccf2261d7fae2fd988fa40dd39abbbcae1a5c344.tar.gz
Backport of PR#1855
-rw-r--r--ChangeLog5
-rw-r--r--doc/whatsnew/1.8.rst4
-rw-r--r--pylint/checkers/refactoring.py5
-rw-r--r--pylint/checkers/utils.py25
-rw-r--r--pylint/test/functional/inconsistent_returns.py16
-rw-r--r--pylint/test/functional/inconsistent_returns.txt26
6 files changed, 61 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 54df5a277..26145f81a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.