Backported the improved the py3flakes checker. 5_0_x

Sat, 13 Nov 2010 19:51:38 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 13 Nov 2010 19:51:38 +0100
branch
5_0_x
changeset 720
dd67928832ab
parent 719
d564fadc6913
child 722
b70941c7f2eb

Backported the improved the py3flakes checker.

APIs/Python3/eric5.api file | annotate | diff | comparison | revisions
Documentation/Help/source.qch file | annotate | diff | comparison | revisions
Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
Documentation/Source/eric5.Utilities.py3flakes.checker.html file | annotate | diff | comparison | revisions
Utilities/py3flakes/checker.py file | annotate | diff | comparison | revisions
--- 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()
Binary file Documentation/Help/source.qch has changed
--- 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)

eric ide

mercurial