Fri, 13 Sep 2013 18:49:26 +0200
Optimized the PEP-8 naming checker.
--- a/APIs/Python3/eric5.api Fri Sep 13 18:38:34 2013 +0200 +++ b/APIs/Python3/eric5.api Fri Sep 13 18:49:26 2013 +0200 @@ -3767,7 +3767,7 @@ eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.Pep8NamingChecker.UppercaseRegexp?7 eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.Pep8NamingChecker.getMessage?4(code, *args) eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.Pep8NamingChecker.run?4() -eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.Pep8NamingChecker?1(tree, filename) +eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.Pep8NamingChecker?1(tree, filename, options) eric5.Plugins.CheckerPlugins.Pep8.Pep8StatisticsDialog.Pep8StatisticsDialog?1(statistics, parent=None) eric5.Plugins.CheckerPlugins.Pep8.pep8.ARITHMETIC_OP?7 eric5.Plugins.CheckerPlugins.Pep8.pep8.BENCHMARK_KEYS?7
--- a/APIs/Python3/eric5.bas Fri Sep 13 18:38:34 2013 +0200 +++ b/APIs/Python3/eric5.bas Fri Sep 13 18:49:26 2013 +0200 @@ -63,7 +63,7 @@ ChangeBookmarkCommand QUndoCommand ChatWidget QWidget Ui_ChatWidget ChromeImporter BookmarksImporter -Class ClbrBaseClasses.Class VisibilityMixin +Class ClbrBase ClassItem UMLItem ClassModel UMLModel ClassScope Scope
--- a/Documentation/Help/source.qhp Fri Sep 13 18:38:34 2013 +0200 +++ b/Documentation/Help/source.qhp Fri Sep 13 18:49:26 2013 +0200 @@ -8086,6 +8086,7 @@ <keyword name="Pep8NamingChecker.__checkImportAs" id="Pep8NamingChecker.__checkImportAs" ref="eric5.UtilitiesPython2.Pep8NamingCheckerPy2.html#Pep8NamingChecker.__checkImportAs" /> <keyword name="Pep8NamingChecker.__checkModule" id="Pep8NamingChecker.__checkModule" ref="eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.html#Pep8NamingChecker.__checkModule" /> <keyword name="Pep8NamingChecker.__checkModule" id="Pep8NamingChecker.__checkModule" ref="eric5.UtilitiesPython2.Pep8NamingCheckerPy2.html#Pep8NamingChecker.__checkModule" /> + <keyword name="Pep8NamingChecker.__checkNameToBeAvoided" id="Pep8NamingChecker.__checkNameToBeAvoided" ref="eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.html#Pep8NamingChecker.__checkNameToBeAvoided" /> <keyword name="Pep8NamingChecker.__checkVariablesInFunction" id="Pep8NamingChecker.__checkVariablesInFunction" ref="eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.html#Pep8NamingChecker.__checkVariablesInFunction" /> <keyword name="Pep8NamingChecker.__checkVariablesInFunction" id="Pep8NamingChecker.__checkVariablesInFunction" ref="eric5.UtilitiesPython2.Pep8NamingCheckerPy2.html#Pep8NamingChecker.__checkVariablesInFunction" /> <keyword name="Pep8NamingChecker.__error" id="Pep8NamingChecker.__error" ref="eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.html#Pep8NamingChecker.__error" />
--- a/Documentation/Source/eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.html Fri Sep 13 18:38:34 2013 +0200 +++ b/Documentation/Source/eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.html Fri Sep 13 18:49:26 2013 +0200 @@ -61,16 +61,16 @@ <table> <tr> <td><a href="#Pep8NamingChecker.__init__">Pep8NamingChecker</a></td> -<td>Constructor (according to pep8.py API)</td> +<td>Constructor (according to 'extended' pep8.py API)</td> </tr><tr> <td><a href="#Pep8NamingChecker.__checkClassName">__checkClassName</a></td> -<td>Private class to check the given node for class name conventions (N801, N831).</td> +<td>Private class to check the given node for class name conventions (N801).</td> </tr><tr> <td><a href="#Pep8NamingChecker.__checkFunctionArgumentNames">__checkFunctionArgumentNames</a></td> -<td>Private class to check the argument names of functions (N803, N804, N805, N806, N831).</td> +<td>Private class to check the argument names of functions (N803, N804, N805, N806).</td> </tr><tr> <td><a href="#Pep8NamingChecker.__checkFuntionName">__checkFuntionName</a></td> -<td>Private class to check the given node for function name conventions (N802, N831).</td> +<td>Private class to check the given node for function name conventions (N802).</td> </tr><tr> <td><a href="#Pep8NamingChecker.__checkImportAs">__checkImportAs</a></td> <td>Private method to check that imports don't change the naming convention (N811, N812, N813, N814).</td> @@ -78,8 +78,11 @@ <td><a href="#Pep8NamingChecker.__checkModule">__checkModule</a></td> <td>Private method to check module naming conventions (N807, N808).</td> </tr><tr> +<td><a href="#Pep8NamingChecker.__checkNameToBeAvoided">__checkNameToBeAvoided</a></td> +<td>Private class to check the given node for a name to be avoided (N831).</td> +</tr><tr> <td><a href="#Pep8NamingChecker.__checkVariablesInFunction">__checkVariablesInFunction</a></td> -<td>Private method to check local variables in functions (N821, N831).</td> +<td>Private method to check local variables in functions (N821).</td> </tr><tr> <td><a href="#Pep8NamingChecker.__error">__error</a></td> <td>Private method to build the error information</td> @@ -131,9 +134,9 @@ </dd> </dl><a NAME="Pep8NamingChecker.__init__" ID="Pep8NamingChecker.__init__"></a> <h4>Pep8NamingChecker (Constructor)</h4> -<b>Pep8NamingChecker</b>(<i>tree, filename</i>) +<b>Pep8NamingChecker</b>(<i>tree, filename, options</i>) <p> - Constructor (according to pep8.py API) + Constructor (according to 'extended' pep8.py API) </p><dl> <dt><i>tree</i></dt> <dd> @@ -141,13 +144,16 @@ </dd><dt><i>filename</i></dt> <dd> name of the source file (string) +</dd><dt><i>options</i></dt> +<dd> +options as parsed by pep8.StyleGuide </dd> </dl><a NAME="Pep8NamingChecker.__checkClassName" ID="Pep8NamingChecker.__checkClassName"></a> <h4>Pep8NamingChecker.__checkClassName</h4> <b>__checkClassName</b>(<i>node, parents</i>) <p> Private class to check the given node for class name - conventions (N801, N831). + conventions (N801). </p><p> Almost without exception, class names use the CapWords convention. Classes for internal use have a leading underscore in addition. @@ -167,7 +173,7 @@ <b>__checkFunctionArgumentNames</b>(<i>node, parents</i>) <p> Private class to check the argument names of functions - (N803, N804, N805, N806, N831). + (N803, N804, N805, N806). </p><p> The argument names of a function should be lowercase, with words separated by underscores. A class method should have 'cls' as the @@ -188,7 +194,7 @@ <b>__checkFuntionName</b>(<i>node, parents</i>) <p> Private class to check the given node for function name - conventions (N802, N831). + conventions (N802). </p><p> Function names should be lowercase, with words separated by underscores as necessary to improve readability. Functions <b>not</b> being @@ -241,11 +247,27 @@ tuple giving line number, offset within line and error code (integer, integer, string) </dd> +</dl><a NAME="Pep8NamingChecker.__checkNameToBeAvoided" ID="Pep8NamingChecker.__checkNameToBeAvoided"></a> +<h4>Pep8NamingChecker.__checkNameToBeAvoided</h4> +<b>__checkNameToBeAvoided</b>(<i>node, parents</i>) +<p> + Private class to check the given node for a name to be avoided (N831). +</p><dl> +<dt><i>node</i></dt> +<dd> +AST note to check +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +tuple giving line number, offset within line and error code + (integer, integer, string) +</dd> </dl><a NAME="Pep8NamingChecker.__checkVariablesInFunction" ID="Pep8NamingChecker.__checkVariablesInFunction"></a> <h4>Pep8NamingChecker.__checkVariablesInFunction</h4> <b>__checkVariablesInFunction</b>(<i>node, parents</i>) <p> - Private method to check local variables in functions (N821, N831). + Private method to check local variables in functions (N821). </p><p> Local variables in functions should be lowercase. </p><dl>
--- a/Plugins/CheckerPlugins/Pep8/Pep8NamingChecker.py Fri Sep 13 18:38:34 2013 +0200 +++ b/Plugins/CheckerPlugins/Pep8/Pep8NamingChecker.py Fri Sep 13 18:49:26 2013 +0200 @@ -60,26 +60,49 @@ "names 'l', 'O' and 'I' should be avoided"), } - def __init__(self, tree, filename): + def __init__(self, tree, filename, options): """ - Constructor (according to pep8.py API) + Constructor (according to 'extended' pep8.py API) @param tree AST tree of the source file @param filename name of the source file (string) + @param options options as parsed by pep8.StyleGuide """ self.__parents = collections.deque() self.__tree = tree self.__filename = filename - self.__checkers = { - "classdef": [self.__checkClassName], - "functiondef": [self.__checkFuntionName, - self.__checkFunctionArgumentNames, - ], - "assign": [self.__checkVariablesInFunction], - "importfrom": [self.__checkImportAs], - "module": [self.__checkModule], + self.__checkersWithCodes = { + "classdef": [ + (self.__checkClassName, ("N801",)), + (self.__checkNameToBeAvoided, ("N831",)), + ], + "functiondef": [ + (self.__checkFuntionName, ("N802",)), + (self.__checkFunctionArgumentNames, + ("N803", "N804", "N805", "N806")), + (self.__checkNameToBeAvoided, ("N831",)), + ], + "assign": [ + (self.__checkVariablesInFunction, ("N821",)), + (self.__checkNameToBeAvoided, ("N831",)), + ], + "importfrom": [ + (self.__checkImportAs, ("N811", "N812", "N813", "N814")), + ], + "module": [ + (self.__checkModule, ("N807", "N808")), + ], } + + self.__checkers = {} + for key, checkers in self.__checkersWithCodes.items(): + for checker, codes in checkers: + if any(not (code and options.ignore_code(code)) + for code in codes): + if key not in self.__checkers: + self.__checkers[key] = [] + self.__checkers[key].append(checker) def run(self): """ @@ -244,10 +267,41 @@ """ return name in ("l", "O", "I") + def __checkNameToBeAvoided(self, node, parents): + """ + Private class to check the given node for a name to be avoided (N831). + + @param node AST note to check + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + if isinstance(node, (ast.ClassDef, ast.FunctionDef)): + name = node.name + if self.__isNameToBeAvoided(name): + yield self.__error(node, "N831") + return + + if isinstance(node, ast.FunctionDef): + argNames = self.__getArgNames(node) + for arg in argNames: + if self.__isNameToBeAvoided(arg): + yield self.__error(node, "N831") + return + + if isinstance(node, ast.Assign): + for target in node.targets: + name = isinstance(target, ast.Name) and target.id + if not name: + return + + if self.__isNameToBeAvoided(name): + yield self.__error(node, "N831") + return + def __checkClassName(self, node, parents): """ Private class to check the given node for class name - conventions (N801, N831). + conventions (N801). Almost without exception, class names use the CapWords convention. Classes for internal use have a leading underscore in addition. @@ -256,17 +310,13 @@ @return tuple giving line number, offset within line and error code (integer, integer, string) """ - if self.__isNameToBeAvoided(node.name): - yield self.__error(node, "N831") - return - if not self.CamelcaseRegexp.match(node.name): yield self.__error(node, "N801") def __checkFuntionName(self, node, parents): """ Private class to check the given node for function name - conventions (N802, N831). + conventions (N802). Function names should be lowercase, with words separated by underscores as necessary to improve readability. Functions <b>not</b> being @@ -280,10 +330,6 @@ """ functionType = getattr(node, "function_type", "function") name = node.name - if self.__isNameToBeAvoided(name): - yield self.__error(node, "N831") - return - if (functionType == "function" and "__" in (name[:2], name[-2:])) or \ not self.LowercaseRegex.match(name): yield self.__error(node, "N802") @@ -291,7 +337,7 @@ def __checkFunctionArgumentNames(self, node, parents): """ Private class to check the argument names of functions - (N803, N804, N805, N806, N831). + (N803, N804, N805, N806). The argument names of a function should be lowercase, with words separated by underscores. A class method should have 'cls' as the @@ -331,17 +377,13 @@ if argNames[0] in ("cls", "self"): yield self.__error(node, "N806") for arg in argNames: - if self.__isNameToBeAvoided(arg): - yield self.__error(node, "N831") - return - if not self.LowercaseRegex.match(arg): yield self.__error(node, "N803") return def __checkVariablesInFunction(self, node, parents): """ - Private method to check local variables in functions (N821, N831). + Private method to check local variables in functions (N821). Local variables in functions should be lowercase. @@ -361,10 +403,6 @@ if not name or name in parentFunc.global_names: return - if self.__isNameToBeAvoided(name): - yield self.__error(node, "N831") - return - if not self.LowercaseRegex.match(name) and name[:1] != '_': yield self.__error(target, "N821")
--- a/Plugins/CheckerPlugins/Pep8/pep8.py Fri Sep 13 18:38:34 2013 +0200 +++ b/Plugins/CheckerPlugins/Pep8/pep8.py Fri Sep 13 18:49:26 2013 +0200 @@ -1378,6 +1378,9 @@ self.report = report or options.report self.report_error = self.report.error self.report_error_args = self.report.error_args + + # added for eric5 integration + self.options = options def report_invalid_syntax(self): exc_type, exc = sys.exc_info()[:2] @@ -1508,7 +1511,8 @@ except (SyntaxError, TypeError): return self.report_invalid_syntax() for name, cls, _ in self._ast_checks: - checker = cls(tree, self.filename) + # extended API for eric5 integration + checker = cls(tree, self.filename, self.options) for lineno, offset, code, check, *args in checker.run(): if not noqa(self.lines[lineno - 1]): self.report_error_args(lineno, offset, code, check, *args)