summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2015-06-26 12:51:30 +0300
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2015-06-26 12:51:30 +0300
commit4a3385a0d3f3cec12314af01426279ea9599ba72 (patch)
tree8da625c8158a5004211d337afa41a7dbdbc7a1ac
parent84c8b402e9a85989cc5f89febbecb3bf83f73994 (diff)
downloadpylint-4a3385a0d3f3cec12314af01426279ea9599ba72.tar.gz
Verify explicitly that a class is not a known exception class.
This catches a couple of builtins which weren't previously detected when checking for catching-non-exception, because all builtins were exempted from this check.
-rw-r--r--pylint/checkers/exceptions.py18
-rw-r--r--pylint/test/functional/invalid_exceptions_caught.py17
-rw-r--r--pylint/test/functional/invalid_exceptions_caught.txt2
3 files changed, 34 insertions, 3 deletions
diff --git a/pylint/checkers/exceptions.py b/pylint/checkers/exceptions.py
index a67fec5..bb9aa07 100644
--- a/pylint/checkers/exceptions.py
+++ b/pylint/checkers/exceptions.py
@@ -14,11 +14,14 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""exceptions handling (raising, catching, exceptions classes) checker
"""
+import inspect
import sys
import astroid
from astroid import YES, Instance, unpack_infer, List, Tuple
from logilab.common.compat import builtins
+from logilab.common import decorators
+import six
from pylint.checkers import BaseChecker
from pylint.checkers.utils import (
@@ -47,12 +50,13 @@ def _annotated_unpack_infer(stmt, context=None):
for infered in stmt.infer(context):
if infered is YES:
continue
- yield stmt, infered
+ yield stmt, infered
PY3K = sys.version_info >= (3, 0)
OVERGENERAL_EXCEPTIONS = ('Exception',)
BUILTINS_NAME = builtins.__name__
+
MSGS = {
'E0701': ('Bad except clauses order (%s)',
'bad-except-order',
@@ -127,6 +131,15 @@ class ExceptionsChecker(BaseChecker):
),
)
+ @decorators.cachedproperty
+ def builtin_exceptions(self):
+ """Get a list of the builtins exceptions."""
+ def predicate(obj):
+ return isinstance(obj, type) and issubclass(obj, BaseException)
+
+ members = inspect.getmembers(six.moves.builtins, predicate)
+ return {exc.__name__ for (_, exc) in members}
+
@check_messages('nonstandard-exception',
'raising-bad-type', 'raising-non-exception',
'notimplemented-raised', 'bad-exception-context')
@@ -255,8 +268,9 @@ class ExceptionsChecker(BaseChecker):
node=handler.type,
args=(part.as_string(), ))
return
+
if (not inherit_from_std_ex(exc) and
- exc.root().name != BUILTINS_NAME):
+ exc.name not in self.builtin_exceptions):
if has_known_bases(exc):
self.add_message('catching-non-exception',
node=handler.type,
diff --git a/pylint/test/functional/invalid_exceptions_caught.py b/pylint/test/functional/invalid_exceptions_caught.py
index 4bb7148..2392ab0 100644
--- a/pylint/test/functional/invalid_exceptions_caught.py
+++ b/pylint/test/functional/invalid_exceptions_caught.py
@@ -2,7 +2,7 @@
# pylint: disable=too-many-ancestors, no-absolute-import, import-error
from __future__ import print_function
-import socket
+import socket, binascii
class MyException(object):
"""Custom 'exception'."""
@@ -92,3 +92,18 @@ try:
1 + 42
except UNKNOWN_COMPONENTS:
print("caught")
+
+try:
+ 1 + 42
+except binascii.Error:
+ print('builtin and detected')
+
+try:
+ 1 + 45
+except object: # [catching-non-exception]
+ print('caught')
+
+try:
+ 1 + 42
+except range: # [catching-non-exception]
+ print('caught')
diff --git a/pylint/test/functional/invalid_exceptions_caught.txt b/pylint/test/functional/invalid_exceptions_caught.txt
index 96ebded..3cd4822 100644
--- a/pylint/test/functional/invalid_exceptions_caught.txt
+++ b/pylint/test/functional/invalid_exceptions_caught.txt
@@ -8,3 +8,5 @@ catching-non-exception:72::"Catching an exception which doesn't inherit from Bas
catching-non-exception:72::"Catching an exception which doesn't inherit from BaseException: None"
catching-non-exception:72::"Catching an exception which doesn't inherit from BaseException: list([4, 5, 6])"
catching-non-exception:85::"Catching an exception which doesn't inherit from BaseException: NON_EXCEPTION_TUPLE"
+catching-non-exception:103::"Catching an exception which doesn't inherit from BaseException: object"
+catching-non-exception:108::"Catching an exception which doesn't inherit from BaseException: range"