# Copyright (c) 2003-2013 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
# Copyright (c) 2009-2010 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""basic checker for Python code"""

import collections
import itertools
import sys
import re

import six
from six.moves import zip  # pylint: disable=redefined-builtin

from logilab.common.ureports import Table

import astroid
import astroid.bases
from astroid import are_exclusive, InferenceError

from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE, HIGH
from pylint.utils import EmptyReport
from pylint.reporters import diff_string
from pylint.checkers import BaseChecker
from pylint.checkers.utils import (
    check_messages,
    clobber_in_except,
    is_builtin_object,
    is_inside_except,
    overrides_a_method,
    safe_infer,
    get_argument_from_call,
    has_known_bases,
    NoSuchArgumentError,
    is_import_error,
    unimplemented_abstract_methods,
    )


# regex for class/function/variable/constant name
CLASS_NAME_RGX = re.compile('[A-Z_][a-zA-Z0-9]+$')
MOD_NAME_RGX = re.compile('(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$')
CONST_NAME_RGX = re.compile('(([A-Z_][A-Z0-9_]*)|(__.*__))$')
COMP_VAR_RGX = re.compile('[A-Za-z_][A-Za-z0-9_]*$')
DEFAULT_NAME_RGX = re.compile('[a-z_][a-z0-9_]{2,30}$')
CLASS_ATTRIBUTE_RGX = re.compile(r'([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$')
# do not require a doc string on system methods
NO_REQUIRED_DOC_RGX = re.compile('__.*__')
REVERSED_METHODS = (('__getitem__', '__len__'),
                    ('__reversed__', ))

PY33 = sys.version_info >= (3, 3)
PY3K = sys.version_info >= (3, 0)
BAD_FUNCTIONS = ['map', 'filter']
if sys.version_info < (3, 0):
    BAD_FUNCTIONS.append('input')

# Name categories that are always consistent with all naming conventions.
EXEMPT_NAME_CATEGORIES = set(('exempt', 'ignore'))

# A mapping from builtin-qname -> symbol, to be used when generating messages
# about dangerous default values as arguments
DEFAULT_ARGUMENT_SYMBOLS = dict(
    zip(['.'.join([astroid.bases.BUILTINS, x]) for x in ('set', 'dict', 'list')],
        ['set()', '{}', '[]'])
)

del re

def _redefines_import(node):
    """ Detect that the given node (AssName) is inside an
    exception handler and redefines an import from the tryexcept body.
    Returns True if the node redefines an import, False otherwise.
    """
    current = node
    while current and not isinstance(current.parent, astroid.ExceptHandler):
        current = current.parent
    if not current or not is_import_error(current.parent):
        return False
    try_block = current.parent.parent
    for import_node in try_block.nodes_of_class((astroid.From, astroid.Import)):
        for name, alias in import_node.names:
            if alias:
                if alias == node.name:
                    return True
            elif name == node.name:
                return True
    return False

def in_loop(node):
    """return True if the node is inside a kind of for loop"""
    parent = node.parent
    while parent is not None:
        if isinstance(parent, (astroid.For, astroid.ListComp, astroid.SetComp,
                               astroid.DictComp, astroid.GenExpr)):
            return True
        parent = parent.parent
    return False

def in_nested_list(nested_list, obj):
    """return true if the object is an element of <nested_list> or of a nested
    list
    """
    for elmt in nested_list:
        if isinstance(elmt, (list, tuple)):
            if in_nested_list(elmt, obj):
                return True
        elif elmt == obj:
            return True
    return False

def _loop_exits_early(loop):
    """Returns true if a loop has a break statement in its body."""
    loop_nodes = (astroid.For, astroid.While)
    # Loop over body explicitly to avoid matching break statements
    # in orelse.
    for child in loop.body:
        if isinstance(child, loop_nodes):
            # break statement may be in orelse of child loop.
            # pylint: disable=superfluous-parens
            for orelse in (child.orelse or ()):
                for _ in orelse.nodes_of_class(astroid.Break, skip_klass=loop_nodes):
                    return True
            continue
        for _ in child.nodes_of_class(astroid.Break, skip_klass=loop_nodes):
            return True
    return False

def _is_multi_naming_match(match, node_type, confidence):
    return (match is not None and
            match.lastgroup is not None and
            match.lastgroup not in EXEMPT_NAME_CATEGORIES
            and (node_type != 'method' or confidence != INFERENCE_FAILURE))


if sys.version_info < (3, 0):
    PROPERTY_CLASSES = set(('__builtin__.property', 'abc.abstractproperty'))
else:
    PROPERTY_CLASSES = set(('builtins.property', 'abc.abstractproperty'))


def _determine_function_name_type(node):
    """Determine the name type whose regex the a function's name should match.

    :param node: A function node.
    :returns: One of ('function', 'method', 'attr')
    """
    if not node.is_method():
        return 'function'
    if node.decorators:
        decorators = node.decorators.nodes
    else:
        decorators = []
    for decorator in decorators:
        # If the function is a property (decorated with @property
        # or @abc.abstractproperty), the name type is 'attr'.
        if (isinstance(decorator, astroid.Name) or
                (isinstance(decorator, astroid.Getattr) and
                 decorator.attrname == 'abstractproperty')):
            infered = safe_infer(decorator)
            if infered and infered.qname() in PROPERTY_CLASSES:
                return 'attr'
        # If the function is decorated using the prop_method.{setter,getter}
        # form, treat it like an attribute as well.
        elif (isinstance(decorator, astroid.Getattr) and
              decorator.attrname in ('setter', 'deleter')):
            return 'attr'
    return 'method'



def _has_abstract_methods(node):
    """
    Determine if the given `node` has abstract methods.

    The methods should be made abstract by decorating them
    with `abc` decorators.
    """
    return len(unimplemented_abstract_methods(node)) > 0


def report_by_type_stats(sect, stats, old_stats):
    """make a report of

    * percentage of different types documented
    * percentage of different types with a bad name
    """
    # percentage of different types documented and/or with a bad name
    nice_stats = {}
    for node_type in ('module', 'class', 'method', 'function'):
        try:
            total = stats[node_type]
        except KeyError:
            raise EmptyReport()
        nice_stats[node_type] = {}
        if total != 0:
            try:
                documented = total - stats['undocumented_'+node_type]
                percent = (documented * 100.) / total
                nice_stats[node_type]['percent_documented'] = '%.2f' % percent
            except KeyError:
                nice_stats[node_type]['percent_documented'] = 'NC'
            try:
                percent = (stats['badname_'+node_type] * 100.) / total
                nice_stats[node_type]['percent_badname'] = '%.2f' % percent
            except KeyError:
                nice_stats[node_type]['percent_badname'] = 'NC'
    lines = ('type', 'number', 'old number', 'difference',
             '%documented', '%badname')
    for node_type in ('module', 'class', 'method', 'function'):
        new = stats[node_type]
        old = old_stats.get(node_type, None)
        if old is not None:
            diff_str = diff_string(old, new)
        else:
            old, diff_str = 'NC', 'NC'
        lines += (node_type, str(new), str(old), diff_str,
                  nice_stats[node_type].get('percent_documented', '0'),
                  nice_stats[node_type].get('percent_badname', '0'))
    sect.append(Table(children=lines, cols=6, rheaders=1))

def redefined_by_decorator(node):
    """return True if the object is a method redefined via decorator.

    For example:
        @property
        def x(self): return self._x
        @x.setter
        def x(self, value): self._x = value
    """
    if node.decorators:
        for decorator in node.decorators.nodes:
            if (isinstance(decorator, astroid.Getattr) and
                    getattr(decorator.expr, 'name', None) == node.name):
                return True
    return False

class _BasicChecker(BaseChecker):
    __implements__ = IAstroidChecker
    name = 'basic'

class BasicErrorChecker(_BasicChecker):
    msgs = {
        'E0100': ('__init__ method is a generator',
                  'init-is-generator',
                  'Used when the special class method __init__ is turned into a '
                  'generator by a yield in its body.'),
        'E0101': ('Explicit return in __init__',
                  'return-in-init',
                  'Used when the special class method __init__ has an explicit '
                  'return value.'),
        'E0102': ('%s already defined line %s',
                  'function-redefined',
                  'Used when a function / class / method is redefined.'),
        'E0103': ('%r not properly in loop',
                  'not-in-loop',
                  'Used when break or continue keywords are used outside a loop.'),
        'E0104': ('Return outside function',
                  'return-outside-function',
                  'Used when a "return" statement is found outside a function or '
                  'method.'),
        'E0105': ('Yield outside function',
                  'yield-outside-function',
                  'Used when a "yield" statement is found outside a function or '
                  'method.'),
        'E0106': ('Return with argument inside generator',
                  'return-arg-in-generator',
                  'Used when a "return" statement with an argument is found '
                  'outside in a generator function or method (e.g. with some '
                  '"yield" statements).',
                  {'maxversion': (3, 3)}),
        'E0107': ("Use of the non-existent %s operator",
                  'nonexistent-operator',
                  "Used when you attempt to use the C-style pre-increment or"
                  "pre-decrement operator -- and ++, which doesn't exist in Python."),
        'E0108': ('Duplicate argument name %s in function definition',
                  'duplicate-argument-name',
                  'Duplicate argument names in function definitions are syntax'
                  ' errors.'),
        'E0110': ('Abstract class %r with abstract methods instantiated',
                  'abstract-class-instantiated',
                  'Used when an abstract class with `abc.ABCMeta` as metaclass '
                  'has abstract methods and is instantiated.'),
        'W0120': ('Else clause on loop without a break statement',
                  'useless-else-on-loop',
                  'Loops should only have an else clause if they can exit early '
                  'with a break statement, otherwise the statements under else '
                  'should be on the same scope as the loop itself.'),
        }

    @check_messages('function-redefined')
    def visit_class(self, node):
        self._check_redefinition('class', node)

    @check_messages('init-is-generator', 'return-in-init',
                    'function-redefined', 'return-arg-in-generator',
                    'duplicate-argument-name')
    def visit_function(self, node):
        if not redefined_by_decorator(node):
            self._check_redefinition(node.is_method() and 'method' or 'function', node)
        # checks for max returns, branch, return in __init__
        returns = node.nodes_of_class(astroid.Return,
                                      skip_klass=(astroid.Function, astroid.Class))
        if node.is_method() and node.name == '__init__':
            if node.is_generator():
                self.add_message('init-is-generator', node=node)
            else:
                values = [r.value for r in returns]
                # Are we returning anything but None from constructors
                if [v for v in values
                        if not (v is None or
                                (isinstance(v, astroid.Const) and v.value is None) or
                                (isinstance(v, astroid.Name)  and v.name == 'None')
                               )]:
                    self.add_message('return-in-init', node=node)
        elif node.is_generator():
            # make sure we don't mix non-None returns and yields
            if not PY33:
                for retnode in returns:
                    if isinstance(retnode.value, astroid.Const) and \
                           retnode.value.value is not None:
                        self.add_message('return-arg-in-generator', node=node,
                                         line=retnode.fromlineno)
        # Check for duplicate names
        args = set()
        for name in node.argnames():
            if name in args:
                self.add_message('duplicate-argument-name', node=node, args=(name,))
            else:
                args.add(name)


    @check_messages('return-outside-function')
    def visit_return(self, node):
        if not isinstance(node.frame(), astroid.Function):
            self.add_message('return-outside-function', node=node)

    @check_messages('yield-outside-function')
    def visit_yield(self, node):
        if not isinstance(node.frame(), (astroid.Function, astroid.Lambda)):
            self.add_message('yield-outside-function', node=node)

    @check_messages('not-in-loop')
    def visit_continue(self, node):
        self._check_in_loop(node, 'continue')

    @check_messages('not-in-loop')
    def visit_break(self, node):
        self._check_in_loop(node, 'break')

    @check_messages('useless-else-on-loop')
    def visit_for(self, node):
        self._check_else_on_loop(node)

    @check_messages('useless-else-on-loop')
    def visit_while(self, node):
        self._check_else_on_loop(node)

    @check_messages('nonexistent-operator')
    def visit_unaryop(self, node):
        """check use of the non-existent ++ and -- operator operator"""
        if ((node.op in '+-') and
                isinstance(node.operand, astroid.UnaryOp) and
                (node.operand.op == node.op)):
            self.add_message('nonexistent-operator', node=node, args=node.op*2)

    @check_messages('abstract-class-instantiated')
    def visit_callfunc(self, node):
        """ Check instantiating abstract class with
        abc.ABCMeta as metaclass.
        """
        try:
            infered = next(node.func.infer())
        except astroid.InferenceError:
            return
        if not isinstance(infered, astroid.Class):
            return
        # __init__ was called
        metaclass = infered.metaclass()
        abstract_methods = _has_abstract_methods(infered)
        if metaclass is None:
            # Python 3.4 has `abc.ABC`, which won't be detected
            # by ClassNode.metaclass()
            for ancestor in infered.ancestors():
                if ancestor.qname() == 'abc.ABC' and abstract_methods:
                    self.add_message('abstract-class-instantiated',
                                     args=(infered.name, ),
                                     node=node)
                    break
            return
        if metaclass.qname() == 'abc.ABCMeta' and abstract_methods:
            self.add_message('abstract-class-instantiated',
                             args=(infered.name, ),
                             node=node)

    def _check_else_on_loop(self, node):
        """Check that any loop with an else clause has a break statement."""
        if node.orelse and not _loop_exits_early(node):
            self.add_message('useless-else-on-loop', node=node,
                             # This is not optimal, but the line previous
                             # to the first statement in the else clause
                             # will usually be the one that contains the else:.
                             line=node.orelse[0].lineno - 1)

    def _check_in_loop(self, node, node_name):
        """check that a node is inside a for or while loop"""
        _node = node.parent
        while _node:
            if isinstance(_node, (astroid.For, astroid.While)):
                break
            _node = _node.parent
        else:
            self.add_message('not-in-loop', node=node, args=node_name)

    def _check_redefinition(self, redeftype, node):
        """check for redefinition of a function / method / class name"""
        defined_self = node.parent.frame()[node.name]
        if defined_self is not node and not are_exclusive(node, defined_self):
            self.add_message('function-redefined', node=node,
                             args=(redeftype, defined_self.fromlineno))



class BasicChecker(_BasicChecker):
    """checks for :
    * doc strings
    * number of arguments, local variables, branches, returns and statements in
functions, methods
    * required module attributes
    * dangerous default values as arguments
    * redefinition of function / method / class
    * uses of the global statement
    """

    __implements__ = IAstroidChecker

    name = 'basic'
    msgs = {
        'W0101': ('Unreachable code',
                  'unreachable',
                  'Used when there is some code behind a "return" or "raise" '
                  'statement, which will never be accessed.'),
        'W0102': ('Dangerous default value %s as argument',
                  'dangerous-default-value',
                  'Used when a mutable value as list or dictionary is detected in '
                  'a default value for an argument.'),
        'W0104': ('Statement seems to have no effect',
                  'pointless-statement',
                  'Used when a statement doesn\'t have (or at least seems to) '
                  'any effect.'),
        'W0105': ('String statement has no effect',
                  'pointless-string-statement',
                  'Used when a string is used as a statement (which of course '
                  'has no effect). This is a particular case of W0104 with its '
                  'own message so you can easily disable it if you\'re using '
                  'those strings as documentation, instead of comments.'),
        'W0106': ('Expression "%s" is assigned to nothing',
                  'expression-not-assigned',
                  'Used when an expression that is not a function call is assigned '
                  'to nothing. Probably something else was intended.'),
        'W0108': ('Lambda may not be necessary',
                  'unnecessary-lambda',
                  'Used when the body of a lambda expression is a function call '
                  'on the same argument list as the lambda itself; such lambda '
                  'expressions are in all but a few cases replaceable with the '
                  'function being called in the body of the lambda.'),
        'W0109': ("Duplicate key %r in dictionary",
                  'duplicate-key',
                  'Used when a dictionary expression binds the same key multiple '
                  'times.'),
        'W0122': ('Use of exec',
                  'exec-used',
                  'Used when you use the "exec" statement (function for Python '
                  '3), to discourage its usage. That doesn\'t '
                  'mean you can not use it !'),
        'W0123': ('Use of eval',
                  'eval-used',
                  'Used when you use the "eval" function, to discourage its '
                  'usage. Consider using `ast.literal_eval` for safely evaluating '
                  'strings containing Python expressions '
                  'from untrusted sources. '),
        'W0141': ('Used builtin function %r',
                  'bad-builtin',
                  'Used when a black listed builtin function is used (see the '
                  'bad-function option). Usual black listed functions are the ones '
                  'like map, or filter , where Python offers now some cleaner '
                  'alternative like list comprehension.'),
        'W0142': ('Used * or ** magic',
                  'star-args',
                  'Used when a function or method is called using `*args` or '
                  '`**kwargs` to dispatch arguments. This doesn\'t improve '
                  'readability and should be used with care.'),
        'W0150': ("%s statement in finally block may swallow exception",
                  'lost-exception',
                  'Used when a break or a return statement is found inside the '
                  'finally clause of a try...finally block: the exceptions raised '
                  'in the try clause will be silently swallowed instead of being '
                  're-raised.'),
        'W0199': ('Assert called on a 2-uple. Did you mean \'assert x,y\'?',
                  'assert-on-tuple',
                  'A call of assert on a tuple will always evaluate to true if '
                  'the tuple is not empty, and will always evaluate to false if '
                  'it is.'),
        'C0121': ('Missing required attribute "%s"', # W0103
                  'missing-module-attribute',
                  'Used when an attribute required for modules is missing.'),

        'E0109': ('Missing argument to reversed()',
                  'missing-reversed-argument',
                  'Used when reversed() builtin didn\'t receive an argument.'),
        'E0111': ('The first reversed() argument is not a sequence',
                  'bad-reversed-sequence',
                  'Used when the first argument to reversed() builtin '
                  'isn\'t a sequence (does not implement __reversed__, '
                  'nor __getitem__ and __len__'),

    }

    options = (('required-attributes',
                {'default' : (), 'type' : 'csv',
                 'metavar' : '<attributes>',
                 'help' : 'Required attributes for module, separated by a '
                          'comma'}
               ),
               ('bad-functions',
                {'default' : BAD_FUNCTIONS,
                 'type' :'csv', 'metavar' : '<builtin function names>',
                 'help' : 'List of builtins function names that should not be '
                          'used, separated by a comma'}
               ),
              )
    reports = (('RP0101', 'Statistics by type', report_by_type_stats),)

    def __init__(self, linter):
        _BasicChecker.__init__(self, linter)
        self.stats = None
        self._tryfinallys = None

    def open(self):
        """initialize visit variables and statistics
        """
        self._tryfinallys = []
        self.stats = self.linter.add_stats(module=0, function=0,
                                           method=0, class_=0)

    @check_messages('missing-module-attribute')
    def visit_module(self, node):
        """check module name, docstring and required arguments
        """
        self.stats['module'] += 1
        for attr in self.config.required_attributes:
            if attr not in node:
                self.add_message('missing-module-attribute', node=node, args=attr)

    def visit_class(self, node): # pylint: disable=unused-argument
        """check module name, docstring and redefinition
        increment branch counter
        """
        self.stats['class'] += 1

    @check_messages('pointless-statement', 'pointless-string-statement',
                    'expression-not-assigned')
    def visit_discard(self, node):
        """check for various kind of statements without effect"""
        expr = node.value
        if isinstance(expr, astroid.Const) and isinstance(expr.value,
                                                          six.string_types):
            # treat string statement in a separated message
            # Handle PEP-257 attribute docstrings.
            # An attribute docstring is defined as being a string right after
            # an assignment at the module level, class level or __init__ level.
            scope = expr.scope()
            if isinstance(scope, (astroid.Class, astroid.Module, astroid.Function)):
                if isinstance(scope, astroid.Function) and scope.name != '__init__':
                    pass
                else:
                    sibling = expr.previous_sibling()
                    if (sibling is not None and sibling.scope() is scope and
                            isinstance(sibling, astroid.Assign)):
                        return
            self.add_message('pointless-string-statement', node=node)
            return
        # ignore if this is :
        # * a direct function call
        # * the unique child of a try/except body
        # * a yield (which are wrapped by a discard node in _ast XXX)
        # warn W0106 if we have any underlying function call (we can't predict
        # side effects), else pointless-statement
        if (isinstance(expr, (astroid.Yield, astroid.CallFunc)) or
                (isinstance(node.parent, astroid.TryExcept) and
                 node.parent.body == [node])):
            return
        if any(expr.nodes_of_class(astroid.CallFunc)):
            self.add_message('expression-not-assigned', node=node,
                             args=expr.as_string())
        else:
            self.add_message('pointless-statement', node=node)

    @check_messages('unnecessary-lambda')
    def visit_lambda(self, node):
        """check whether or not the lambda is suspicious
        """
        # if the body of the lambda is a call expression with the same
        # argument list as the lambda itself, then the lambda is
        # possibly unnecessary and at least suspicious.
        if node.args.defaults:
            # If the arguments of the lambda include defaults, then a
            # judgment cannot be made because there is no way to check
            # that the defaults defined by the lambda are the same as
            # the defaults defined by the function called in the body
            # of the lambda.
            return
        call = node.body
        if not isinstance(call, astroid.CallFunc):
            # The body of the lambda must be a function call expression
            # for the lambda to be unnecessary.
            return
        # XXX are lambda still different with astroid >= 0.18 ?
        # *args and **kwargs need to be treated specially, since they
        # are structured differently between the lambda and the function
        # call (in the lambda they appear in the args.args list and are
        # indicated as * and ** by two bits in the lambda's flags, but
        # in the function call they are omitted from the args list and
        # are indicated by separate attributes on the function call node).
        ordinary_args = list(node.args.args)
        if node.args.kwarg:
            if (not call.kwargs
                    or not isinstance(call.kwargs, astroid.Name)
                    or node.args.kwarg != call.kwargs.name):
                return
        elif call.kwargs:
            return
        if node.args.vararg:
            if (not call.starargs
                    or not isinstance(call.starargs, astroid.Name)
                    or node.args.vararg != call.starargs.name):
                return
        elif call.starargs:
            return
        # The "ordinary" arguments must be in a correspondence such that:
        # ordinary_args[i].name == call.args[i].name.
        if len(ordinary_args) != len(call.args):
            return
        for i in range(len(ordinary_args)):
            if not isinstance(call.args[i], astroid.Name):
                return
            if node.args.args[i].name != call.args[i].name:
                return
        if (isinstance(node.body.func, astroid.Getattr) and
                isinstance(node.body.func.expr, astroid.CallFunc)):
            # Chained call, the intermediate call might
            # return something else (but we don't check that, yet).
            return
        self.add_message('unnecessary-lambda', line=node.fromlineno, node=node)

    @check_messages('dangerous-default-value')
    def visit_function(self, node):
        """check function name, docstring, arguments, redefinition,
        variable names, max locals
        """
        self.stats[node.is_method() and 'method' or 'function'] += 1
        self._check_dangerous_default(node)

    def _check_dangerous_default(self, node):
        # check for dangerous default values as arguments
        is_iterable = lambda n: isinstance(n, (astroid.List,
                                               astroid.Set,
                                               astroid.Dict))
        for default in node.args.defaults:
            try:
                value = next(default.infer())
            except astroid.InferenceError:
                continue

            if (isinstance(value, astroid.Instance) and
                    value.qname() in DEFAULT_ARGUMENT_SYMBOLS):

                if value is default:
                    msg = DEFAULT_ARGUMENT_SYMBOLS[value.qname()]
                elif type(value) is astroid.Instance or is_iterable(value):
                    # We are here in the following situation(s):
                    #   * a dict/set/list/tuple call which wasn't inferred
                    #     to a syntax node ({}, () etc.). This can happen
                    #     when the arguments are invalid or unknown to
                    #     the inference.
                    #   * a variable from somewhere else, which turns out to be a list
                    #     or a dict.
                    if is_iterable(default):
                        msg = value.pytype()
                    elif isinstance(default, astroid.CallFunc):
                        msg = '%s() (%s)' % (value.name, value.qname())
                    else:
                        msg = '%s (%s)' % (default.as_string(), value.qname())
                else:
                    # this argument is a name
                    msg = '%s (%s)' % (default.as_string(),
                                       DEFAULT_ARGUMENT_SYMBOLS[value.qname()])
                self.add_message('dangerous-default-value',
                                 node=node,
                                 args=(msg, ))

    @check_messages('unreachable', 'lost-exception')
    def visit_return(self, node):
        """1 - check is the node has a right sibling (if so, that's some
        unreachable code)
        2 - check is the node is inside the finally clause of a try...finally
        block
        """
        self._check_unreachable(node)
        # Is it inside final body of a try...finally bloc ?
        self._check_not_in_finally(node, 'return', (astroid.Function,))

    @check_messages('unreachable')
    def visit_continue(self, node):
        """check is the node has a right sibling (if so, that's some unreachable
        code)
        """
        self._check_unreachable(node)

    @check_messages('unreachable', 'lost-exception')
    def visit_break(self, node):
        """1 - check is the node has a right sibling (if so, that's some
        unreachable code)
        2 - check is the node is inside the finally clause of a try...finally
        block
        """
        # 1 - Is it right sibling ?
        self._check_unreachable(node)
        # 2 - Is it inside final body of a try...finally bloc ?
        self._check_not_in_finally(node, 'break', (astroid.For, astroid.While,))

    @check_messages('unreachable')
    def visit_raise(self, node):
        """check if the node has a right sibling (if so, that's some unreachable
        code)
        """
        self._check_unreachable(node)

    @check_messages('exec-used')
    def visit_exec(self, node):
        """just print a warning on exec statements"""
        self.add_message('exec-used', node=node)

    @check_messages('bad-builtin', 'star-args', 'eval-used',
                    'exec-used', 'missing-reversed-argument',
                    'bad-reversed-sequence')
    def visit_callfunc(self, node):
        """visit a CallFunc node -> check if this is not a blacklisted builtin
        call and check for * or ** use
        """
        if isinstance(node.func, astroid.Name):
            name = node.func.name
            # ignore the name if it's not a builtin (i.e. not defined in the
            # locals nor globals scope)
            if not (name in node.frame() or
                    name in node.root()):
                if name == 'exec':
                    self.add_message('exec-used', node=node)
                elif name == 'reversed':
                    self._check_reversed(node)
                elif name == 'eval':
                    self.add_message('eval-used', node=node)
                if name in self.config.bad_functions:
                    self.add_message('bad-builtin', node=node, args=name)
        if node.starargs or node.kwargs:
            scope = node.scope()
            if isinstance(scope, astroid.Function):
                toprocess = [(n, vn) for (n, vn) in ((node.starargs, scope.args.vararg),
                                                     (node.kwargs, scope.args.kwarg)) if n]
                if toprocess:
                    for cfnode, fargname in toprocess[:]:
                        if getattr(cfnode, 'name', None) == fargname:
                            toprocess.remove((cfnode, fargname))
                    if not toprocess:
                        return # star-args can be skipped
            self.add_message('star-args', node=node.func)

    @check_messages('assert-on-tuple')
    def visit_assert(self, node):
        """check the use of an assert statement on a tuple."""
        if node.fail is None and isinstance(node.test, astroid.Tuple) and \
                len(node.test.elts) == 2:
            self.add_message('assert-on-tuple', node=node)

    @check_messages('duplicate-key')
    def visit_dict(self, node):
        """check duplicate key in dictionary"""
        keys = set()
        for k, _ in node.items:
            if isinstance(k, astroid.Const):
                key = k.value
                if key in keys:
                    self.add_message('duplicate-key', node=node, args=key)
                keys.add(key)

    def visit_tryfinally(self, node):
        """update try...finally flag"""
        self._tryfinallys.append(node)

    def leave_tryfinally(self, node): # pylint: disable=unused-argument
        """update try...finally flag"""
        self._tryfinallys.pop()

    def _check_unreachable(self, node):
        """check unreachable code"""
        unreach_stmt = node.next_sibling()
        if unreach_stmt is not None:
            self.add_message('unreachable', node=unreach_stmt)

    def _check_not_in_finally(self, node, node_name, breaker_classes=()):
        """check that a node is not inside a finally clause of a
        try...finally statement.
        If we found before a try...finally bloc a parent which its type is
        in breaker_classes, we skip the whole check."""
        # if self._tryfinallys is empty, we're not a in try...finally bloc
        if not self._tryfinallys:
            return
        # the node could be a grand-grand...-children of the try...finally
        _parent = node.parent
        _node = node
        while _parent and not isinstance(_parent, breaker_classes):
            if hasattr(_parent, 'finalbody') and _node in _parent.finalbody:
                self.add_message('lost-exception', node=node, args=node_name)
                return
            _node = _parent
            _parent = _node.parent

    def _check_reversed(self, node):
        """ check that the argument to `reversed` is a sequence """
        try:
            argument = safe_infer(get_argument_from_call(node, position=0))
        except NoSuchArgumentError:
            self.add_message('missing-reversed-argument', node=node)
        else:
            if argument is astroid.YES:
                return
            if argument is None:
                # Nothing was infered.
                # Try to see if we have iter().
                if isinstance(node.args[0], astroid.CallFunc):
                    try:
                        func = next(node.args[0].func.infer())
                    except InferenceError:
                        return
                    if (getattr(func, 'name', None) == 'iter' and
                            is_builtin_object(func)):
                        self.add_message('bad-reversed-sequence', node=node)
                return

            if isinstance(argument, astroid.Instance):
                if (argument._proxied.name == 'dict' and
                        is_builtin_object(argument._proxied)):
                    self.add_message('bad-reversed-sequence', node=node)
                    return
                elif any(ancestor.name == 'dict' and is_builtin_object(ancestor)
                         for ancestor in argument._proxied.ancestors()):
                    # mappings aren't accepted by reversed()
                    self.add_message('bad-reversed-sequence', node=node)
                    return

                for methods in REVERSED_METHODS:
                    for meth in methods:
                        try:
                            argument.getattr(meth)
                        except astroid.NotFoundError:
                            break
                    else:
                        break
                else:
                    # Check if it is a .deque. It doesn't seem that
                    # we can retrieve special methods
                    # from C implemented constructs.
                    if argument._proxied.qname().endswith(".deque"):
                        return
                    self.add_message('bad-reversed-sequence', node=node)
            elif not isinstance(argument, (astroid.List, astroid.Tuple)):
                # everything else is not a proper sequence for reversed()
                self.add_message('bad-reversed-sequence', node=node)

_NAME_TYPES = {
    'module': (MOD_NAME_RGX, 'module'),
    'const': (CONST_NAME_RGX, 'constant'),
    'class': (CLASS_NAME_RGX, 'class'),
    'function': (DEFAULT_NAME_RGX, 'function'),
    'method': (DEFAULT_NAME_RGX, 'method'),
    'attr': (DEFAULT_NAME_RGX, 'attribute'),
    'argument': (DEFAULT_NAME_RGX, 'argument'),
    'variable': (DEFAULT_NAME_RGX, 'variable'),
    'class_attribute': (CLASS_ATTRIBUTE_RGX, 'class attribute'),
    'inlinevar': (COMP_VAR_RGX, 'inline iteration'),
}

def _create_naming_options():
    name_options = []
    for name_type, (rgx, human_readable_name) in six.iteritems(_NAME_TYPES):
        name_type = name_type.replace('_', '-')
        name_options.append((
            '%s-rgx' % (name_type,),
            {'default': rgx, 'type': 'regexp', 'metavar': '<regexp>',
             'help': 'Regular expression matching correct %s names' % (human_readable_name,)}))
        name_options.append((
            '%s-name-hint' % (name_type,),
            {'default': rgx.pattern, 'type': 'string', 'metavar': '<string>',
             'help': 'Naming hint for %s names' % (human_readable_name,)}))
    return tuple(name_options)

class NameChecker(_BasicChecker):
    msgs = {
        'C0102': ('Black listed name "%s"',
                  'blacklisted-name',
                  'Used when the name is listed in the black list (unauthorized '
                  'names).'),
        'C0103': ('Invalid %s name "%s"%s',
                  'invalid-name',
                  'Used when the name doesn\'t match the regular expression '
                  'associated to its type (constant, variable, class...).'),
    }

    options = (('good-names',
                {'default' : ('i', 'j', 'k', 'ex', 'Run', '_'),
                 'type' :'csv', 'metavar' : '<names>',
                 'help' : 'Good variable names which should always be accepted,'
                          ' separated by a comma'}
               ),
               ('bad-names',
                {'default' : ('foo', 'bar', 'baz', 'toto', 'tutu', 'tata'),
                 'type' :'csv', 'metavar' : '<names>',
                 'help' : 'Bad variable names which should always be refused, '
                          'separated by a comma'}
               ),
               ('name-group',
                {'default' : (),
                 'type' :'csv', 'metavar' : '<name1:name2>',
                 'help' : ('Colon-delimited sets of names that determine each'
                           ' other\'s naming style when the name regexes'
                           ' allow several styles.')}
               ),
               ('include-naming-hint',
                {'default': False, 'type' : 'yn', 'metavar' : '<y_or_n>',
                 'help': 'Include a hint for the correct naming format with invalid-name'}
               ),
              ) + _create_naming_options()


    def __init__(self, linter):
        _BasicChecker.__init__(self, linter)
        self._name_category = {}
        self._name_group = {}
        self._bad_names = {}

    def open(self):
        self.stats = self.linter.add_stats(badname_module=0,
                                           badname_class=0, badname_function=0,
                                           badname_method=0, badname_attr=0,
                                           badname_const=0,
                                           badname_variable=0,
                                           badname_inlinevar=0,
                                           badname_argument=0,
                                           badname_class_attribute=0)
        for group in self.config.name_group:
            for name_type in group.split(':'):
                self._name_group[name_type] = 'group_%s' % (group,)

    @check_messages('blacklisted-name', 'invalid-name')
    def visit_module(self, node):
        self._check_name('module', node.name.split('.')[-1], node)
        self._bad_names = {}

    def leave_module(self, node): # pylint: disable=unused-argument
        for all_groups in six.itervalues(self._bad_names):
            if len(all_groups) < 2:
                continue
            groups = collections.defaultdict(list)
            min_warnings = sys.maxsize
            for group in six.itervalues(all_groups):
                groups[len(group)].append(group)
                min_warnings = min(len(group), min_warnings)
            if len(groups[min_warnings]) > 1:
                by_line = sorted(groups[min_warnings],
                                 key=lambda group: min(warning[0].lineno for warning in group))
                warnings = itertools.chain(*by_line[1:])
            else:
                warnings = groups[min_warnings][0]
            for args in warnings:
                self._raise_name_warning(*args)

    @check_messages('blacklisted-name', 'invalid-name')
    def visit_class(self, node):
        self._check_name('class', node.name, node)
        for attr, anodes in six.iteritems(node.instance_attrs):
            if not list(node.instance_attr_ancestors(attr)):
                self._check_name('attr', attr, anodes[0])

    @check_messages('blacklisted-name', 'invalid-name')
    def visit_function(self, node):
        # Do not emit any warnings if the method is just an implementation
        # of a base class method.
        confidence = HIGH
        if node.is_method():
            if overrides_a_method(node.parent.frame(), node.name):
                return
            confidence = (INFERENCE if has_known_bases(node.parent.frame())
                          else INFERENCE_FAILURE)

        self._check_name(_determine_function_name_type(node),
                         node.name, node, confidence)
        # Check argument names
        args = node.args.args
        if args is not None:
            self._recursive_check_names(args, node)

    @check_messages('blacklisted-name', 'invalid-name')
    def visit_global(self, node):
        for name in node.names:
            self._check_name('const', name, node)

    @check_messages('blacklisted-name', 'invalid-name')
    def visit_assname(self, node):
        """check module level assigned names"""
        frame = node.frame()
        ass_type = node.ass_type()
        if isinstance(ass_type, astroid.Comprehension):
            self._check_name('inlinevar', node.name, node)
        elif isinstance(frame, astroid.Module):
            if isinstance(ass_type, astroid.Assign) and not in_loop(ass_type):
                if isinstance(safe_infer(ass_type.value), astroid.Class):
                    self._check_name('class', node.name, node)
                else:
                    if not _redefines_import(node):
                        # Don't emit if the name redefines an import
                        # in an ImportError except handler.
                        self._check_name('const', node.name, node)
            elif isinstance(ass_type, astroid.ExceptHandler):
                self._check_name('variable', node.name, node)
        elif isinstance(frame, astroid.Function):
            # global introduced variable aren't in the function locals
            if node.name in frame and node.name not in frame.argnames():
                if not _redefines_import(node):
                    self._check_name('variable', node.name, node)
        elif isinstance(frame, astroid.Class):
            if not list(frame.local_attr_ancestors(node.name)):
                self._check_name('class_attribute', node.name, node)

    def _recursive_check_names(self, args, node):
        """check names in a possibly recursive list <arg>"""
        for arg in args:
            if isinstance(arg, astroid.AssName):
                self._check_name('argument', arg.name, node)
            else:
                self._recursive_check_names(arg.elts, node)

    def _find_name_group(self, node_type):
        return self._name_group.get(node_type, node_type)

    def _raise_name_warning(self, node, node_type, name, confidence):
        type_label = _NAME_TYPES[node_type][1]
        hint = ''
        if self.config.include_naming_hint:
            hint = ' (hint: %s)' % (getattr(self.config, node_type + '_name_hint'))
        self.add_message('invalid-name', node=node, args=(type_label, name, hint),
                         confidence=confidence)
        self.stats['badname_' + node_type] += 1

    def _check_name(self, node_type, name, node, confidence=HIGH):
        """check for a name using the type's regexp"""
        if is_inside_except(node):
            clobbering, _ = clobber_in_except(node)
            if clobbering:
                return
        if name in self.config.good_names:
            return
        if name in self.config.bad_names:
            self.stats['badname_' + node_type] += 1
            self.add_message('blacklisted-name', node=node, args=name)
            return
        regexp = getattr(self.config, node_type + '_rgx')
        match = regexp.match(name)

        if _is_multi_naming_match(match, node_type, confidence):
            name_group = self._find_name_group(node_type)
            bad_name_group = self._bad_names.setdefault(name_group, {})
            warnings = bad_name_group.setdefault(match.lastgroup, [])
            warnings.append((node, node_type, name, confidence))

        if match is None:
            self._raise_name_warning(node, node_type, name, confidence)


class DocStringChecker(_BasicChecker):
    msgs = {
        'C0111': ('Missing %s docstring', # W0131
                  'missing-docstring',
                  'Used when a module, function, class or method has no docstring.'
                  'Some special methods like __init__ doesn\'t necessary require a '
                  'docstring.'),
        'C0112': ('Empty %s docstring', # W0132
                  'empty-docstring',
                  'Used when a module, function, class or method has an empty '
                  'docstring (it would be too easy ;).'),
        }
    options = (('no-docstring-rgx',
                {'default' : NO_REQUIRED_DOC_RGX,
                 'type' : 'regexp', 'metavar' : '<regexp>',
                 'help' : 'Regular expression which should only match '
                          'function or class names that do not require a '
                          'docstring.'}
               ),
               ('docstring-min-length',
                {'default' : -1,
                 'type' : 'int', 'metavar' : '<int>',
                 'help': ('Minimum line length for functions/classes that'
                          ' require docstrings, shorter ones are exempt.')}
               ),
              )


    def open(self):
        self.stats = self.linter.add_stats(undocumented_module=0,
                                           undocumented_function=0,
                                           undocumented_method=0,
                                           undocumented_class=0)
    @check_messages('missing-docstring', 'empty-docstring')
    def visit_module(self, node):
        self._check_docstring('module', node)

    @check_messages('missing-docstring', 'empty-docstring')
    def visit_class(self, node):
        if self.config.no_docstring_rgx.match(node.name) is None:
            self._check_docstring('class', node)

    @check_messages('missing-docstring', 'empty-docstring')
    def visit_function(self, node):
        if self.config.no_docstring_rgx.match(node.name) is None:
            ftype = node.is_method() and 'method' or 'function'
            if isinstance(node.parent.frame(), astroid.Class):
                overridden = False
                confidence = (INFERENCE if has_known_bases(node.parent.frame())
                              else INFERENCE_FAILURE)
                # check if node is from a method overridden by its ancestor
                for ancestor in node.parent.frame().ancestors():
                    if node.name in ancestor and \
                       isinstance(ancestor[node.name], astroid.Function):
                        overridden = True
                        break
                self._check_docstring(ftype, node,
                                      report_missing=not overridden,
                                      confidence=confidence)
            else:
                self._check_docstring(ftype, node)

    def _check_docstring(self, node_type, node, report_missing=True,
                         confidence=HIGH):
        """check the node has a non empty docstring"""
        docstring = node.doc
        if docstring is None:
            if not report_missing:
                return
            if node.body:
                lines = node.body[-1].lineno - node.body[0].lineno + 1
            else:
                lines = 0
            max_lines = self.config.docstring_min_length

            if node_type != 'module' and max_lines > -1 and lines < max_lines:
                return
            self.stats['undocumented_'+node_type] += 1
            if (node.body and isinstance(node.body[0], astroid.Discard) and
                    isinstance(node.body[0].value, astroid.CallFunc)):
                # Most likely a string with a format call. Let's see.
                func = safe_infer(node.body[0].value.func)
                if (isinstance(func, astroid.BoundMethod)
                        and isinstance(func.bound, astroid.Instance)):
                    # Strings in Python 3, others in Python 2.
                    if PY3K and func.bound.name == 'str':
                        return
                    elif func.bound.name in ('str', 'unicode', 'bytes'):
                        return
            self.add_message('missing-docstring', node=node, args=(node_type,),
                             confidence=confidence)
        elif not docstring.strip():
            self.stats['undocumented_'+node_type] += 1
            self.add_message('empty-docstring', node=node, args=(node_type,),
                             confidence=confidence)


class PassChecker(_BasicChecker):
    """check if the pass statement is really necessary"""
    msgs = {'W0107': ('Unnecessary pass statement',
                      'unnecessary-pass',
                      'Used when a "pass" statement that can be avoided is '
                      'encountered.'),
           }
    @check_messages('unnecessary-pass')
    def visit_pass(self, node):
        if len(node.parent.child_sequence(node)) > 1:
            self.add_message('unnecessary-pass', node=node)


class LambdaForComprehensionChecker(_BasicChecker):
    """check for using a lambda where a comprehension would do.

    See <http://www.artima.com/weblogs/viewpost.jsp?thread=98196>
    where GvR says comprehensions would be clearer.
    """

    msgs = {'W0110': ('map/filter on lambda could be replaced by comprehension',
                      'deprecated-lambda',
                      'Used when a lambda is the first argument to "map" or '
                      '"filter". It could be clearer as a list '
                      'comprehension or generator expression.',
                      {'maxversion': (3, 0)}),
           }

    @check_messages('deprecated-lambda')
    def visit_callfunc(self, node):
        """visit a CallFunc node, check if map or filter are called with a
        lambda
        """
        if not node.args:
            return
        if not isinstance(node.args[0], astroid.Lambda):
            return
        infered = safe_infer(node.func)
        if (is_builtin_object(infered)
                and infered.name in ['map', 'filter']):
            self.add_message('deprecated-lambda', node=node)


def register(linter):
    """required method to auto register this checker"""
    linter.register_checker(BasicErrorChecker(linter))
    linter.register_checker(BasicChecker(linter))
    linter.register_checker(NameChecker(linter))
    linter.register_checker(DocStringChecker(linter))
    linter.register_checker(PassChecker(linter))
    linter.register_checker(LambdaForComprehensionChecker(linter))
