closes #74745: make 'too general' exception names configurable (patch by Google)

authorSylvain Th?nault <sylvain.thenault@logilab.fr>
changeset8353eea079aa
branchdefault
phasepublic
hiddenno
parent revision#da7ed73e8cff Fixes misleading wording in warnings E1001 and E1002 (patch by google)
child revision#f0886f3824cb closes #74747: don't crash when lookup up a special attribute in class scope
files modified by this revision
ChangeLog
checkers/exceptions.py
test/messages/func_w0703.txt
# HG changeset patch
# User Sylvain Thénault <sylvain.thenault@logilab.fr>
# Date 1315383917 -7200
# Wed Sep 07 10:25:17 2011 +0200
# Node ID 8353eea079aa405a3332e2ccc47cc535db1dbee1
# Parent da7ed73e8cffc796b763db709522df67160c02c4
closes #74745: make 'too general' exception names configurable (patch by Google)

diff --git a/ChangeLog b/ChangeLog
@@ -1,15 +1,18 @@
1  ChangeLog for PyLint
2  ====================
3 +
4  --
5      * #74742: make allowed name for first argument of class method configurable
6        (patch by Google)
7 
8      * #74087: handle case where inference of a module return YES; this avoid
9        some cases of "TypeError: '_Yes' object does not support indexing" (patch
10        by Google)
11 
12 +    * #74745: make "too general" exception names configurable (patch by Google)
13 +
14 
15  2011-07-18  --  0.24.0
16      * #69738: add regular expressions support for "generated-members"
17 
18      * ids of logging and string_format checkers have been changed:
diff --git a/checkers/exceptions.py b/checkers/exceptions.py
@@ -24,10 +24,12 @@
19  from pylint.checkers import BaseChecker
20  from pylint.checkers.utils import is_empty, is_raising
21  from pylint.interfaces import IASTNGChecker
22 
23 
24 +OVERGENERAL_EXCEPTIONS = ('Exception',)
25 +
26  MSGS = {
27      'E0701': (
28      'Bad except clauses order (%s)',
29      'Used when except clauses are not in the correct order (from the \
30      more specific to the more generic). If you don\'t fix the order, \
@@ -45,12 +47,13 @@
31      'W0701': ('Raising a string exception',
32                'Used when a string exception is raised.'),
33      'W0702': ('No exception type(s) specified',
34                'Used when an except clause doesn\'t specify exceptions type to \
35                catch.'),
36 -    'W0703': ('Catch "Exception"',
37 -              'Used when an except catches Exception instances.'),
38 +    'W0703': ('Catching too general exception %s',
39 +              'Used when an except catches a too general exception, \
40 +              possibly burying unrelated errors.'),
41      'W0704': ('Except doesn\'t do anything',
42                'Used when an except clause does nothing but "pass" and there is\
43                no "else" clause.'),
44      'W0710': ('Exception doesn\'t inherit from standard "Exception" class',
45                'Used when a custom exception class is raised but doesn\'t \
@@ -72,11 +75,18 @@
46      __implements__ = IASTNGChecker
47 
48      name = 'exceptions'
49      msgs = MSGS
50      priority = -4
51 -    options = ()
52 +    options = (('overgeneral-exceptions',
53 +                {'default' : OVERGENERAL_EXCEPTIONS,
54 +                 'type' :'csv', 'metavar' : '<comma-separated class names>',
55 +                 'help' : 'Exceptions that will emit a warning '
56 +                          'when being caught. Defaults to "%s"' % (
57 +                              ', '.join(OVERGENERAL_EXCEPTIONS),)}
58 +                ),
59 +               )
60 
61      def visit_raise(self, node):
62          """visit raise possibly inferring value"""
63          # ignore empty raise
64          if node.exc is None:
@@ -161,14 +171,14 @@
65                      for previous_exc in exceptions_classes:
66                          if previous_exc in exc_ancestors:
67                              msg = '%s is an ancestor class of %s' % (
68                                  previous_exc.name, exc.name)
69                              self.add_message('E0701', node=handler.type, args=msg)
70 -                    if (exc.name == 'Exception'
71 +                    if (exc.name in self.config.overgeneral_exceptions
72                          and exc.root().name == EXCEPTIONS_MODULE
73                          and nb_handlers == 1 and not is_raising(handler.body)):
74 -                        self.add_message('W0703', node=handler.type)
75 +                        self.add_message('W0703', args=exc.name, node=handler.type)
76                  exceptions_classes += excs
77 
78 
79  def inherit_from_std_ex(node):
80      """return true if the given class node is subclass of
@@ -183,6 +193,5 @@
81      return False
82 
83  def register(linter):
84      """required method to auto register this checker"""
85      linter.register_checker(ExceptionsChecker(linter))
86 -
diff --git a/test/messages/func_w0703.txt b/test/messages/func_w0703.txt
@@ -1,1 +1,1 @@
87 -W:  8: Catch "Exception"
88 +W:  8: Catching too general exception Exception