From: Thomas V. S. <tho...@us...> - 2011-01-25 10:32:33
|
Update of /cvsroot/pychecker/pychecker/pychecker In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv23632/pychecker Modified Files: CodeChecks.py Stack.py Log Message: * HACKING: Add debian note. * pychecker/CodeChecks.py: Add a FIXME for an internal warning. * pychecker/Stack.py: Comment, document, and assert assumptions related to attributes and indirections. Index: CodeChecks.py =================================================================== RCS file: /cvsroot/pychecker/pychecker/pychecker/CodeChecks.py,v retrieving revision 1.227 retrieving revision 1.228 diff -u -d -r1.227 -r1.228 --- CodeChecks.py 25 Jan 2011 08:44:45 -0000 1.227 +++ CodeChecks.py 25 Jan 2011 10:32:24 -0000 1.228 @@ -1561,6 +1561,7 @@ def _LOAD_ATTR(oparg, operand, codeSource, code) : # FIXME: how can LOAD_ATTR happen without a stack ? + # FIXME: add an internal warning here if len(code.stack) > 0 : top = code.stack[-1] _checkAttribute(top, operand, codeSource, code) Index: Stack.py =================================================================== RCS file: /cvsroot/pychecker/pychecker/pychecker/Stack.py,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- Stack.py 9 Jan 2011 17:19:43 -0000 1.27 +++ Stack.py 25 Jan 2011 10:32:24 -0000 1.28 @@ -21,6 +21,8 @@ TYPE_GLOBAL = "-global-" TYPE_EXCEPT = "-except-" +# conventions for Items: +# a method call has data ('self', methodName), type ATTRIBUTE class Item: """ Representation of data on the stack @@ -72,8 +74,31 @@ return self.data is None and self.const def isMethodCall(self, c, methodArgName): - return self.type == TYPE_ATTRIBUTE and c != None and \ - len(self.data) == 2 and self.data[0] == methodArgName + """ + @param methodArgName: the first argument + Check if the stack item is a method call. + + @type methodArgName: str + @param methodArgName: the name of the first argument for method calls; + usually self. + """ + if self.type != TYPE_ATTRIBUTE: + return False + + # FIXME: we only check if c is not None; that doesn't mean it + # has the given methodArgName + if c is None: + return False + + if len(self.data) != 2: + # no object indirection happening + return False + + if self.data[0] != methodArgName: + # indirection does not start with first argument for method calls + return False + + return True def isLocals(self): return self.type == types.DictType and self.data == LOCALS @@ -111,6 +136,8 @@ return TYPE_UNKNOWN def getName(self): + # if the item is an attribute but not a string, it's a tuple + # of object indirections if self.type == TYPE_ATTRIBUTE and type(self.data) != types.StringType: strValue = "" # convert the tuple into a string ('self', 'data') -> self.data @@ -120,10 +147,27 @@ return utils.safestr(self.data) def addAttribute(self, attr): - if type(self.data) == types.TupleType: - self.data = self.data + (attr,) - else: - self.data = (self.data, attr) + """ + Replaces self with a stack item representing the dereferencing of + its attribute. + + For example, if the stack item describes a class, calling this method + will replace the stack item with one describing the attribute of + this class. + + @type attr: str + """ + # only called through LOAD_ATTR, which replaces TOS with the + # dereferencing result + assert type(attr) is str + + # make sure that adding an attribute makes data a tuple if it + # wasn't yet + if type(self.data) != types.TupleType: + self.data = (self.data, ) + + self.data = self.data + (attr,) + self.type = TYPE_ATTRIBUTE |