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)
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
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
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
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
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
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
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
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