Example #1
0
def _checkReturnWarnings(code) :
    is_getattr = code.func_code.co_name in ('__getattr__', '__getattribute__')
    if is_getattr :
        for line, retval, dummy in code.returnValues :
            if retval.isNone() :
                err = msgs.DONT_RETURN_NONE % code.func_code.co_name
                code.addWarning(err, line+1)

    # there must be at least 2 real return values to check for consistency
    returnValuesLen = len(code.returnValues)
    if returnValuesLen < 2 :
        return

    # if the last return is implicit, check if there are non None returns
    lastReturn = code.returnValues[-1]

    # Python 2.4 optimizes the dead implicit return out, so we can't
    # distinguish implicit and explicit "return None"
    if utils.pythonVersion() < utils.PYTHON_2_4 and \
           not code.starts_and_ends_with_finally and \
           cfg().checkImplicitReturns and lastReturn[1].isImplicitNone():
        for line, retval, dummy in code.returnValues[:-1] :
            if not retval.isNone() :
                code.addWarning(msgs.IMPLICIT_AND_EXPLICIT_RETURNS,
                                lastReturn[0]+1)
                break

    # __get*__ funcs can return different types, don't warn about inconsistency
    if utils.startswith(code.func_code.co_name, '__get') and \
       utils.endswith(code.func_code.co_name, '__') :
        return

    returnType, returnData = None, None
    for line, value, dummy in code.returnValues :
        if not value.isNone() :
            valueType = value.getType(code.typeMap)
            if returnType is None and valueType not in _IGNORE_RETURN_TYPES :
                returnData = value
                returnType = valueType
                continue

            # always ignore None, None can be returned w/any other type
            # FIXME: if we stored func return values, we could do better
            if returnType is not None and not value.isNone() and \
               valueType not in _IGNORE_RETURN_TYPES and \
               returnData.type not in _IGNORE_RETURN_TYPES :
                ok = returnType in (type(value.data), valueType)
                if ok :
                    if returnType == types.TupleType :
                        # FIXME: this isn't perfect, if len == 0
                        # the length can really be 0 OR unknown
                        # we shouldn't check the lengths for equality
                        # ONLY IF one of the lengths is truly unknown
                        if returnData.length > 0 and value.length > 0:
                            ok = returnData.length == value.length
                else :
                    ok = _checkSubclass(returnType, valueType) or \
                         _checkSubclass(valueType, returnType)
                if not ok :
                    code.addWarning(msgs.INCONSISTENT_RETURN_TYPE, line)
Example #2
0
def _checkReturnWarnings(code) :
    is_getattr = code.func_code.co_name in ('__getattr__', '__getattribute__')
    if is_getattr :
        for line, retval, dummy in code.returnValues :
            if retval.isNone() :
                err = msgs.DONT_RETURN_NONE % code.func_code.co_name
                code.addWarning(err, line+1)

    # there must be at least 2 real return values to check for consistency
    returnValuesLen = len(code.returnValues)
    if returnValuesLen < 2 :
        return

    # if the last return is implicit, check if there are non None returns
    lastReturn = code.returnValues[-1]

    # Python 2.4 optimizes the dead implicit return out, so we can't
    # distinguish implicit and explicit "return None"
    if utils.pythonVersion() < utils.PYTHON_2_4 and \
           not code.starts_and_ends_with_finally and \
           cfg().checkImplicitReturns and lastReturn[1].isImplicitNone():
        for line, retval, dummy in code.returnValues[:-1] :
            if not retval.isNone() :
                code.addWarning(msgs.IMPLICIT_AND_EXPLICIT_RETURNS,
                                lastReturn[0]+1)
                break

    # __get*__ funcs can return different types, don't warn about inconsistency
    if utils.startswith(code.func_code.co_name, '__get') and \
       utils.endswith(code.func_code.co_name, '__') :
        return

    returnType, returnData = None, None
    for line, value, dummy in code.returnValues :
        if not value.isNone() :
            valueType = value.getType(code.typeMap)
            if returnType is None and valueType not in _IGNORE_RETURN_TYPES :
                returnData = value
                returnType = valueType
                continue

            # always ignore None, None can be returned w/any other type
            # FIXME: if we stored func return values, we could do better
            if returnType is not None and not value.isNone() and \
               valueType not in _IGNORE_RETURN_TYPES and \
               returnData.type not in _IGNORE_RETURN_TYPES :
                ok = returnType in (type(value.data), valueType)
                if ok :
                    if returnType == types.TupleType :
                        # FIXME: this isn't perfect, if len == 0
                        # the length can really be 0 OR unknown
                        # we shouldn't check the lengths for equality
                        # ONLY IF one of the lengths is truly unknown
                        if returnData.length > 0 and value.length > 0:
                            ok = returnData.length == value.length
                else :
                    ok = _checkSubclass(returnType, valueType) or \
                         _checkSubclass(valueType, returnType)
                if not ok :
                    code.addWarning(msgs.INCONSISTENT_RETURN_TYPE, line)
Example #3
0
def _name_unused(var) :
    if var in cfg().unusedNames :
        return 0
    for name in cfg().unusedNames :
        if name != '_' and utils.startswith(var, name) :
            return 0
    return 1
Example #4
0
def _name_unused(var) :
    if var in cfg().unusedNames :
        return 0
    for name in cfg().unusedNames :
        if name != '_' and utils.startswith(var, name) :
            return 0
    return 1
Example #5
0
def _getUnused(module, globalRefs, dict, msg, filterPrefix=None):
    """
    Return a list of warnings for unused globals.

    

    For example, for modules:
      from twisted.internet import defer
    would result in
      'defer' -> PyCheckerModule at 0x...: twisted.internet.defer

    @param globalRefs: dict of token alias -> full name of token aliases
                       that have been used ?
    @type  globalRefs: dict of str -> str
    @param dict:       dict of token alias -> token containing the tokens
                       to check for use
    @type  dict:       dict of str -> token
    @param msg:        the message template to use to create warnings
    @type  msg:        str from L{msgs}
    """

    import pprint

    warnings = []

    for ref in dict.keys():
        check = not filterPrefix or utils.startswith(ref, filterPrefix)
        # FIXME: do a ref in globalRefs instead?
        if check and globalRefs.get(ref) == None:
            lineInfo = module.moduleLineNums.get(ref)
            if lineInfo:
                warnings.append(Warning(lineInfo[0], lineInfo[1], msg % ref))

    return warnings
Example #6
0
def _getUnused(module, globalRefs, dict, msg, filterPrefix = None) :
    """
    Return a list of warnings for unused globals.

    

    For example, for modules:
      from twisted.internet import defer
    would result in
      'defer' -> PyCheckerModule at 0x...: twisted.internet.defer

    @param globalRefs: dict of token alias -> full name of token aliases
                       that have been used ?
    @type  globalRefs: dict of str -> str
    @param dict:       dict of token alias -> token containing the tokens
                       to check for use
    @type  dict:       dict of str -> token
    @param msg:        the message template to use to create warnings
    @type  msg:        str from L{msgs}
    """

    import pprint

    warnings = []

    for ref in dict.keys():
        check = not filterPrefix or utils.startswith(ref, filterPrefix)
        # FIXME: do a ref in globalRefs instead?
        if check and globalRefs.get(ref) == None :
            lineInfo = module.moduleLineNums.get(ref)
            if lineInfo:
                warnings.append(Warning(lineInfo[0], lineInfo[1], msg % ref))

    return warnings
Example #7
0
def _getUnused(module, globalRefs, dict, msg, filterPrefix = None) :
    "Return a list of warnings for unused globals"

    warnings = []
    for ref in dict.keys() :
        check = not filterPrefix or utils.startswith(ref, filterPrefix)
        if check and globalRefs.get(ref) == None :
            lineInfo = module.moduleLineNums.get(ref)
            if lineInfo:
                warnings.append(Warning(lineInfo[0], lineInfo[1], msg % ref))
    return warnings
Example #8
0
def _getUnused(module, globalRefs, dict, msg, filterPrefix = None) :
    "Return a list of warnings for unused globals"

    warnings = []
    for ref in dict.keys() :
        check = not filterPrefix or utils.startswith(ref, filterPrefix)
        if check and globalRefs.get(ref) == None :
            lineInfo = module.moduleLineNums.get(ref)
            if lineInfo:
                warnings.append(Warning(lineInfo[0], lineInfo[1], msg % ref))
    return warnings
Example #9
0
def removeWarnings(warnings, blacklist, std_lib, cfg):
    if std_lib is not None:
        std_lib = normalize_path(std_lib)
    for index in range(len(warnings)-1, -1, -1) :
        filename = normalize_path(warnings[index].file)
        if filename in blacklist or (std_lib is not None and
                                     utils.startswith(filename, std_lib)) :
            del warnings[index]
        elif cfg.only:
            # ignore files not specified on the cmd line if requested
            if os.path.abspath(filename) not in cfg.files:
                del warnings[index]

        # filter by warning/error level if requested
        if cfg.level and warnings[index].level < cfg.level:
            del warnings[index]

    if cfg.limit:
        # sort by severity first, then normal sort (by file/line)
        warnings.sort(lambda a, b: cmp(a.level, b.level) or cmp(a, b))

        # strip duplicates
        lastWarning = None
        for index in range(len(warnings)-1, -1, -1):
            warning = warnings[index]

            # remove duplicate warnings
            if lastWarning is not None and cmp(lastWarning, warning) == 0:
                del warnings[index]
            else:
                lastWarning = warning

        num_ignored = len(warnings) - cfg.limit
        if num_ignored > 0:
            del warnings[:-cfg.limit]
            msg = msgs.TOO_MANY_WARNINGS % num_ignored
            warnings.append(Warning('', 0, msg))

    return warnings
Example #10
0
def removeWarnings(warnings, blacklist, std_lib, cfg):
    if std_lib is not None:
        std_lib = normalize_path(std_lib)
    for index in range(len(warnings) - 1, -1, -1):
        filename = normalize_path(warnings[index].file)
        if filename in blacklist or (std_lib is not None
                                     and utils.startswith(filename, std_lib)):
            del warnings[index]
        elif cfg.only:
            # ignore files not specified on the cmd line if requested
            if os.path.abspath(filename) not in cfg.files:
                del warnings[index]

        # filter by warning/error level if requested
        if cfg.level and warnings[index].level < cfg.level:
            del warnings[index]

    if cfg.limit:
        # sort by severity first, then normal sort (by file/line)
        warnings.sort(lambda a, b: cmp(a.level, b.level) or cmp(a, b))

        # strip duplicates
        lastWarning = None
        for index in range(len(warnings) - 1, -1, -1):
            warning = warnings[index]

            # remove duplicate warnings
            if lastWarning is not None and cmp(lastWarning, warning) == 0:
                del warnings[index]
            else:
                lastWarning = warning

        num_ignored = len(warnings) - cfg.limit
        if num_ignored > 0:
            del warnings[:-cfg.limit]
            msg = msgs.TOO_MANY_WARNINGS % num_ignored
            warnings.append(Warning('', 0, msg))

    return warnings
Example #11
0
def removeWarnings(warnings, blacklist, std_lib, cfg):
    """
    @param blacklist: list of absolute paths not to warn for
    @type  blacklist: str
    @param std_lib:   list of standard library directories
    @type  std_lib:   list of str or None
    """
    if std_lib is not None:
        std_lib = [normalize_path(p) for p in std_lib]
    for index in range(len(warnings)-1, -1, -1) :
        filename = normalize_path(warnings[index].file)
        # the blacklist contains paths to packages and modules we do not
        # want warnings for
        # when we find a match, make sure we continue the warnings for loop
        found = False
        for path in blacklist:
            if not found and filename.startswith(path):
                found = True
                del warnings[index]
        if found:
            continue
        if std_lib:
            found = False
            for path in std_lib:
                if not found and utils.startswith(filename, path) :
                    found = True
                    del warnings[index]
            if found:
                continue
        elif cfg.only:
            # ignore files not specified on the cmd line if requested
            if os.path.abspath(filename) not in cfg.files:
                del warnings[index]
                continue

        # filter by warning/error level if requested
        if cfg.level and warnings[index].level < cfg.level:
            del warnings[index]

    if cfg.limit:
        # sort by severity first, then normal sort (by file/line)
        warnings.sort(lambda a, b: cmp(a.level, b.level) or cmp(a, b))

        # strip duplicates
        lastWarning = None
        for index in range(len(warnings)-1, -1, -1):
            warning = warnings[index]

            # remove duplicate warnings
            if lastWarning is not None and cmp(lastWarning, warning) == 0:
                del warnings[index]
            else:
                lastWarning = warning

        num_ignored = len(warnings) - cfg.limit
        if num_ignored > 0:
            del warnings[:-cfg.limit]
            msg = msgs.TOO_MANY_WARNINGS % num_ignored
            warnings.append(Warning('', 0, msg))

    return warnings
Example #12
0
def removeWarnings(warnings, blacklist, std_lib, cfg):
    """
    @param blacklist: list of absolute paths not to warn for
    @type  blacklist: str
    @param std_lib:   list of standard library directories
    @type  std_lib:   list of str or None
    """
    utils.debug('filtering %d warnings with blacklist', len(warnings))

    if std_lib is not None:
        std_lib = [normalize_path(p) for p in std_lib]
    for index in range(len(warnings) - 1, -1, -1):
        filename = normalize_path(warnings[index].file)
        # the blacklist contains paths to packages and modules we do not
        # want warnings for
        # when we find a match, make sure we continue the warnings for loop
        found = False
        for path in blacklist:
            if not found and filename.startswith(path):
                found = True
                del warnings[index]
        if found:
            continue
        if std_lib:
            found = False
            for path in std_lib:
                if not found and utils.startswith(filename, path) :
                    found = True
                    del warnings[index]
            if found:
                continue
        elif cfg.only:
            # ignore files not specified on the cmd line if requested
            if os.path.abspath(filename) not in cfg.files:
                del warnings[index]
                continue

        # filter by warning/error level if requested
        if cfg.level and warnings[index].level < cfg.level:
            del warnings[index]

    if cfg.limit:
        # sort by severity first, then normal sort (by file/line)
        warnings.sort(lambda a, b: cmp(a.level, b.level) or cmp(a, b))

        # strip duplicates
        lastWarning = None
        for index in range(len(warnings)-1, -1, -1):
            warning = warnings[index]

            # remove duplicate warnings
            if lastWarning is not None and cmp(lastWarning, warning) == 0:
                del warnings[index]
            else:
                lastWarning = warning

        num_ignored = len(warnings) - cfg.limit
        if num_ignored > 0:
            del warnings[:-cfg.limit]
            msg = msgs.TOO_MANY_WARNINGS % num_ignored
            warnings.append(Warning('', 0, msg))

    utils.debug('kept %d warnings with blacklist', len(warnings))

    return warnings