Sat, 13 Nov 2010 19:51:38 +0100
Backported the improved the py3flakes checker.
--- a/APIs/Python3/eric5.api Fri Nov 12 19:17:44 2010 +0100 +++ b/APIs/Python3/eric5.api Sat Nov 13 19:51:38 2010 +0100 @@ -5674,53 +5674,33 @@ eric5.Utilities.pwDecode?4(epw) eric5.Utilities.pwEncode?4(pw) eric5.Utilities.py3flakes.checker.Binding?1(name, source) -eric5.Utilities.py3flakes.checker.Checker.ASSERT?4(node) eric5.Utilities.py3flakes.checker.Checker.ASSIGN?4(node) -eric5.Utilities.py3flakes.checker.Checker.ATTRIBUTE?4(node) eric5.Utilities.py3flakes.checker.Checker.ATTRIBUTES?7 eric5.Utilities.py3flakes.checker.Checker.AUGASSIGN?4(node) -eric5.Utilities.py3flakes.checker.Checker.BINOP?4(node) -eric5.Utilities.py3flakes.checker.Checker.BOOLOP?4(node) -eric5.Utilities.py3flakes.checker.Checker.CALL?4(node) +eric5.Utilities.py3flakes.checker.Checker.BOOLOP?7 +eric5.Utilities.py3flakes.checker.Checker.CALL?7 eric5.Utilities.py3flakes.checker.Checker.CLASSDEF?4(node) -eric5.Utilities.py3flakes.checker.Checker.COMPARE?4(node) -eric5.Utilities.py3flakes.checker.Checker.COMPREHENSION?4(node) -eric5.Utilities.py3flakes.checker.Checker.DELETE?4(node) -eric5.Utilities.py3flakes.checker.Checker.DICT?4(node) +eric5.Utilities.py3flakes.checker.Checker.COMPREHENSION?7 eric5.Utilities.py3flakes.checker.Checker.DICTCOMP?4(node) eric5.Utilities.py3flakes.checker.Checker.EXCEPTHANDLER?4(node) -eric5.Utilities.py3flakes.checker.Checker.EXPR?4(node) -eric5.Utilities.py3flakes.checker.Checker.EXTSLICE?4(node) eric5.Utilities.py3flakes.checker.Checker.FOR?4(node) eric5.Utilities.py3flakes.checker.Checker.FUNCTIONDEF?4(node) eric5.Utilities.py3flakes.checker.Checker.GLOBAL?4(node) -eric5.Utilities.py3flakes.checker.Checker.IF?4(node) -eric5.Utilities.py3flakes.checker.Checker.IFEXP?4(node) eric5.Utilities.py3flakes.checker.Checker.IMPORT?4(node) eric5.Utilities.py3flakes.checker.Checker.IMPORTFROM?4(node) -eric5.Utilities.py3flakes.checker.Checker.INDEX?4(node) eric5.Utilities.py3flakes.checker.Checker.INVERT?7 -eric5.Utilities.py3flakes.checker.Checker.KEYWORD?4(node) +eric5.Utilities.py3flakes.checker.Checker.ISNOT?7 eric5.Utilities.py3flakes.checker.Checker.LAMBDA?4(node) -eric5.Utilities.py3flakes.checker.Checker.LIST?4(node) eric5.Utilities.py3flakes.checker.Checker.LISTCOMP?4(node) +eric5.Utilities.py3flakes.checker.Checker.LOAD?7 eric5.Utilities.py3flakes.checker.Checker.MOD?7 eric5.Utilities.py3flakes.checker.Checker.NAME?4(node) eric5.Utilities.py3flakes.checker.Checker.NONLOCAL?7 eric5.Utilities.py3flakes.checker.Checker.PASS?7 -eric5.Utilities.py3flakes.checker.Checker.RAISE?4(node) -eric5.Utilities.py3flakes.checker.Checker.RETURN?4(node) -eric5.Utilities.py3flakes.checker.Checker.SET?7 +eric5.Utilities.py3flakes.checker.Checker.RETURN?7 eric5.Utilities.py3flakes.checker.Checker.SETCOMP?7 -eric5.Utilities.py3flakes.checker.Checker.SLICE?4(node) +eric5.Utilities.py3flakes.checker.Checker.SLICE?7 eric5.Utilities.py3flakes.checker.Checker.STARRED?4(node) -eric5.Utilities.py3flakes.checker.Checker.SUBSCRIPT?4(node) -eric5.Utilities.py3flakes.checker.Checker.TRYEXCEPT?4(node) -eric5.Utilities.py3flakes.checker.Checker.TRYFINALLY?4(node) -eric5.Utilities.py3flakes.checker.Checker.UNARYOP?4(node) -eric5.Utilities.py3flakes.checker.Checker.WHILE?7 -eric5.Utilities.py3flakes.checker.Checker.WITH?4(node) -eric5.Utilities.py3flakes.checker.Checker.YIELD?4(node) eric5.Utilities.py3flakes.checker.Checker._runDeferred?5(deferred) eric5.Utilities.py3flakes.checker.Checker.addArgs?4() eric5.Utilities.py3flakes.checker.Checker.addBinding?4(lineno, value, reportRedef = True) @@ -5731,8 +5711,10 @@ eric5.Utilities.py3flakes.checker.Checker.deferFunction?4(callable) eric5.Utilities.py3flakes.checker.Checker.handleAssignName?4(node) eric5.Utilities.py3flakes.checker.Checker.handleBody?4(tree) +eric5.Utilities.py3flakes.checker.Checker.handleChildren?4(tree) eric5.Utilities.py3flakes.checker.Checker.handleNode?4(node, parent) eric5.Utilities.py3flakes.checker.Checker.ignore?4(node) +eric5.Utilities.py3flakes.checker.Checker.isDocstring?4(node) eric5.Utilities.py3flakes.checker.Checker.nodeDepth?7 eric5.Utilities.py3flakes.checker.Checker.popScope?4() eric5.Utilities.py3flakes.checker.Checker.pushClassScope?4()
--- a/Documentation/Help/source.qhp Fri Nov 12 19:17:44 2010 +0100 +++ b/Documentation/Help/source.qhp Sat Nov 13 19:51:38 2010 +0100 @@ -6643,45 +6643,20 @@ <keyword name="Binding.__repr__" id="Binding.__repr__" ref="eric5.Utilities.py3flakes.checker.html#Binding.__repr__" /> <keyword name="Binding.__str__" id="Binding.__str__" ref="eric5.Utilities.py3flakes.checker.html#Binding.__str__" /> <keyword name="Checker (Constructor)" id="Checker (Constructor)" ref="eric5.Utilities.py3flakes.checker.html#Checker.__init__" /> - <keyword name="Checker.ASSERT" id="Checker.ASSERT" ref="eric5.Utilities.py3flakes.checker.html#Checker.ASSERT" /> <keyword name="Checker.ASSIGN" id="Checker.ASSIGN" ref="eric5.Utilities.py3flakes.checker.html#Checker.ASSIGN" /> - <keyword name="Checker.ATTRIBUTE" id="Checker.ATTRIBUTE" ref="eric5.Utilities.py3flakes.checker.html#Checker.ATTRIBUTE" /> <keyword name="Checker.AUGASSIGN" id="Checker.AUGASSIGN" ref="eric5.Utilities.py3flakes.checker.html#Checker.AUGASSIGN" /> - <keyword name="Checker.BINOP" id="Checker.BINOP" ref="eric5.Utilities.py3flakes.checker.html#Checker.BINOP" /> - <keyword name="Checker.BOOLOP" id="Checker.BOOLOP" ref="eric5.Utilities.py3flakes.checker.html#Checker.BOOLOP" /> - <keyword name="Checker.CALL" id="Checker.CALL" ref="eric5.Utilities.py3flakes.checker.html#Checker.CALL" /> <keyword name="Checker.CLASSDEF" id="Checker.CLASSDEF" ref="eric5.Utilities.py3flakes.checker.html#Checker.CLASSDEF" /> - <keyword name="Checker.COMPARE" id="Checker.COMPARE" ref="eric5.Utilities.py3flakes.checker.html#Checker.COMPARE" /> - <keyword name="Checker.COMPREHENSION" id="Checker.COMPREHENSION" ref="eric5.Utilities.py3flakes.checker.html#Checker.COMPREHENSION" /> - <keyword name="Checker.DELETE" id="Checker.DELETE" ref="eric5.Utilities.py3flakes.checker.html#Checker.DELETE" /> - <keyword name="Checker.DICT" id="Checker.DICT" ref="eric5.Utilities.py3flakes.checker.html#Checker.DICT" /> <keyword name="Checker.DICTCOMP" id="Checker.DICTCOMP" ref="eric5.Utilities.py3flakes.checker.html#Checker.DICTCOMP" /> <keyword name="Checker.EXCEPTHANDLER" id="Checker.EXCEPTHANDLER" ref="eric5.Utilities.py3flakes.checker.html#Checker.EXCEPTHANDLER" /> - <keyword name="Checker.EXPR" id="Checker.EXPR" ref="eric5.Utilities.py3flakes.checker.html#Checker.EXPR" /> - <keyword name="Checker.EXTSLICE" id="Checker.EXTSLICE" ref="eric5.Utilities.py3flakes.checker.html#Checker.EXTSLICE" /> <keyword name="Checker.FOR" id="Checker.FOR" ref="eric5.Utilities.py3flakes.checker.html#Checker.FOR" /> <keyword name="Checker.FUNCTIONDEF" id="Checker.FUNCTIONDEF" ref="eric5.Utilities.py3flakes.checker.html#Checker.FUNCTIONDEF" /> <keyword name="Checker.GLOBAL" id="Checker.GLOBAL" ref="eric5.Utilities.py3flakes.checker.html#Checker.GLOBAL" /> - <keyword name="Checker.IF" id="Checker.IF" ref="eric5.Utilities.py3flakes.checker.html#Checker.IF" /> - <keyword name="Checker.IFEXP" id="Checker.IFEXP" ref="eric5.Utilities.py3flakes.checker.html#Checker.IFEXP" /> <keyword name="Checker.IMPORT" id="Checker.IMPORT" ref="eric5.Utilities.py3flakes.checker.html#Checker.IMPORT" /> <keyword name="Checker.IMPORTFROM" id="Checker.IMPORTFROM" ref="eric5.Utilities.py3flakes.checker.html#Checker.IMPORTFROM" /> - <keyword name="Checker.INDEX" id="Checker.INDEX" ref="eric5.Utilities.py3flakes.checker.html#Checker.INDEX" /> - <keyword name="Checker.KEYWORD" id="Checker.KEYWORD" ref="eric5.Utilities.py3flakes.checker.html#Checker.KEYWORD" /> <keyword name="Checker.LAMBDA" id="Checker.LAMBDA" ref="eric5.Utilities.py3flakes.checker.html#Checker.LAMBDA" /> - <keyword name="Checker.LIST" id="Checker.LIST" ref="eric5.Utilities.py3flakes.checker.html#Checker.LIST" /> <keyword name="Checker.LISTCOMP" id="Checker.LISTCOMP" ref="eric5.Utilities.py3flakes.checker.html#Checker.LISTCOMP" /> <keyword name="Checker.NAME" id="Checker.NAME" ref="eric5.Utilities.py3flakes.checker.html#Checker.NAME" /> - <keyword name="Checker.RAISE" id="Checker.RAISE" ref="eric5.Utilities.py3flakes.checker.html#Checker.RAISE" /> - <keyword name="Checker.RETURN" id="Checker.RETURN" ref="eric5.Utilities.py3flakes.checker.html#Checker.RETURN" /> - <keyword name="Checker.SLICE" id="Checker.SLICE" ref="eric5.Utilities.py3flakes.checker.html#Checker.SLICE" /> <keyword name="Checker.STARRED" id="Checker.STARRED" ref="eric5.Utilities.py3flakes.checker.html#Checker.STARRED" /> - <keyword name="Checker.SUBSCRIPT" id="Checker.SUBSCRIPT" ref="eric5.Utilities.py3flakes.checker.html#Checker.SUBSCRIPT" /> - <keyword name="Checker.TRYEXCEPT" id="Checker.TRYEXCEPT" ref="eric5.Utilities.py3flakes.checker.html#Checker.TRYEXCEPT" /> - <keyword name="Checker.TRYFINALLY" id="Checker.TRYFINALLY" ref="eric5.Utilities.py3flakes.checker.html#Checker.TRYFINALLY" /> - <keyword name="Checker.UNARYOP" id="Checker.UNARYOP" ref="eric5.Utilities.py3flakes.checker.html#Checker.UNARYOP" /> - <keyword name="Checker.WITH" id="Checker.WITH" ref="eric5.Utilities.py3flakes.checker.html#Checker.WITH" /> - <keyword name="Checker.YIELD" id="Checker.YIELD" ref="eric5.Utilities.py3flakes.checker.html#Checker.YIELD" /> <keyword name="Checker._runDeferred" id="Checker._runDeferred" ref="eric5.Utilities.py3flakes.checker.html#Checker._runDeferred" /> <keyword name="Checker.addArgs" id="Checker.addArgs" ref="eric5.Utilities.py3flakes.checker.html#Checker.addArgs" /> <keyword name="Checker.addBinding" id="Checker.addBinding" ref="eric5.Utilities.py3flakes.checker.html#Checker.addBinding" /> @@ -6692,8 +6667,10 @@ <keyword name="Checker.deferFunction" id="Checker.deferFunction" ref="eric5.Utilities.py3flakes.checker.html#Checker.deferFunction" /> <keyword name="Checker.handleAssignName" id="Checker.handleAssignName" ref="eric5.Utilities.py3flakes.checker.html#Checker.handleAssignName" /> <keyword name="Checker.handleBody" id="Checker.handleBody" ref="eric5.Utilities.py3flakes.checker.html#Checker.handleBody" /> + <keyword name="Checker.handleChildren" id="Checker.handleChildren" ref="eric5.Utilities.py3flakes.checker.html#Checker.handleChildren" /> <keyword name="Checker.handleNode" id="Checker.handleNode" ref="eric5.Utilities.py3flakes.checker.html#Checker.handleNode" /> <keyword name="Checker.ignore" id="Checker.ignore" ref="eric5.Utilities.py3flakes.checker.html#Checker.ignore" /> + <keyword name="Checker.isDocstring" id="Checker.isDocstring" ref="eric5.Utilities.py3flakes.checker.html#Checker.isDocstring" /> <keyword name="Checker.popScope" id="Checker.popScope" ref="eric5.Utilities.py3flakes.checker.html#Checker.popScope" /> <keyword name="Checker.pushClassScope" id="Checker.pushClassScope" ref="eric5.Utilities.py3flakes.checker.html#Checker.pushClassScope" /> <keyword name="Checker.pushFunctionScope" id="Checker.pushFunctionScope" ref="eric5.Utilities.py3flakes.checker.html#Checker.pushFunctionScope" />
--- a/Documentation/Source/eric5.Utilities.py3flakes.checker.html Fri Nov 12 19:17:44 2010 +0100 +++ b/Documentation/Source/eric5.Utilities.py3flakes.checker.html Sat Nov 13 19:51:38 2010 +0100 @@ -160,7 +160,7 @@ object <h3>Class Attributes</h3> <table> -<tr><td>ATTRIBUTES</td></tr><tr><td>INVERT</td></tr><tr><td>MOD</td></tr><tr><td>NONLOCAL</td></tr><tr><td>PASS</td></tr><tr><td>SET</td></tr><tr><td>SETCOMP</td></tr><tr><td>WHILE</td></tr><tr><td>nodeDepth</td></tr><tr><td>scope</td></tr><tr><td>traceTree</td></tr> +<tr><td>ATTRIBUTES</td></tr><tr><td>BOOLOP</td></tr><tr><td>CALL</td></tr><tr><td>COMPREHENSION</td></tr><tr><td>INVERT</td></tr><tr><td>ISNOT</td></tr><tr><td>LOAD</td></tr><tr><td>MOD</td></tr><tr><td>NONLOCAL</td></tr><tr><td>PASS</td></tr><tr><td>RETURN</td></tr><tr><td>SETCOMP</td></tr><tr><td>SLICE</td></tr><tr><td>nodeDepth</td></tr><tr><td>scope</td></tr><tr><td>traceTree</td></tr> </table> <h3>Methods</h3> <table> @@ -168,54 +168,21 @@ <td><a href="#Checker.__init__">Checker</a></td> <td>Constructor</td> </tr><tr> -<td><a href="#Checker.ASSERT">ASSERT</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.ASSIGN">ASSIGN</a></td> <td></td> </tr><tr> -<td><a href="#Checker.ATTRIBUTE">ATTRIBUTE</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.AUGASSIGN">AUGASSIGN</a></td> <td></td> </tr><tr> -<td><a href="#Checker.BINOP">BINOP</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.BOOLOP">BOOLOP</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.CALL">CALL</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.CLASSDEF">CLASSDEF</a></td> <td>Check names used in a class definition, including its decorators, base classes, and the body of its definition.</td> </tr><tr> -<td><a href="#Checker.COMPARE">COMPARE</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.COMPREHENSION">COMPREHENSION</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.DELETE">DELETE</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.DICT">DICT</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.DICTCOMP">DICTCOMP</a></td> <td></td> </tr><tr> <td><a href="#Checker.EXCEPTHANDLER">EXCEPTHANDLER</a></td> <td></td> </tr><tr> -<td><a href="#Checker.EXPR">EXPR</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.EXTSLICE">EXTSLICE</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.FOR">FOR</a></td> <td>Process bindings for loop variables.</td> </tr><tr> @@ -225,66 +192,24 @@ <td><a href="#Checker.GLOBAL">GLOBAL</a></td> <td>Keep track of globals declarations.</td> </tr><tr> -<td><a href="#Checker.IF">IF</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.IFEXP">IFEXP</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.IMPORT">IMPORT</a></td> <td></td> </tr><tr> <td><a href="#Checker.IMPORTFROM">IMPORTFROM</a></td> <td></td> </tr><tr> -<td><a href="#Checker.INDEX">INDEX</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.KEYWORD">KEYWORD</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.LAMBDA">LAMBDA</a></td> <td></td> </tr><tr> -<td><a href="#Checker.LIST">LIST</a></td> -<td></td> -</tr><tr> <td><a href="#Checker.LISTCOMP">LISTCOMP</a></td> <td></td> </tr><tr> <td><a href="#Checker.NAME">NAME</a></td> -<td>Locate the name in locals / function / globals scopes.</td> -</tr><tr> -<td><a href="#Checker.RAISE">RAISE</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.RETURN">RETURN</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.SLICE">SLICE</a></td> -<td></td> +<td>Handle occurrence of Name (which can be a load/store/delete access.)</td> </tr><tr> <td><a href="#Checker.STARRED">STARRED</a></td> <td></td> </tr><tr> -<td><a href="#Checker.SUBSCRIPT">SUBSCRIPT</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.TRYEXCEPT">TRYEXCEPT</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.TRYFINALLY">TRYFINALLY</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.UNARYOP">UNARYOP</a></td> -<td></td> -</tr><tr> -<td><a href="#Checker.WITH">WITH</a></td> -<td>Handle with by checking the target of the statement (which can be an identifier, a list or tuple of targets, an attribute, etc) for undefined names and defining any it adds to the scope and by continuing to process the suite within the statement.</td> -</tr><tr> -<td><a href="#Checker.YIELD">YIELD</a></td> -<td></td> -</tr><tr> <td><a href="#Checker._runDeferred">_runDeferred</a></td> <td>Run the callables in deferred using their associated scope stack.</td> </tr><tr> @@ -315,12 +240,18 @@ <td><a href="#Checker.handleBody">handleBody</a></td> <td></td> </tr><tr> +<td><a href="#Checker.handleChildren">handleChildren</a></td> +<td></td> +</tr><tr> <td><a href="#Checker.handleNode">handleNode</a></td> <td></td> </tr><tr> <td><a href="#Checker.ignore">ignore</a></td> <td></td> </tr><tr> +<td><a href="#Checker.isDocstring">isDocstring</a></td> +<td>Determine if the given node is a docstring, as long as it is at the correct place in the node tree.</td> +</tr><tr> <td><a href="#Checker.popScope">popScope</a></td> <td></td> </tr><tr> @@ -353,27 +284,12 @@ <dd> name of the module file (string) </dd> -</dl><a NAME="Checker.ASSERT" ID="Checker.ASSERT"></a> -<h4>Checker.ASSERT</h4> -<b>ASSERT</b>(<i>node</i>) -<a NAME="Checker.ASSIGN" ID="Checker.ASSIGN"></a> +</dl><a NAME="Checker.ASSIGN" ID="Checker.ASSIGN"></a> <h4>Checker.ASSIGN</h4> <b>ASSIGN</b>(<i>node</i>) -<a NAME="Checker.ATTRIBUTE" ID="Checker.ATTRIBUTE"></a> -<h4>Checker.ATTRIBUTE</h4> -<b>ATTRIBUTE</b>(<i>node</i>) <a NAME="Checker.AUGASSIGN" ID="Checker.AUGASSIGN"></a> <h4>Checker.AUGASSIGN</h4> <b>AUGASSIGN</b>(<i>node</i>) -<a NAME="Checker.BINOP" ID="Checker.BINOP"></a> -<h4>Checker.BINOP</h4> -<b>BINOP</b>(<i>node</i>) -<a NAME="Checker.BOOLOP" ID="Checker.BOOLOP"></a> -<h4>Checker.BOOLOP</h4> -<b>BOOLOP</b>(<i>node</i>) -<a NAME="Checker.CALL" ID="Checker.CALL"></a> -<h4>Checker.CALL</h4> -<b>CALL</b>(<i>node</i>) <a NAME="Checker.CLASSDEF" ID="Checker.CLASSDEF"></a> <h4>Checker.CLASSDEF</h4> <b>CLASSDEF</b>(<i>node</i>) @@ -381,30 +297,12 @@ Check names used in a class definition, including its decorators, base classes, and the body of its definition. Additionally, add its name to the current scope. -</p><a NAME="Checker.COMPARE" ID="Checker.COMPARE"></a> -<h4>Checker.COMPARE</h4> -<b>COMPARE</b>(<i>node</i>) -<a NAME="Checker.COMPREHENSION" ID="Checker.COMPREHENSION"></a> -<h4>Checker.COMPREHENSION</h4> -<b>COMPREHENSION</b>(<i>node</i>) -<a NAME="Checker.DELETE" ID="Checker.DELETE"></a> -<h4>Checker.DELETE</h4> -<b>DELETE</b>(<i>node</i>) -<a NAME="Checker.DICT" ID="Checker.DICT"></a> -<h4>Checker.DICT</h4> -<b>DICT</b>(<i>node</i>) -<a NAME="Checker.DICTCOMP" ID="Checker.DICTCOMP"></a> +</p><a NAME="Checker.DICTCOMP" ID="Checker.DICTCOMP"></a> <h4>Checker.DICTCOMP</h4> <b>DICTCOMP</b>(<i>node</i>) <a NAME="Checker.EXCEPTHANDLER" ID="Checker.EXCEPTHANDLER"></a> <h4>Checker.EXCEPTHANDLER</h4> <b>EXCEPTHANDLER</b>(<i>node</i>) -<a NAME="Checker.EXPR" ID="Checker.EXPR"></a> -<h4>Checker.EXPR</h4> -<b>EXPR</b>(<i>node</i>) -<a NAME="Checker.EXTSLICE" ID="Checker.EXTSLICE"></a> -<h4>Checker.EXTSLICE</h4> -<b>EXTSLICE</b>(<i>node</i>) <a NAME="Checker.FOR" ID="Checker.FOR"></a> <h4>Checker.FOR</h4> <b>FOR</b>(<i>node</i>) @@ -418,30 +316,15 @@ <b>GLOBAL</b>(<i>node</i>) <p> Keep track of globals declarations. -</p><a NAME="Checker.IF" ID="Checker.IF"></a> -<h4>Checker.IF</h4> -<b>IF</b>(<i>node</i>) -<a NAME="Checker.IFEXP" ID="Checker.IFEXP"></a> -<h4>Checker.IFEXP</h4> -<b>IFEXP</b>(<i>node</i>) -<a NAME="Checker.IMPORT" ID="Checker.IMPORT"></a> +</p><a NAME="Checker.IMPORT" ID="Checker.IMPORT"></a> <h4>Checker.IMPORT</h4> <b>IMPORT</b>(<i>node</i>) <a NAME="Checker.IMPORTFROM" ID="Checker.IMPORTFROM"></a> <h4>Checker.IMPORTFROM</h4> <b>IMPORTFROM</b>(<i>node</i>) -<a NAME="Checker.INDEX" ID="Checker.INDEX"></a> -<h4>Checker.INDEX</h4> -<b>INDEX</b>(<i>node</i>) -<a NAME="Checker.KEYWORD" ID="Checker.KEYWORD"></a> -<h4>Checker.KEYWORD</h4> -<b>KEYWORD</b>(<i>node</i>) <a NAME="Checker.LAMBDA" ID="Checker.LAMBDA"></a> <h4>Checker.LAMBDA</h4> <b>LAMBDA</b>(<i>node</i>) -<a NAME="Checker.LIST" ID="Checker.LIST"></a> -<h4>Checker.LIST</h4> -<b>LIST</b>(<i>node</i>) <a NAME="Checker.LISTCOMP" ID="Checker.LISTCOMP"></a> <h4>Checker.LISTCOMP</h4> <b>LISTCOMP</b>(<i>node</i>) @@ -449,42 +332,10 @@ <h4>Checker.NAME</h4> <b>NAME</b>(<i>node</i>) <p> - Locate the name in locals / function / globals scopes. -</p><a NAME="Checker.RAISE" ID="Checker.RAISE"></a> -<h4>Checker.RAISE</h4> -<b>RAISE</b>(<i>node</i>) -<a NAME="Checker.RETURN" ID="Checker.RETURN"></a> -<h4>Checker.RETURN</h4> -<b>RETURN</b>(<i>node</i>) -<a NAME="Checker.SLICE" ID="Checker.SLICE"></a> -<h4>Checker.SLICE</h4> -<b>SLICE</b>(<i>node</i>) -<a NAME="Checker.STARRED" ID="Checker.STARRED"></a> + Handle occurrence of Name (which can be a load/store/delete access.) +</p><a NAME="Checker.STARRED" ID="Checker.STARRED"></a> <h4>Checker.STARRED</h4> <b>STARRED</b>(<i>node</i>) -<a NAME="Checker.SUBSCRIPT" ID="Checker.SUBSCRIPT"></a> -<h4>Checker.SUBSCRIPT</h4> -<b>SUBSCRIPT</b>(<i>node</i>) -<a NAME="Checker.TRYEXCEPT" ID="Checker.TRYEXCEPT"></a> -<h4>Checker.TRYEXCEPT</h4> -<b>TRYEXCEPT</b>(<i>node</i>) -<a NAME="Checker.TRYFINALLY" ID="Checker.TRYFINALLY"></a> -<h4>Checker.TRYFINALLY</h4> -<b>TRYFINALLY</b>(<i>node</i>) -<a NAME="Checker.UNARYOP" ID="Checker.UNARYOP"></a> -<h4>Checker.UNARYOP</h4> -<b>UNARYOP</b>(<i>node</i>) -<a NAME="Checker.WITH" ID="Checker.WITH"></a> -<h4>Checker.WITH</h4> -<b>WITH</b>(<i>node</i>) -<p> - Handle with by checking the target of the statement (which can be an - identifier, a list or tuple of targets, an attribute, etc) for - undefined names and defining any it adds to the scope and by continuing - to process the suite within the statement. -</p><a NAME="Checker.YIELD" ID="Checker.YIELD"></a> -<h4>Checker.YIELD</h4> -<b>YIELD</b>(<i>node</i>) <a NAME="Checker._runDeferred" ID="Checker._runDeferred"></a> <h4>Checker._runDeferred</h4> <b>_runDeferred</b>(<i>deferred</i>) @@ -547,13 +398,22 @@ <a NAME="Checker.handleBody" ID="Checker.handleBody"></a> <h4>Checker.handleBody</h4> <b>handleBody</b>(<i>tree</i>) +<a NAME="Checker.handleChildren" ID="Checker.handleChildren"></a> +<h4>Checker.handleChildren</h4> +<b>handleChildren</b>(<i>tree</i>) <a NAME="Checker.handleNode" ID="Checker.handleNode"></a> <h4>Checker.handleNode</h4> <b>handleNode</b>(<i>node, parent</i>) <a NAME="Checker.ignore" ID="Checker.ignore"></a> <h4>Checker.ignore</h4> <b>ignore</b>(<i>node</i>) -<a NAME="Checker.popScope" ID="Checker.popScope"></a> +<a NAME="Checker.isDocstring" ID="Checker.isDocstring"></a> +<h4>Checker.isDocstring</h4> +<b>isDocstring</b>(<i>node</i>) +<p> + Determine if the given node is a docstring, as long as it is at the + correct place in the node tree. +</p><a NAME="Checker.popScope" ID="Checker.popScope"></a> <h4>Checker.popScope</h4> <b>popScope</b>(<i></i>) <a NAME="Checker.pushClassScope" ID="Checker.pushClassScope"></a>
--- a/Utilities/py3flakes/checker.py Fri Nov 12 19:17:44 2010 +0100 +++ b/Utilities/py3flakes/checker.py Sat Nov 13 19:51:38 2010 +0100 @@ -104,7 +104,8 @@ importStarred = False # set to True when import * is found def __repr__(self): - return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), dict.__repr__(self)) + return '<{0} at 0x{1:x} {2}>'.format( + self.__class__.__name__, id(self), dict.__repr__(self)) def __init__(self): super(Scope, self).__init__() @@ -244,12 +245,28 @@ for node in tree.body: self.handleNode(node, tree) + def handleChildren(self, tree): + for node in ast.iter_child_nodes(tree): + self.handleNode(node, tree) + + def isDocstring(self, node): + """ + Determine if the given node is a docstring, as long as it is at the + correct place in the node tree. + """ + return isinstance(node, ast.Str) or \ + (isinstance(node, ast.Expr) and + isinstance(node.value, ast.Str)) + def handleNode(self, node, parent): if node: node.parent = parent if self.traceTree: print(' ' * self.nodeDepth + node.__class__.__name__) self.nodeDepth += 1 + if self.futuresAllowed and not \ + (isinstance(node, ast.ImportFrom) or self.isDocstring(node)): + self.futuresAllowed = False nodeType = node.__class__.__name__.upper() try: handler = getattr(self, nodeType) @@ -264,10 +281,26 @@ # ast nodes to be ignored PASS = CONTINUE = BREAK = ELLIPSIS = NUM = STR = BYTES = \ + LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = \ ATTRIBUTES = AND = OR = ADD = SUB = MULT = DIV = \ MOD = POW = LSHIFT = RSHIFT = BITOR = BITXOR = BITAND = FLOORDIV = \ - INVERT = NOT = UADD = USUB = INVERT = NOT = UADD = USUB = ignore + INVERT = NOT = UADD = USUB = EQ = NOTEQ = LT = LTE = GT = GTE = IS = \ + ISNOT = IN = NOTIN = ignore + # "stmt" type nodes + RETURN = DELETE = PRINT = WHILE = IF = WITH = RAISE = TRYEXCEPT = \ + TRYFINALLY = ASSERT = EXEC = EXPR = handleChildren + + # "expr" type nodes + BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = YIELD = COMPARE = \ + CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = handleChildren + + # "slice" type nodes + SLICE = EXTSLICE = INDEX = handleChildren + + # additional node types + COMPREHENSION = KEYWORD = handleChildren + def addBinding(self, lineno, value, reportRedef = True): '''Called when a binding is altered. @@ -285,11 +318,12 @@ if not isinstance(self.scope, ClassScope): for scope in self.scopeStack[::-1]: existing = scope.get(value.name) - if (isinstance(existing, Importation) - and not existing.used - and (not isinstance(value, Importation) or value.fullName == existing.fullName) - and reportRedef): - + if isinstance(existing, Importation) and \ + not existing.used and \ + not isinstance(value, UnBinding) and \ + (not isinstance(value, Importation) or \ + value.fullName == existing.fullName) and \ + reportRedef: self.report(messages.RedefinedWhileUnused, lineno, value.name, scope[value.name].source.lineno) @@ -305,37 +339,6 @@ ## individual handler methods below ############################################################ - def LIST(self, node): - for elt in node.elts: - self.handleNode(elt, node) - - SET = TUPLE = LIST - - def DICT(self, node): - for key in node.keys: - self.handleNode(key, node) - for val in node.values: - self.handleNode(val, node) - - def WITH(self, node): - """ - Handle with by checking the target of the statement (which can be an - identifier, a list or tuple of targets, an attribute, etc) for - undefined names and defining any it adds to the scope and by continuing - to process the suite within the statement. - """ - # Check the "foo" part of a "with foo as bar" statement. Do this no - # matter what, since there's always a "foo" part. - self.handleNode(node.context_expr, node) - - arg = None - if node.optional_vars is not None: - arg = Argument(node.optional_vars.id, node) - self.addBinding(node.lineno, arg, reportRedef=False) - self.handleBody(node) - if arg: - del self.scope[arg.name] - def GLOBAL(self, node): """ Keep track of globals declarations. @@ -358,13 +361,6 @@ self.handleNode(node.key, node) self.handleNode(node.value, node) - def COMPREHENSION(self, node): - node.target.parent = node - self.handleAssignName(node.target) - self.handleNode(node.iter, node) - for elt in node.ifs: - self.handleNode(elt, node) - def FOR(self, node): """ Process bindings for loop variables. @@ -373,6 +369,11 @@ def collectLoopVars(n): if isinstance(n, ast.Name): vars.append(n.id) + elif isinstance(n, ast.expr_context): + return + else: + for c in ast.iter_child_nodes(n): + collectLoopVars(c) collectLoopVars(node.target) for varn in vars: @@ -382,50 +383,92 @@ self.report(messages.ImportShadowedByLoopVar, node.lineno, varn, self.scope[varn].source.lineno) - node.target.parent = node - self.handleAssignName(node.target) - self.handleNode(node.iter, node) - self.handleBody(node) + self.handleChildren(node) def NAME(self, node): """ - Locate the name in locals / function / globals scopes. + Handle occurrence of Name (which can be a load/store/delete access.) """ - # try local scope - importStarred = self.scope.importStarred - try: - self.scope[node.id].used = (self.scope, node.lineno) - except KeyError: - pass - else: - return - - # try enclosing function scopes - for scope in self.scopeStack[-2:0:-1]: - importStarred = importStarred or scope.importStarred - if not isinstance(scope, FunctionScope): - continue + # Locate the name in locals / function / globals scopes. + if isinstance(node.ctx, (ast.Load, ast.AugLoad)): + # try local scope + importStarred = self.scope.importStarred try: - scope[node.id].used = (self.scope, node.lineno) + self.scope[node.id].used = (self.scope, node.lineno) except KeyError: pass else: return - # try global scope - importStarred = importStarred or self.scopeStack[0].importStarred - try: - self.scopeStack[0][node.id].used = (self.scope, node.lineno) - except KeyError: - if ((not hasattr(builtins, node.id)) - and node.id not in _MAGIC_GLOBALS - and not importStarred): - if (os.path.basename(self.filename) == '__init__.py' and - node.id == '__path__'): - # the special name __path__ is valid only in packages + # try enclosing function scopes + for scope in self.scopeStack[-2:0:-1]: + importStarred = importStarred or scope.importStarred + if not isinstance(scope, FunctionScope): + continue + try: + scope[node.id].used = (self.scope, node.lineno) + except KeyError: pass else: - self.report(messages.UndefinedName, node.lineno, node.id) + return + + # try global scope + importStarred = importStarred or self.scopeStack[0].importStarred + try: + self.scopeStack[0][node.id].used = (self.scope, node.lineno) + except KeyError: + if ((not hasattr(builtins, node.id)) + and node.id not in _MAGIC_GLOBALS + and not importStarred): + if (os.path.basename(self.filename) == '__init__.py' and + node.id == '__path__'): + # the special name __path__ is valid only in packages + pass + else: + self.report(messages.UndefinedName, node.lineno, node.id) + elif isinstance(node.ctx, (ast.Store, ast.AugStore)): + # if the name hasn't already been defined in the current scope + if isinstance(self.scope, FunctionScope) and node.id not in self.scope: + # for each function or module scope above us + for scope in self.scopeStack[:-1]: + if not isinstance(scope, (FunctionScope, ModuleScope)): + continue + # if the name was defined in that scope, and the name has + # been accessed already in the current scope, and hasn't + # been declared global + if (node.id in scope + and scope[node.id].used + and scope[node.id].used[0] is self.scope + and node.id not in self.scope.globals): + # then it's probably a mistake + self.report(messages.UndefinedLocal, + scope[node.id].used[1], + node.id, + scope[node.id].source.lineno) + break + + if isinstance(node.parent, + (ast.For, ast.comprehension, ast.Tuple, ast.List)): + binding = Binding(node.id, node) + elif (node.id == '__all__' and + isinstance(self.scope, ModuleScope)): + binding = ExportBinding(node.id, node.parent.value) + else: + binding = Assignment(node.id, node) + if node.id in self.scope: + binding.used = self.scope[node.id].used + self.addBinding(node.lineno, binding) + elif isinstance(node.ctx, ast.Del): + if isinstance(self.scope, FunctionScope) and \ + node.id in self.scope.globals: + del self.scope.globals[node.id] + else: + self.addBinding(node.lineno, UnBinding(node.id, node)) + else: + # must be a Param context -- this only happens for names in function + # arguments, but these aren't dispatched through here + raise RuntimeError( + "Got impossible expression context: {0:r}".format(node.ctx,)) def FUNCTIONDEF(self, node): if getattr(node, "decorator_list", None) is not None: @@ -463,14 +506,13 @@ self.pushFunctionScope() addArgs(node.args.args) addArgs(node.args.kwonlyargs) + # vararg/kwarg identifiers are not Name nodes + if node.args.vararg: + args.append(node.args.vararg) + if node.args.kwarg: + args.append(node.args.kwarg) for name in args: self.addBinding(node.lineno, Argument(name, node), reportRedef=False) - if node.args.vararg: - self.addBinding(node.lineno, Argument(node.args.vararg, node), - reportRedef=False) - if node.args.kwarg: - self.addBinding(node.lineno, Argument(node.args.kwarg, node), - reportRedef=False) if isinstance(node.body, list): self.handleBody(node) else: @@ -555,15 +597,16 @@ def ASSIGN(self, node): self.handleNode(node.value, node) - for subnode in node.targets[::-1]: - subnode.parent = node - if isinstance(subnode, ast.Attribute): - self.handleNode(subnode.value, subnode) - else: - self.handleAssignName(subnode) + for target in node.targets: + self.handleNode(target, node) def AUGASSIGN(self, node): + # AugAssign is awkward: must set the context explicitly and visit twice, + # once with AugLoad context, once with AugStore context + node.target.ctx = ast.AugLoad() + self.handleNode(node.target, node) self.handleNode(node.value, node) + node.target.ctx = ast.AugStore() self.handleNode(node.target, node) def IMPORT(self, node): @@ -591,66 +634,6 @@ importation.used = (self.scope, node.lineno) self.addBinding(node.lineno, importation) - def CALL(self, node): - self.handleNode(node.func, node) - for arg in node.args: - self.handleNode(arg, node) - for kw in node.keywords: - self.handleNode(kw, node) - node.starargs and self.handleNode(node.starargs, node) - node.kwargs and self.handleNode(node.kwargs, node) - - def KEYWORD(self, node): - self.handleNode(node.value, node) - - def BOOLOP(self, node): - for val in node.values: - self.handleNode(val, node) - - def BINOP(self, node): - self.handleNode(node.left, node) - self.handleNode(node.right, node) - - def UNARYOP(self, node): - self.handleNode(node.operand, node) - - def RETURN(self, node): - node.value and self.handleNode(node.value, node) - - def DELETE(self, node): - for tgt in node.targets: - self.handleNode(tgt, node) - - def EXPR(self, node): - self.handleNode(node.value, node) - - def ATTRIBUTE(self, node): - self.handleNode(node.value, node) - - def IF(self, node): - self.handleNode(node.test, node) - self.handleBody(node) - for stmt in node.orelse: - self.handleNode(stmt, node) - - WHILE = IF - - def RAISE(self, node): - node.exc and self.handleNode(node.exc, node) - node.cause and self.handleNode(node.cause, node) - - def TRYEXCEPT(self, node): - self.handleBody(node) - for handler in node.handlers: - self.handleNode(handler, node) - for stmt in node.orelse: - self.handleNode(stmt, node) - - def TRYFINALLY(self, node): - self.handleBody(node) - for stmt in node.finalbody: - self.handleNode(stmt, node) - def EXCEPTHANDLER(self, node): node.type and self.handleNode(node.type, node) if node.name: @@ -658,38 +641,5 @@ self.handleAssignName(node) self.handleBody(node) - def ASSERT(self, node): - self.handleNode(node.test, node) - node.msg and self.handleNode(node.msg, node) - - def COMPARE(self, node): - self.handleNode(node.left, node) - for comparator in node.comparators: - self.handleNode(comparator, node) - - def YIELD(self, node): - node.value and self.handleNode(node.value, node) - - def SUBSCRIPT(self, node): - self.handleNode(node.value, node) - self.handleNode(node.slice, node) - - def SLICE(self, node): - node.lower and self.handleNode(node.lower, node) - node.upper and self.handleNode(node.upper, node) - node.step and self.handleNode(node.step, node) - - def EXTSLICE(self, node): - for slice in node.dims: - self.handleNode(slice, node) - - def INDEX(self, node): - self.handleNode(node.value, node) - - def IFEXP(self, node): - self.handleNode(node.test, node) - self.handleNode(node.body, node) - self.handleNode(node.orelse, node) - def STARRED(self, node): self.handleNode(node.value, node)