~ubuntu-branches/debian/sid/pylint/sid

« back to all changes in this revision

Viewing changes to checkers/base.py

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2010-03-28 12:57:48 UTC
  • mfrom: (1.1.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100328125748-fblfc09naepbjhnx
Tags: 0.20.0-1
* New upstream release
  - thanks to Michael Richters for the report; Closes: #475939
* debian/copyright
  - updated upstream and packaging copyright years
* debian/control
  - bump Depends on python-logilab-common to '>= 0.49.0'
  - bump Depends on python-logilab-astng to '>= 0.20.0'
  - bump Standards-Version to 3.8.4 (no changes needed)
  - dropped XB-Python-Version
  - added python-logilab-common to b-d-i to have 'pytest' available
  - added python-logilab-astng to b-d-i, needed to run tests
* debian/rules
  - also delete *.pyo files (generated by tests running with -OO)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (c) 2003-2009 LOGILAB S.A. (Paris, FRANCE).
2
 
# Copyright (c) 2009 Arista Networks, Inc.
 
1
# Copyright (c) 2003-2010 LOGILAB S.A. (Paris, FRANCE).
 
2
# Copyright (c) 2009-2010 Arista Networks, Inc.
3
3
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
4
4
# This program is free software; you can redistribute it and/or modify it under
5
5
# the terms of the GNU General Public License as published by the Free Software
20
20
from logilab import astng
21
21
from logilab.common.compat import any
22
22
from logilab.common.ureports import Table
23
 
from logilab.astng.infutils import are_exclusive
 
23
from logilab.astng import are_exclusive
24
24
 
25
25
from pylint.interfaces import IASTNGChecker
26
26
from pylint.reporters import diff_string
160
160
              'Used when a function or method is called using `*args` or '
161
161
              '`**kwargs` to dispatch arguments. This doesn\'t improve '
162
162
              'readability and should be used with care.'),
 
163
    'W0150': ("%s statement in finally block may swallow exception",
 
164
              "Used when a break or a return statement is found inside the \
 
165
              finally clause of a try...finally block: the exceptions raised \
 
166
              in the try clause will be silently swallowed instead of being \
 
167
              re-raised."),
 
168
    'W0199': ('Assert called on a 2-uple. Did you mean \'assert x,y\'?',
 
169
              'A call of assert on a tuple will always evaluate to true if '
 
170
              'the tuple is not empty, and will always evaluate to false if '
 
171
              'it is.'),
163
172
 
164
173
    'C0102': ('Black listed name "%s"',
165
174
              'Used when the name is listed in the black list (unauthorized \
296
305
        BaseChecker.__init__(self, linter)
297
306
        self.stats = None
298
307
        self._returns = None
 
308
        self._tryfinallys = None
299
309
 
300
310
    def open(self):
301
311
        """initialize visit variables and statistics
302
312
        """
303
313
        self._returns = []
 
314
        self._tryfinallys = []
304
315
        self.stats = self.linter.add_stats(module=0, function=0,
305
316
                                           method=0, class_=0,
306
317
                                           badname_module=0,
469
480
                self._check_name('variable', node.name, node)
470
481
 
471
482
    def visit_return(self, node):
472
 
        """check is the node has a right sibling (if so, that's some unreachable
473
 
        code)
 
483
        """1 - check is the node has a right sibling (if so, that's some
 
484
        unreachable code)
 
485
        2 - check is the node is inside the finally clause of a try...finally
 
486
        block
474
487
        """
475
488
        # if self._returns is empty, we're outside a function !
476
489
        if not self._returns:
478
491
            return
479
492
        self._returns[-1].append(node)
480
493
        self._check_unreachable(node)
 
494
        # Is it inside final body of a try...finally bloc ?
 
495
        self._check_not_in_finally(node, 'return', (astng.Function,))
481
496
 
482
497
    def visit_yield(self, node):
483
498
        """check is the node has a right sibling (if so, that's some unreachable
497
512
        self._check_in_loop(node, 'continue')
498
513
 
499
514
    def visit_break(self, node):
500
 
        """check is the node has a right sibling (if so, that's some unreachable
501
 
        code)
 
515
        """1 - check is the node has a right sibling (if so, that's some
 
516
        unreachable code)
 
517
        2 - check is the node is inside the finally clause of a try...finally
 
518
        block
502
519
        """
 
520
        # 1 - Is it right sibling ?
503
521
        self._check_unreachable(node)
504
522
        self._check_in_loop(node, 'break')
 
523
        # 2 - Is it inside final body of a try...finally bloc ?
 
524
        self._check_not_in_finally(node, 'break', (astng.For, astng.While,))
505
525
 
506
526
    def visit_raise(self, node):
507
527
        """check is the node has a right sibling (if so, that's some unreachable
544
564
            isinstance(node.operand, astng.UnaryOp) and
545
565
            (node.operand.op == node.op)):
546
566
            self.add_message('E0107', node=node, args=node.op*2)
 
567
    
 
568
    def visit_assert(self, node):
 
569
        """check the use of an assert statement on a tuple."""
 
570
        if node.fail is None and isinstance(node.test, astng.Tuple) and \
 
571
           len(node.test.elts) == 2:
 
572
             self.add_message('W0199', line=node.fromlineno, node=node)
547
573
 
548
574
    def visit_dict(self, node):
549
575
        """check duplicate key in dictionary"""
555
581
                    self.add_message('W0109', node=node, args=key)
556
582
                keys.add(key)
557
583
 
 
584
    def visit_tryfinally(self, node):
 
585
        """update try...finally flag"""
 
586
        self._tryfinallys.append(node)
 
587
 
 
588
    def leave_tryfinally(self, node):
 
589
        """update try...finally flag"""
 
590
        self._tryfinallys.pop()
 
591
 
558
592
 
559
593
    def _check_unreachable(self, node):
560
594
        """check unreachable code"""
632
666
            if not node.has_key(attr):
633
667
                self.add_message('C0121', node=node, args=attr)
634
668
 
 
669
    def _check_not_in_finally(self, node, node_name, breaker_classes=()):
 
670
        """check that a node is not inside a finally clause of a
 
671
        try...finally statement.
 
672
        If we found before a try...finally bloc a parent which its type is
 
673
        in breaker_classes, we skip the whole check."""
 
674
        # if self._tryfinallys is empty, we're not a in try...finally bloc
 
675
        if not self._tryfinallys:
 
676
            return
 
677
        # the node could be a grand-grand...-children of the try...finally
 
678
        _parent = node.parent
 
679
        _node = node
 
680
        while _parent and not isinstance(_parent, breaker_classes):
 
681
            if hasattr(_parent, 'finalbody') and _node in _parent.finalbody:
 
682
                self.add_message('W0150', node=node, args=node_name)
 
683
                return
 
684
            _node = _parent
 
685
            _parent = _node.parent
635
686
 
636
687
def register(linter):
637
688
    """required method to auto register this checker"""