Below is a new checker that checks three miscellaneous things:

-- use of the non-existent ++ operator
-- duplicate key in dictionary
-- "assert x and y" rather than "assert x" and "assert y"

For example, on the following file:

x = y = 0
print ++x
d = { 'a' : 0, 'a' : 1 }
assert ( x == 0 ) and ( y == 0 )

it produces the following messages:

************* Module pylint-misc
E9800:  2: Use of the non-existent ++ operator
W9800:  3: Duplicate key 'a' in dictionary
W9801:  4: Assert x and y


Please consider these for inclusion in pylint.  I suspect the right thing to
do would be to add these to one of the existing checkers (perhaps the
"basic" checker for the ++ operator check, and the "variables" checker for
the duplicate key check).

Note that the third check ("assert x and y") might be considered
controversial, but I would argue that it's good style to split such asserts
into two separate asserts, so that when one of the conditions fails you can
tell from the backtrace which one it was.  Feel free to ignore this check if
you think it doesn't have sufficiently widespread appeal.

Thanks,
James.


===============================================

# Copyright (c) 2009 Arista Networks, Inc.
#
# This program is free software; you can redistribute it and/or modify it
under
# the terms of the GNU General Public License as published by the Free
Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
#
# You should have received a copy of the GNU General Public License along
with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
"""Checker for miscellaneous things.
"""

from logilab import astng
from pylint.interfaces import IASTNGChecker
from pylint.checkers import BaseChecker

MSGS = {
    'E9800': ("Use of the non-existent ++ operator",
              "Used when you attempt to use the C-style pre-increment
operator \
              (++), which doesn't exist in Python."),
    'W9800': ("Duplicate key %r in dictionary",
              "Used when a dictionary expression binds the same key multiple
\
              times."),
    'W9801': ("Assert x and y",
              'Used when an assert statement of the form "assert x and y" is
\
              encountered.  Use "assert x" and "assert y" instead.'),
    }

class MiscChecker(BaseChecker):
    """Checks for miscelaneous things.
    """

    __implements__ = (IASTNGChecker,)

    name = 'misc'
    msgs = MSGS

    def visit_unaryop(self, node):
        if ((node.op == '+') and
            isinstance(node.operand, astng.UnaryOp) and
            (node.operand.op == '+')):
            self.add_message('E9800', node=node)

    def visit_dict(self, node):
        keys = set()
        for k, v in node.items:
            if isinstance(k, astng.Const):
                key = k.value
                if key in keys:
                    self.add_message('W9800', node=node, args=key)
                keys.add(key)

    def visit_assert(self, node):
        if isinstance(node.test, astng.BoolOp) and (node.test.op == 'and'):
            self.add_message('W9801', node=node)

def register(linter):
    """required method to auto register this checker """
    linter.register_checker(MiscChecker(linter))
_______________________________________________
Python-Projects mailing list
Python-Projects@lists.logilab.org
http://lists.logilab.org/mailman/listinfo/python-projects

Reply via email to