~ubuntu-branches/ubuntu/trusty/pylint/trusty

« back to all changes in this revision

Viewing changes to checkers/design_analysis.py

  • Committer: Bazaar Package Importer
  • Author(s): Sylvain Thénault
  • Date: 2006-09-25 16:46:40 UTC
  • mfrom: (1.2.1 upstream) (2.1.4 feisty)
  • Revision ID: james.westby@ubuntu.com-20060925164640-obkb6g34gqtyk20n
new uptream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2003-2006 LOGILAB S.A. (Paris, FRANCE).
 
2
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
 
3
#
1
4
# This program is free software; you can redistribute it and/or modify it under
2
5
# the terms of the GNU General Public License as published by the Free Software
3
6
# Foundation; either version 2 of the License, or (at your option) any later
10
13
# You should have received a copy of the GNU General Public License along with
11
14
# this program; if not, write to the Free Software Foundation, Inc.,
12
15
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
13
 
""" Copyright (c) 2002-2004 LOGILAB S.A. (Paris, FRANCE).
14
 
 http://www.logilab.fr/ -- mailto:contact@logilab.fr
15
 
 
16
 
 check for signs of poor design
 
16
"""check for signs of poor design
17
17
 
18
18
 
19
19
 see http://intranet.logilab.fr/jpl/view?rql=Any%20X%20where%20X%20eid%201243
20
20
 FIXME: missing 13, 15, 16
21
21
"""
22
22
 
23
 
__revision__ = "$Id: design_analysis.py,v 1.7 2005/01/19 16:09:45 syt Exp $"
24
 
 
25
 
from logilab.common.astng import Function
26
 
from logilab.common.astng.utils import get_interfaces
27
 
 
28
 
from logilab.pylint.interfaces import IASTNGChecker
29
 
from logilab.pylint.checkers import BaseChecker
30
 
from logilab.pylint.checkers.utils import is_interface, is_exception, \
31
 
     is_abstract, is_metaclass
 
23
__revision__ = "$Id: design_analysis.py,v 1.11 2005-12-30 15:41:29 adim Exp $"
 
24
 
 
25
from logilab.astng import Function, InferenceError
 
26
 
 
27
from pylint.interfaces import IASTNGChecker
 
28
from pylint.checkers import BaseChecker
32
29
 
33
30
def class_is_abstract(klass):
34
 
    """return true if the given class node should be considered as an abstrac
 
31
    """return true if the given class node should be considered as an abstract
35
32
    class
36
33
    """
37
 
    for attr in klass.locals.values():
 
34
    for attr in klass.values():
38
35
        if isinstance(attr, Function):
39
 
            if is_abstract(attr, pass_is_abstract=False):
 
36
            if attr.is_abstract(pass_is_abstract=False):
40
37
                return True
41
38
    return False
42
39
 
43
40
 
44
41
MSGS = {
45
42
    'R0901': ('Too many ancestors (%s/%s)',
46
 
              'Used when class has too many parent classes.'),
 
43
              'Used when class has too many parent classes, try to reduce \
 
44
              this to get a more simple (and so easier to use) class.'),
47
45
    'R0902': ('Too many instance attributes (%s/%s)',
48
 
              'Used when class has too many instance attributes.'),
49
 
    'R0903': ('Not enough public methods (%s/%s)',
50
 
              'Used when class has not enough public methods.'),
 
46
              'Used when class has too many instance attributes, try to reduce \
 
47
              this to get a more simple (and so easier to use) class.'),
 
48
    'R0903': ('To few public methods (%s/%s)',
 
49
              'Used when class has to few public methods, so be sure it\'s \
 
50
              really worth it.'),
51
51
    'R0904': ('Too many public methods (%s/%s)',
52
 
              'Used when class has too many public methods.'),
 
52
              'Used when class has too many public methods, try to reduce \
 
53
              this to get a more simple (and so easier to use) class.'),
53
54
    
54
55
    'R0911': ('Too many return statements (%s/%s)',
55
 
              'Used when a function or method has too many return statement.'),
 
56
              'Used when a function or method has too many return statement, \
 
57
              making it hard to follow.'),
56
58
    'R0912': ('Too many branches (%s/%s)',
57
 
              'Used when a function or method has too many branches.'),
 
59
              'Used when a function or method has too many branches, \
 
60
              making it hard to follow.'),
58
61
    'R0913': ('Too many arguments (%s/%s)',
59
62
              'Used when a function or method takes too many arguments.'),
60
63
    'R0914': ('Too many local variables (%s/%s)',
190
193
        # update abstract / interface classes structures
191
194
        if class_is_abstract(node):
192
195
            self._abstracts.append(node)
193
 
        elif is_interface(node) and node.name != 'Interface':
 
196
        elif node.type == 'interface' and node.name != 'Interface':
194
197
            self._ifaces.append(node)
195
198
            for parent in node.ancestors(False):
196
199
                if parent.name == 'Interface':
197
200
                    continue
198
201
                self._used_ifaces[parent] = 1
199
 
        for iface in get_interfaces(node):
200
 
            self._used_ifaces[iface] = 1
 
202
        try:
 
203
            for iface in node.interfaces():
 
204
                self._used_ifaces[iface] = 1
 
205
        except InferenceError:
 
206
            # XXX log ? 
 
207
            pass
201
208
        for parent in node.ancestors():
202
209
            try:
203
210
                self._used_abstracts[parent] += 1
215
222
            self.add_message('R0904', node=node,
216
223
                             args=(nb_public_methods,
217
224
                                   self.config.max_public_methods))
218
 
        if is_exception(node) or is_metaclass(node) or is_interface(node):
 
225
        # stop here for exception, metaclass and interface classes
 
226
        if node.type != 'class':
219
227
            return
220
228
        # Does the class contain more than 5 public methods ?
221
229
        if nb_public_methods < self.config.min_public_methods:
310
318
    def _inc_branch(self, branchsnum=1):
311
319
        """increments the branchs counter"""
312
320
        branchs = self._branchs
313
 
        for i in range(len(branchs)):
 
321
        for i in xrange(len(branchs)):
314
322
            branchs[i] += branchsnum
315
323
 
316
324
    # FIXME: make a nice report...