def _handleNestedCode(func_code, code, codeSource): """ @param func_code: the code object for the nested code @type func_code: L{types.CodeType} @param code: the parent code in which the code is nested @type code: L{CodeChecks.Code} @type codeSource: L{Codechecks.CodeSource} """ nested = not (codeSource.main or codeSource.in_class) if func_code.co_name == utils.LAMBDA or nested: utils.debug(' handling nested code %s under %r for %r', func_code.co_name, codeSource.func, code.func) varnames = None if nested and func_code.co_name != utils.LAMBDA: varnames = func_code.co_varnames + \ codeSource.calling_code[-1].function.func_code.co_varnames # save the original func return value and restore after checking func = code.func returnValues = code.returnValues # we don't want suppressions from nested code to bleed into the # containing code block, or the next nested code on the same level utils.pushConfig() code.init( function.create_fake(func_code.co_name, func_code, {}, varnames)) _checkCode(code, codeSource) utils.popConfig() # restore code.init(func) code.returnValues = returnValues
def _handleNestedCode(func_code, code, codeSource): """ @param func_code: the code object for the nested code @type func_code: L{types.CodeType} @param code: the parent code in which the code is nested @type code: L{CodeChecks.Code} @type codeSource: L{Codechecks.CodeSource} """ nested = not (codeSource.main or codeSource.in_class) if func_code.co_name == utils.LAMBDA or nested: utils.debug(' handling nested code %s under %r for %r', func_code.co_name, codeSource.func, code.func) varnames = None if nested and func_code.co_name != utils.LAMBDA: varnames = func_code.co_varnames + \ codeSource.calling_code[-1].function.func_code.co_varnames # save the original func return value and restore after checking func = code.func returnValues = code.returnValues # we don't want suppressions from nested code to bleed into the # containing code block, or the next nested code on the same level utils.pushConfig() code.init(function.create_fake(func_code.co_name, func_code, {}, varnames)) _checkCode(code, codeSource) utils.popConfig() # restore code.init(func) code.returnValues = returnValues
def _handleNestedCode(func_code, code, codeSource): nested = not (codeSource.main or codeSource.in_class) if func_code.co_name == utils.LAMBDA or nested: utils.debug(' handling nested code') varnames = None if nested and func_code.co_name != utils.LAMBDA: varnames = func_code.co_varnames + \ codeSource.calling_code[-1].function.func_code.co_varnames # save the original return value and restore after checking returnValues = code.returnValues code.init(function.create_fake(func_code.co_name, func_code, {}, varnames)) _checkCode(code, codeSource) code.returnValues = returnValues
def _handleNestedCode(func_code, code, codeSource): nested = not (codeSource.main or codeSource.in_class) if func_code.co_name == utils.LAMBDA or nested: utils.debug(' handling nested code') varnames = None if nested and func_code.co_name != utils.LAMBDA: varnames = func_code.co_varnames + \ codeSource.calling_code[-1].function.func_code.co_varnames # save the original return value and restore after checking returnValues = code.returnValues code.init( function.create_fake(func_code.co_name, func_code, {}, varnames)) _checkCode(code, codeSource) code.returnValues = returnValues
def _handleNestedCode(func_code, code, codeSource): nested = not (codeSource.main or codeSource.in_class) if func_code.co_name == utils.LAMBDA or nested: utils.debug(' handling nested code %s under %r', func_code.co_name, codeSource.func) varnames = None if nested and func_code.co_name != utils.LAMBDA: varnames = func_code.co_varnames + \ codeSource.calling_code[-1].function.func_code.co_varnames # save the original return value and restore after checking returnValues = code.returnValues # we don't want suppressions from nested code to bleed into the # containing code block, or the next nested code on the same level utils.pushConfig() code.init(function.create_fake(func_code.co_name, func_code, {}, varnames)) _checkCode(code, codeSource) utils.popConfig() code.returnValues = returnValues
def _findClassWarnings(module, c, class_code, globalRefs, warnings, suppressions) : try: className = utils.safestr(c.classObject) except TypeError: # goofy __getattr__ return classSuppress = getSuppression(className, suppressions, warnings) baseClasses = c.allBaseClasses() for base in baseClasses : baseModule = utils.safestr(base) if '.' in baseModule : # make sure we handle import x.y.z packages = string.split(baseModule, '.') baseModuleDir = string.join(packages[:-1], '.') globalRefs[baseModuleDir] = baseModule # handle class variables if class_code is not None : func = function.create_fake(c.name, class_code) _updateFunctionWarnings(module, func, c, warnings, globalRefs, 0, 1) filename = module.filename() func_code = None for method in c.methods.values() : if method == None : continue func_code = method.function.func_code utils.debug("method:", func_code) try: name = utils.safestr(c.classObject) + '.' + method.function.func_name except AttributeError: # func_name may not exist continue methodSuppress = getSuppression(name, suppressions, warnings) if cfg().checkSpecialMethods: funcname = method.function.func_name if funcname[:2] == '__' == funcname[-2:] and \ funcname != '__init__': err = None argCount = python.SPECIAL_METHODS.get(funcname, -1) if argCount != -1: # if the args are None, it can be any # of args if argCount is not None: minArgs = maxArgs = argCount err = CodeChecks.getFunctionArgErr(funcname, func_code.co_argcount, minArgs, maxArgs) else: err = msgs.NOT_SPECIAL_METHOD % funcname if err is not None: warnings.append(Warning(filename, func_code, err)) if cfg().checkOverridenMethods : _checkOverridenMethods(method.function, baseClasses, warnings) if cfg().noDocFunc and method.function.__doc__ == None : err = msgs.NO_FUNC_DOC % method.function.__name__ # FIXME: is there a good reason why this passes func_code as line ? warnings.append(Warning(filename, func_code, err)) _checkSelfArg(method, warnings) tmpModule = _getModuleFromFilename(module, func_code.co_filename) funcInfo = _updateFunctionWarnings(tmpModule, method, c, warnings, globalRefs) if func_code.co_name == utils.INIT : # this is a constructor if utils.INIT in dir(c.classObject) : warns = _checkBaseClassInit(filename, c, func_code, funcInfo) warnings.extend(warns) elif cfg().initDefinedInSubclass : err = msgs.NO_INIT_IN_SUBCLASS % c.name warnings.append(Warning(filename, c.getFirstLine(), err)) if methodSuppress is not None : utils.popConfig() if c.memberRefs and cfg().membersUsed : memberList = c.memberRefs.keys() memberList.sort() err = msgs.UNUSED_MEMBERS % (string.join(memberList, ', '), c.name) warnings.append(Warning(filename, c.getFirstLine(), err)) try: newStyleClass = issubclass(c.classObject, object) except TypeError: # FIXME: perhaps this should warn b/c it may be a class??? newStyleClass = 0 slots = c.statics.get('__slots__') if slots is not None and cfg().slots: lineNum = c.lineNums['__slots__'] if not newStyleClass: err = msgs.USING_SLOTS_IN_CLASSIC_CLASS % c.name warnings.append(Warning(filename, lineNum, err)) elif cfg().emptySlots: try: if len(slots.data) == 0: err = msgs.EMPTY_SLOTS % c.name warnings.append(Warning(filename, lineNum, err)) except AttributeError: # happens when slots is an instance of a class w/o __len__ pass if not newStyleClass and property is not None and cfg().classicProperties: for static in c.statics.keys(): if type(getattr(c.classObject, static, None)) == property: err = msgs.USING_PROPERTIES_IN_CLASSIC_CLASS % (static, c.name) warnings.append(Warning(filename, c.lineNums[static], err)) coerceMethod = c.methods.get('__coerce__') if newStyleClass and coerceMethod: lineNum = coerceMethod.function.func_code.co_firstlineno err = msgs.USING_COERCE_IN_NEW_CLASS % c.name warnings.append(Warning(filename, lineNum, err)) for newClassMethodName in python.NEW_STYLE_CLASS_METHODS: newClassMethod = c.methods.get(newClassMethodName) if not newStyleClass and newClassMethod: lineNum = newClassMethod.function.func_code.co_firstlineno err = msgs.USING_NEW_STYLE_METHOD_IN_OLD_CLASS % (newClassMethodName, c.name) warnings.append(Warning(filename, lineNum, err)) if cfg().noDocClass and c.classObject.__doc__ == None : method = c.methods.get(utils.INIT, None) if method != None : func_code = method.function.func_code # FIXME: check to make sure this is in our file, # not a base class file??? err = msgs.NO_CLASS_DOC % c.classObject.__name__ warnings.append(Warning(filename, func_code, err)) # we have to do this here, b/c checkFunction doesn't popConfig for classes # this allows us to have __pychecker__ apply to all methods # when defined at class scope if class_code is not None : utils.popConfig() if classSuppress is not None : utils.popConfig()
def _findClassWarnings(module, c, class_code, globalRefs, warnings, suppressions) : utils.debug("class:", class_code) try: className = utils.safestr(c.classObject) except TypeError: # goofy __getattr__ return classSuppress = getSuppression(className, suppressions, warnings) baseClasses = c.allBaseClasses() for base in baseClasses : baseModule = utils.safestr(base) if '.' in baseModule : # make sure we handle import x.y.z packages = string.split(baseModule, '.') baseModuleDir = string.join(packages[:-1], '.') globalRefs[baseModuleDir] = baseModule # handle class variables if class_code is not None : func = function.create_fake(c.name, class_code) _updateFunctionWarnings(module, func, c, warnings, globalRefs, 0, 1) filename = module.filename() func_code = None for method in c.methods.values() : if method == None : continue func_code = method.function.func_code utils.debug("class %s: method:" % className, func_code) try: name = utils.safestr(c.classObject) + '.' + method.function.func_name except AttributeError: # func_name may not exist continue methodSuppress = getSuppression(name, suppressions, warnings) if cfg().checkSpecialMethods: funcname = method.function.func_name if funcname[:2] == '__' == funcname[-2:] and \ funcname != '__init__': err = None argCount = python.SPECIAL_METHODS.get(funcname, -1) if argCount != -1: # if the args are None, it can be any # of args if argCount is not None: minArgs = maxArgs = argCount err = CodeChecks.getFunctionArgErr(funcname, func_code.co_argcount, minArgs, maxArgs) else: err = msgs.NOT_SPECIAL_METHOD % funcname if err is not None: warnings.append(Warning(filename, func_code, err)) if cfg().checkOverridenMethods : _checkOverridenMethods(method.function, baseClasses, warnings) if cfg().noDocFunc and method.function.__doc__ == None : err = msgs.NO_FUNC_DOC % method.function.__name__ # FIXME: is there a good reason why this passes func_code as line ? warnings.append(Warning(filename, func_code, err)) _checkSelfArg(method, warnings) tmpModule = _getModuleFromFilename(module, func_code.co_filename) funcInfo = _updateFunctionWarnings(tmpModule, method, c, warnings, globalRefs) if func_code.co_name == utils.INIT : # this is a constructor if utils.INIT in dir(c.classObject) : warns = _checkBaseClassInit(filename, c, func_code, funcInfo) warnings.extend(warns) elif cfg().initDefinedInSubclass : err = msgs.NO_INIT_IN_SUBCLASS % c.name warnings.append(Warning(filename, c.getFirstLine(), err)) if methodSuppress is not None : utils.popConfig() if c.memberRefs and cfg().membersUsed : memberList = c.memberRefs.keys() memberList.sort() err = msgs.UNUSED_MEMBERS % (string.join(memberList, ', '), c.name) warnings.append(Warning(filename, c.getFirstLine(), err)) try: newStyleClass = issubclass(c.classObject, object) except TypeError: # FIXME: perhaps this should warn b/c it may be a class??? newStyleClass = 0 slots = c.statics.get('__slots__') if slots is not None and cfg().slots: lineNum = c.lineNums['__slots__'] if not newStyleClass: err = msgs.USING_SLOTS_IN_CLASSIC_CLASS % c.name warnings.append(Warning(filename, lineNum, err)) elif cfg().emptySlots: try: if len(slots.data) == 0: err = msgs.EMPTY_SLOTS % c.name warnings.append(Warning(filename, lineNum, err)) except AttributeError: # happens when slots is an instance of a class w/o __len__ pass if not newStyleClass and property is not None and cfg().classicProperties: for static in c.statics.keys(): if type(getattr(c.classObject, static, None)) == property: err = msgs.USING_PROPERTIES_IN_CLASSIC_CLASS % (static, c.name) warnings.append(Warning(filename, c.lineNums[static], err)) coerceMethod = c.methods.get('__coerce__') if newStyleClass and coerceMethod: lineNum = coerceMethod.function.func_code.co_firstlineno err = msgs.USING_COERCE_IN_NEW_CLASS % c.name warnings.append(Warning(filename, lineNum, err)) for newClassMethodName in python.NEW_STYLE_CLASS_METHODS: newClassMethod = c.methods.get(newClassMethodName) if not newStyleClass and newClassMethod: lineNum = newClassMethod.function.func_code.co_firstlineno err = msgs.USING_NEW_STYLE_METHOD_IN_OLD_CLASS % (newClassMethodName, c.name) warnings.append(Warning(filename, lineNum, err)) if cfg().noDocClass and c.classObject.__doc__ == None : method = c.methods.get(utils.INIT, None) if method != None : func_code = method.function.func_code # FIXME: check to make sure this is in our file, # not a base class file??? err = msgs.NO_CLASS_DOC % c.classObject.__name__ warnings.append(Warning(filename, func_code, err)) # we have to do this here, b/c checkFunction doesn't popConfig for classes # this allows us to have __pychecker__ apply to all methods # when defined at class scope if class_code is not None : utils.popConfig() if classSuppress is not None : utils.popConfig()