def __init__(self, name, pcmodule): """ @type name: str @type pcmodule: L{PyCheckerModule} """ self.name = name module = pcmodule.module self.classObject = getattr(module, name) modname = getattr(self.classObject, '__module__', None) if modname is None: # hm, some ExtensionClasses don't have a __module__ attribute # so try parsing the type output typerepr = repr(type(self.classObject)) mo = re.match("^<type ['\"](.+)['\"]>$", typerepr) if mo: modname = ".".join(mo.group(1).split(".")[:-1]) # TODO(nnorwitz): this check for __name__ might not be necessary # any more. Previously we checked objects as if they were classes. # This problem is fixed by not adding objects as if they are classes. # zope.interface for example has Provides and Declaration that # look a lot like class objects but do not have __name__ if not hasattr(self.classObject, '__name__'): if modname not in utils.cfg().blacklist: sys.stderr.write("warning: no __name__ attribute " "for class %s (module name: %s)\n" % (self.classObject, modname)) self.classObject.__name__ = name # later pychecker code uses this self.classObject__name__ = self.classObject.__name__ self.module = sys.modules.get(modname) # if the pcmodule has moduleDir, it means we processed it before, # and deleted it from sys.modules if not self.module and pcmodule.moduleDir is None: self.module = module if modname not in utils.cfg().blacklist \ and not modname.startswith('_'): sys.stderr.write("warning: couldn't find real module " "for class %s (module name: %s)\n" % (self.classObject, modname)) self.ignoreAttrs = 0 self.methods = {} self.members = { '__class__': types.ClassType, '__doc__': types.StringType, '__dict__': types.DictType, } self.memberRefs = {} self.statics = {} self.lineNums = {}
def addMembersFromMethod(self, method) : if not hasattr(method, 'func_code') : return func_code, code, i, maxCode, extended_arg = OP.initFuncCode(method) stack = [] while i < maxCode : op, oparg, i, extended_arg = OP.getInfo(code, i, extended_arg) if op >= OP.HAVE_ARGUMENT : operand = OP.getOperand(op, func_code, oparg) if OP.LOAD_CONST(op) or OP.LOAD_FAST(op) or OP.LOAD_GLOBAL(op): stack.append(operand) elif OP.LOAD_DEREF(op): try: operand = func_code.co_cellvars[oparg] except IndexError: index = oparg - len(func_code.co_cellvars) operand = func_code.co_freevars[index] stack.append(operand) elif OP.STORE_ATTR(op) : if len(stack) > 0 : if stack[-1] == utils.cfg().methodArgName: value = None if len(stack) > 1 : value = type(stack[-2]) self.members[operand] = value self.memberRefs[operand] = None stack = [] self.cleanupMemberRefs()
def addMembersFromMethod(self, method): if not hasattr(method, 'func_code'): return func_code, code, i, maxCode, extended_arg = OP.initFuncCode(method) stack = [] while i < maxCode: op, oparg, i, extended_arg = OP.getInfo(code, i, extended_arg) if op >= OP.HAVE_ARGUMENT: operand = OP.getOperand(op, func_code, oparg) if OP.LOAD_CONST(op) or OP.LOAD_FAST(op) or OP.LOAD_GLOBAL(op): stack.append(operand) elif OP.LOAD_DEREF(op): try: operand = func_code.co_cellvars[oparg] except IndexError: index = oparg - len(func_code.co_cellvars) operand = func_code.co_freevars[index] stack.append(operand) elif OP.STORE_ATTR(op): if len(stack) > 0: if stack[-1] == utils.cfg().methodArgName: value = None if len(stack) > 1: value = type(stack[-2]) self.members[operand] = value self.memberRefs[operand] = None stack = [] self.cleanupMemberRefs()
def load(self, allowImportError=False): """ @param allowImportError: if True, do not catch ImportError but reraise them, so caller can know this module does not exist. """ try: # there's no need to reload modules we already have if no moduleDir # is specified for this module # NOTE: self.moduleDir can be '' if the module tested lives in # the current working directory if self.moduleDir is None: module = sys.modules.get(self.moduleName) if module: pcmodule = getPCModule(self.moduleName) if not pcmodule.module: return self._initModule(module) return 1 return self._initModule(self.setupMainCode()) except (SystemExit, KeyboardInterrupt): exc_type, exc_value, exc_tb = sys.exc_info() raise exc_type, exc_value except Exception, e: if allowImportError: raise utils.importError(self.moduleName, self.moduleDir) return utils.cfg().ignoreImportErrors
def load(self, allowImportError=False): """ @param allowImportError: if True, do not catch ImportError but reraise them, so caller can know this module does not exist. """ try : # there's no need to reload modules we already have if no moduleDir # is specified for this module # NOTE: self.moduleDir can be '' if the module tested lives in # the current working directory if self.moduleDir is None: module = sys.modules.get(self.moduleName) if module: pcmodule = getPCModule(self.moduleName) if not pcmodule.module: return self._initModule(module) return 1 return self._initModule(self.setupMainCode()) except (SystemExit, KeyboardInterrupt): exc_type, exc_value, exc_tb = sys.exc_info() raise exc_type, exc_value except Exception, e: if allowImportError: raise utils.importError(self.moduleName, self.moduleDir) return utils.cfg().ignoreImportErrors
def addMembers(self, classObject) : if not utils.cfg().onlyCheckInitForMembers : for classToken in _getClassTokens(classObject) : method = getattr(classObject, classToken, None) if type(method) == types.MethodType : self.addMembersFromMethod(method.im_func) else: try: self.addMembersFromMethod(classObject.__init__.im_func) except AttributeError: pass
def addMembers(self, classObject): if not utils.cfg().onlyCheckInitForMembers: for classToken in _getClassTokens(classObject): method = getattr(classObject, classToken, None) if type(method) == types.MethodType: self.addMembersFromMethod(method.im_func) else: try: self.addMembersFromMethod(classObject.__init__.im_func) except AttributeError: pass
def addClass(self, name): self.classes[name] = c = Class(name, self) try: objName = utils.safestr(c.classObject) except TypeError: # this can happen if there is a goofy __getattr__ c.ignoreAttrs = 1 else: packages = string.split(objName, '.') c.ignoreAttrs = packages[0] in utils.cfg().blacklist if not c.ignoreAttrs : self.__addAttributes(c, c.classObject)
def addClass(self, name): self.classes[name] = c = Class(name, self) try: objName = utils.safestr(c.classObject) except TypeError: # this can happen if there is a goofy __getattr__ c.ignoreAttrs = 1 else: packages = string.split(objName, '.') c.ignoreAttrs = packages[0] in utils.cfg().blacklist if not c.ignoreAttrs: self.__addAttributes(c, c.classObject)
def load(self): try : # there's no need to reload modules we already have if no moduleDir # is specified for this module # NOTE: self.moduleDir can be '' if the module tested lives in # the current working directory if self.moduleDir is None: module = sys.modules.get(self.moduleName) if module: pcmodule = getPCModule(self.moduleName) if not pcmodule.module: return self._initModule(module) return 1 return self._initModule(self.setupMainCode()) except (SystemExit, KeyboardInterrupt): exc_type, exc_value, exc_tb = sys.exc_info() raise exc_type, exc_value except: utils.importError(self.moduleName, self.moduleDir) return utils.cfg().ignoreImportErrors
def load(self): try: # there's no need to reload modules we already have if no moduleDir # is specified for this module # NOTE: self.moduleDir can be '' if the module tested lives in # the current working directory if self.moduleDir is None: module = sys.modules.get(self.moduleName) if module: pcmodule = getPCModule(self.moduleName) if not pcmodule.module: return self._initModule(module) return 1 return self._initModule(self.setupMainCode()) except (SystemExit, KeyboardInterrupt): exc_type, exc_value, exc_tb = sys.exc_info() raise exc_type, exc_value except: utils.importError(self.moduleName, self.moduleDir) return utils.cfg().ignoreImportErrors
def _initModule(self, module): self.module = module self.attributes = dir(self.module) # interpret module-specific suppressions pychecker_attr = getattr(module, Config.CHECKER_VAR, None) if pychecker_attr is not None : utils.pushConfig() utils.updateCheckerArgs(pychecker_attr, 'suppressions', 0, []) # read all tokens from the real module, and register them for tokenName in _getModuleTokens(self.module): if EVIL_C_OBJECTS.has_key('%s.%s' % (self.moduleName, tokenName)): continue # README if interpreter is crashing: # Change 0 to 1 if the interpretter is crashing and re-run. # Follow the instructions from the last line printed. if utils.cfg().findEvil: print "Add the following line to EVIL_C_OBJECTS or the string to evil in a config file:\n" \ " '%s.%s': None, " % (self.moduleName, tokenName) token = getattr(self.module, tokenName) if isinstance(token, types.ModuleType) : # get the real module name, tokenName could be an alias self.addModule(token.__name__) elif isinstance(token, types.FunctionType) : self.addFunction(token) elif isinstance(token, types.ClassType) or \ hasattr(token, '__bases__') and \ issubclass(type(token), type): self.addClass(tokenName) else : self.addVariable(tokenName, type(token)) if pychecker_attr is not None : utils.popConfig() return 1
def _initModule(self, module): self.module = module self.attributes = dir(self.module) # interpret module-specific suppressions pychecker_attr = getattr(module, Config.CHECKER_VAR, None) if pychecker_attr is not None: utils.pushConfig() utils.updateCheckerArgs(pychecker_attr, 'suppressions', 0, []) # read all tokens from the real module, and register them for tokenName in _getModuleTokens(self.module): if EVIL_C_OBJECTS.has_key('%s.%s' % (self.moduleName, tokenName)): continue # README if interpreter is crashing: # Change 0 to 1 if the interpretter is crashing and re-run. # Follow the instructions from the last line printed. if utils.cfg().findEvil: print "Add the following line to EVIL_C_OBJECTS or the string to evil in a config file:\n" \ " '%s.%s': None, " % (self.moduleName, tokenName) token = getattr(self.module, tokenName) if isinstance(token, types.ModuleType): # get the real module name, tokenName could be an alias self.addModule(token.__name__) elif isinstance(token, types.FunctionType): self.addFunction(token) elif isinstance(token, types.ClassType) or \ hasattr(token, '__bases__') and \ issubclass(type(token), type): self.addClass(tokenName) else: self.addVariable(tokenName, type(token)) if pychecker_attr is not None: utils.popConfig() return 1
def cfg(): return utils.cfg()
def cfg() : return utils.cfg()