Tue, 01 Oct 2013 18:34:19 +0200
Continued changing the names of the various code style checkers to make them more appropriate to the broadened scope.
--- a/Documentation/Source/eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker.html Tue Oct 01 18:31:05 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,421 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker</title> -<meta charset="UTF-8"> -<style> -body { - background: #EDECE6; - margin: 0em 1em 10em 1em; - color: black; -} - -h1 { color: white; background: #85774A; } -h2 { color: white; background: #85774A; } -h3 { color: white; background: #9D936E; } -h4 { color: white; background: #9D936E; } - -a { color: #BA6D36; } - -</style> -</head> -<body><a NAME="top" ID="top"></a> -<h1>eric5.Plugins.CheckerPlugins.Pep8.Pep8NamingChecker</h1> -<p> -Module implementing a checker for PEP-8 naming conventions. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#Pep8NamingChecker">Pep8NamingChecker</a></td> -<td>Class implementing a checker for PEP-8 naming conventions.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="Pep8NamingChecker" ID="Pep8NamingChecker"></a> -<h2>Pep8NamingChecker</h2> -<p> - Class implementing a checker for PEP-8 naming conventions. -</p> -<h3>Derived from</h3> -object -<h3>Class Attributes</h3> -<table> -<tr><td>CamelcaseRegexp</td></tr><tr><td>Codes</td></tr><tr><td>LowercaseRegex</td></tr><tr><td>Messages</td></tr><tr><td>MixedcaseRegexp</td></tr><tr><td>UppercaseRegexp</td></tr> -</table> -<h3>Class Methods</h3> -<table> -<tr> -<td><a href="#Pep8NamingChecker.getMessage">getMessage</a></td> -<td>Class method to get a translated and formatted message for a given code.</td> -</tr> -</table> -<h3>Methods</h3> -<table> -<tr> -<td><a href="#Pep8NamingChecker.__init__">Pep8NamingChecker</a></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).</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).</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__checkFuntionName">__checkFuntionName</a></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> -</tr><tr> -<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).</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__error">__error</a></td> -<td>Private method to build the error information.</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__findGlobalDefs">__findGlobalDefs</a></td> -<td>Private method amend a node with global definitions information.</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__getArgNames">__getArgNames</a></td> -<td>Private method to get the argument names of a function node.</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__isNameToBeAvoided">__isNameToBeAvoided</a></td> -<td>Private method to check, if the given name should be avoided.</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__tagClassFunctions">__tagClassFunctions</a></td> -<td>Private method to tag functions if they are methods, class methods or static methods.</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__visitNode">__visitNode</a></td> -<td>Private method to inspect the given AST node.</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.__visitTree">__visitTree</a></td> -<td>Private method to scan the given AST tree.</td> -</tr><tr> -<td><a href="#Pep8NamingChecker.run">run</a></td> -<td>Public method run by the pep8.py checker.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="Pep8NamingChecker.getMessage" ID="Pep8NamingChecker.getMessage"></a> -<h4>Pep8NamingChecker.getMessage (class method)</h4> -<b>getMessage</b>(<i>code, *args</i>) -<p> - Class method to get a translated and formatted message for a - given code. -</p><dl> -<dt><i>code</i></dt> -<dd> -message code (string) -</dd><dt><i>args</i></dt> -<dd> -arguments for a formatted message (list) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -translated and formatted message (string) -</dd> -</dl><a NAME="Pep8NamingChecker.__init__" ID="Pep8NamingChecker.__init__"></a> -<h4>Pep8NamingChecker (Constructor)</h4> -<b>Pep8NamingChecker</b>(<i>tree, filename, options</i>) -<p> - Constructor (according to 'extended' pep8.py API) -</p><dl> -<dt><i>tree</i></dt> -<dd> -AST tree of the source file -</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). -</p><p> - Almost without exception, class names use the CapWords convention. - Classes for internal use have a leading underscore in addition. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST note to check -</dd><dt><i>parents</i></dt> -<dd> -list of parent nodes -</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.__checkFunctionArgumentNames" ID="Pep8NamingChecker.__checkFunctionArgumentNames"></a> -<h4>Pep8NamingChecker.__checkFunctionArgumentNames</h4> -<b>__checkFunctionArgumentNames</b>(<i>node, parents</i>) -<p> - Private class to check the argument names of functions - (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 - first argument. A method should have 'self' as the first argument. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST note to check -</dd><dt><i>parents</i></dt> -<dd> -list of parent nodes -</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.__checkFuntionName" ID="Pep8NamingChecker.__checkFuntionName"></a> -<h4>Pep8NamingChecker.__checkFuntionName</h4> -<b>__checkFuntionName</b>(<i>node, parents</i>) -<p> - Private class to check the given node for function name - conventions (N802). -</p><p> - Function names should be lowercase, with words separated by underscores - as necessary to improve readability. Functions <b>not</b> being - methods '__' in front and back are not allowed. Mixed case is allowed - only in contexts where that's already the prevailing style - (e.g. threading.py), to retain backwards compatibility. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST note to check -</dd><dt><i>parents</i></dt> -<dd> -list of parent nodes -</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.__checkImportAs" ID="Pep8NamingChecker.__checkImportAs"></a> -<h4>Pep8NamingChecker.__checkImportAs</h4> -<b>__checkImportAs</b>(<i>node, parents</i>) -<p> - Private method to check that imports don't change the - naming convention (N811, N812, N813, N814). -</p><dl> -<dt><i>node</i></dt> -<dd> -AST note to check -</dd><dt><i>parents</i></dt> -<dd> -list of parent nodes -</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.__checkModule" ID="Pep8NamingChecker.__checkModule"></a> -<h4>Pep8NamingChecker.__checkModule</h4> -<b>__checkModule</b>(<i>node, parents</i>) -<p> - Private method to check module naming conventions (N807, N808). -</p><p> - Module and package names should be lowercase. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST note to check -</dd><dt><i>parents</i></dt> -<dd> -list of parent nodes -</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.__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><dt><i>parents</i></dt> -<dd> -list of parent nodes -</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). -</p><p> - Local variables in functions should be lowercase. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST note to check -</dd><dt><i>parents</i></dt> -<dd> -list of parent nodes -</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.__error" ID="Pep8NamingChecker.__error"></a> -<h4>Pep8NamingChecker.__error</h4> -<b>__error</b>(<i>node, code</i>) -<p> - Private method to build the error information. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST node to report an error for -</dd><dt><i>code</i></dt> -<dd> -error code to report (string) -</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.__findGlobalDefs" ID="Pep8NamingChecker.__findGlobalDefs"></a> -<h4>Pep8NamingChecker.__findGlobalDefs</h4> -<b>__findGlobalDefs</b>(<i>functionNode</i>) -<p> - Private method amend a node with global definitions information. -</p><dl> -<dt><i>functionNode</i></dt> -<dd> -AST tree node to amend -</dd> -</dl><a NAME="Pep8NamingChecker.__getArgNames" ID="Pep8NamingChecker.__getArgNames"></a> -<h4>Pep8NamingChecker.__getArgNames</h4> -<b>__getArgNames</b>(<i>node</i>) -<p> - Private method to get the argument names of a function node. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST node to extract arguments names from -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -list of argument names (list of string) -</dd> -</dl><a NAME="Pep8NamingChecker.__isNameToBeAvoided" ID="Pep8NamingChecker.__isNameToBeAvoided"></a> -<h4>Pep8NamingChecker.__isNameToBeAvoided</h4> -<b>__isNameToBeAvoided</b>(<i>name</i>) -<p> - Private method to check, if the given name should be avoided. -</p><dl> -<dt><i>name</i></dt> -<dd> -name to be checked (string) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating to avoid it (boolen) -</dd> -</dl><a NAME="Pep8NamingChecker.__tagClassFunctions" ID="Pep8NamingChecker.__tagClassFunctions"></a> -<h4>Pep8NamingChecker.__tagClassFunctions</h4> -<b>__tagClassFunctions</b>(<i>classNode</i>) -<p> - Private method to tag functions if they are methods, class methods or - static methods. -</p><dl> -<dt><i>classNode</i></dt> -<dd> -AST tree node to tag -</dd> -</dl><a NAME="Pep8NamingChecker.__visitNode" ID="Pep8NamingChecker.__visitNode"></a> -<h4>Pep8NamingChecker.__visitNode</h4> -<b>__visitNode</b>(<i>node</i>) -<p> - Private method to inspect the given AST node. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST tree node to inspect -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -tuple giving line number, offset within line, code and - checker function -</dd> -</dl><a NAME="Pep8NamingChecker.__visitTree" ID="Pep8NamingChecker.__visitTree"></a> -<h4>Pep8NamingChecker.__visitTree</h4> -<b>__visitTree</b>(<i>node</i>) -<p> - Private method to scan the given AST tree. -</p><dl> -<dt><i>node</i></dt> -<dd> -AST tree node to scan -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -tuple giving line number, offset within line, code and - checker function -</dd> -</dl><a NAME="Pep8NamingChecker.run" ID="Pep8NamingChecker.run"></a> -<h4>Pep8NamingChecker.run</h4> -<b>run</b>(<i></i>) -<p> - Public method run by the pep8.py checker. -</p><dl> -<dt>Returns:</dt> -<dd> -tuple giving line number, offset within line, code and - checker function -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/Plugins/CheckerPlugins/Pep8/CodeStyleChecker.py Tue Oct 01 18:31:05 2013 +0200 +++ b/Plugins/CheckerPlugins/Pep8/CodeStyleChecker.py Tue Oct 01 18:34:19 2013 +0200 @@ -12,7 +12,7 @@ from PyQt4.QtCore import QProcess, QCoreApplication from . import pep8 -from .Pep8NamingChecker import Pep8NamingChecker +from .NamingStyleChecker import NamingStyleChecker from .DocStyleChecker import DocStyleChecker import Preferences @@ -111,8 +111,8 @@ argindex += 1 index += 6 + arglen - if code in Pep8NamingChecker.Codes: - text = Pep8NamingChecker.getMessage(code, *args) + if code in NamingStyleChecker.Codes: + text = NamingStyleChecker.getMessage(code, *args) elif code in DocStyleChecker.Codes: text = DocStyleChecker.getMessage(code, *args) else:
--- a/Plugins/CheckerPlugins/Pep8/CodeStyleCheckerDialog.py Tue Oct 01 18:31:05 2013 +0200 +++ b/Plugins/CheckerPlugins/Pep8/CodeStyleCheckerDialog.py Tue Oct 01 18:34:19 2013 +0200 @@ -23,10 +23,10 @@ import Utilities from . import pep8 -from .Pep8NamingChecker import Pep8NamingChecker +from .NamingStyleChecker import NamingStyleChecker # register the name checker -pep8.register_check(Pep8NamingChecker, Pep8NamingChecker.Codes) +pep8.register_check(NamingStyleChecker, NamingStyleChecker.Codes) from .DocStyleChecker import DocStyleChecker @@ -59,8 +59,8 @@ """ code = super().error_args(line_number, offset, code, check, *args) if code and (self.counters[code] == 1 or self.__repeat): - if code in Pep8NamingChecker.Codes: - text = Pep8NamingChecker.getMessage(code, *args) + if code in NamingStyleChecker.Codes: + text = NamingStyleChecker.getMessage(code, *args) else: text = pep8.getMessage(code, *args) self.errors.append(
--- a/Plugins/CheckerPlugins/Pep8/CodeStyleCodeSelectionDialog.py Tue Oct 01 18:31:05 2013 +0200 +++ b/Plugins/CheckerPlugins/Pep8/CodeStyleCodeSelectionDialog.py Tue Oct 01 18:34:19 2013 +0200 @@ -11,7 +11,7 @@ from PyQt4.QtGui import QDialog, QTreeWidgetItem from . import pep8 -from .Pep8NamingChecker import Pep8NamingChecker +from .NamingStyleChecker import NamingStyleChecker from .DocStyleChecker import DocStyleChecker from .Ui_CodeStyleCodeSelectionDialog import Ui_CodeStyleCodeSelectionDialog @@ -42,7 +42,7 @@ selectableCodes = FixableCodeStyleIssues else: selectableCodes = list(pep8.pep8_messages.keys()) - selectableCodes.extend(Pep8NamingChecker.Messages.keys()) + selectableCodes.extend(NamingStyleChecker.Messages.keys()) selectableCodes.extend(DocStyleChecker.Messages.keys()) for code in sorted(selectableCodes): if code in pep8.pep8_messages_sample_args: @@ -52,10 +52,10 @@ elif code in pep8.pep8_messages: message = QCoreApplication.translate( "pep8", pep8.pep8_messages[code]) - elif code in Pep8NamingChecker.Messages: + elif code in NamingStyleChecker.Messages: message = QCoreApplication.translate( - "Pep8NamingChecker", - Pep8NamingChecker.Messages[code]) + "NamingStyleChecker", + NamingStyleChecker.Messages[code]) elif code in DocStyleChecker.Messages: message = QCoreApplication.translate( "DocStyleChecker", DocStyleChecker.Messages[code])
--- a/Plugins/CheckerPlugins/Pep8/CodeStyleStatisticsDialog.py Tue Oct 01 18:31:05 2013 +0200 +++ b/Plugins/CheckerPlugins/Pep8/CodeStyleStatisticsDialog.py Tue Oct 01 18:34:19 2013 +0200 @@ -12,7 +12,7 @@ from PyQt4.QtGui import QDialog, QTreeWidgetItem from . import pep8 -from .Pep8NamingChecker import Pep8NamingChecker +from .NamingStyleChecker import NamingStyleChecker from .DocStyleChecker import DocStyleChecker from .Ui_CodeStyleStatisticsDialog import Ui_CodeStyleStatisticsDialog @@ -53,9 +53,9 @@ elif code in pep8.pep8_messages: message = QCoreApplication.translate( "pep8", pep8.pep8_messages[code]) - elif code in Pep8NamingChecker.Messages: + elif code in NamingStyleChecker.Messages: message = QCoreApplication.translate( - "Pep8NamingChecker", Pep8NamingChecker.Messages[code]) + "NamingStyleChecker", NamingStyleChecker.Messages[code]) elif code in DocStyleChecker.Messages: message = QCoreApplication.translate( "DocStyleChecker", DocStyleChecker.Messages[code])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/CheckerPlugins/Pep8/NamingStyleChecker.py Tue Oct 01 18:34:19 2013 +0200 @@ -0,0 +1,460 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2013 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a checker for PEP-8 naming conventions. +""" + +import collections +import ast +import re +import os + +from PyQt4.QtCore import QT_TRANSLATE_NOOP, QCoreApplication + + +class NamingStyleChecker(object): + """ + Class implementing a checker for PEP-8 naming conventions. + """ + LowercaseRegex = re.compile(r"[_a-z][_a-z0-9]*$") + UppercaseRegexp = re.compile(r"[_A-Z][_A-Z0-9]*$") + CamelcaseRegexp = re.compile(r"_?[A-Z][a-zA-Z0-9]*$") + MixedcaseRegexp = re.compile(r"_?[a-z][a-zA-Z0-9]*$") + + Codes = [ + "N801", "N802", "N803", "N804", "N805", "N806", "N807", "N808", + "N811", "N812", "N813", "N814", "N821", "N831" + ] + Messages = { + "N801": QT_TRANSLATE_NOOP("NamingStyleChecker", + "class names should use CapWords convention"), + "N802": QT_TRANSLATE_NOOP("NamingStyleChecker", + "function name should be lowercase"), + "N803": QT_TRANSLATE_NOOP("NamingStyleChecker", + "argument name should be lowercase"), + "N804": QT_TRANSLATE_NOOP("NamingStyleChecker", + "first argument of a class method should be named 'cls'"), + "N805": QT_TRANSLATE_NOOP("NamingStyleChecker", + "first argument of a method should be named 'self'"), + "N806": QT_TRANSLATE_NOOP("NamingStyleChecker", + "first argument of a static method should not be named" + " 'self' or 'cls"), + "N807": QT_TRANSLATE_NOOP("NamingStyleChecker", + "module names should be lowercase"), + "N808": QT_TRANSLATE_NOOP("NamingStyleChecker", + "package names should be lowercase"), + "N811": QT_TRANSLATE_NOOP("NamingStyleChecker", + "constant imported as non constant"), + "N812": QT_TRANSLATE_NOOP("NamingStyleChecker", + "lowercase imported as non lowercase"), + "N813": QT_TRANSLATE_NOOP("NamingStyleChecker", + "camelcase imported as lowercase"), + "N814": QT_TRANSLATE_NOOP("NamingStyleChecker", + "camelcase imported as constant"), + "N821": QT_TRANSLATE_NOOP("NamingStyleChecker", + "variable in function should be lowercase"), + "N831": QT_TRANSLATE_NOOP("NamingStyleChecker", + "names 'l', 'O' and 'I' should be avoided"), + } + + def __init__(self, tree, filename, options): + """ + 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.__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): + """ + Public method run by the pep8.py checker. + + @return tuple giving line number, offset within line, code and + checker function + """ + if self.__tree and self.__checkers: + return self.__visitTree(self.__tree) + else: + return () + + @classmethod + def getMessage(cls, code, *args): + """ + Class method to get a translated and formatted message for a + given code. + + @param code message code (string) + @param args arguments for a formatted message (list) + @return translated and formatted message (string) + """ + if code in cls.Messages: + return code + " " + QCoreApplication.translate("NamingStyleChecker", + cls.Messages[code]).format(*args) + else: + return code + " " + QCoreApplication.translate("NamingStyleChecker", + "no message for this code defined") + + def __visitTree(self, node): + """ + Private method to scan the given AST tree. + + @param node AST tree node to scan + @return tuple giving line number, offset within line, code and + checker function + """ + for error in self.__visitNode(node): + yield error + self.__parents.append(node) + for child in ast.iter_child_nodes(node): + for error in self.__visitTree(child): + yield error + self.__parents.pop() + + def __visitNode(self, node): + """ + Private method to inspect the given AST node. + + @param node AST tree node to inspect + @return tuple giving line number, offset within line, code and + checker function + """ + if isinstance(node, ast.ClassDef): + self.__tagClassFunctions(node) + elif isinstance(node, ast.FunctionDef): + self.__findGlobalDefs(node) + + checkerName = node.__class__.__name__.lower() + if checkerName in self.__checkers: + for checker in self.__checkers[checkerName]: + for error in checker(node, self.__parents): + yield error + (self.__checkers[checkerName],) + + def __tagClassFunctions(self, classNode): + """ + Private method to tag functions if they are methods, class methods or + static methods. + + @param classNode AST tree node to tag + """ + # try to find all 'old style decorators' like + # m = staticmethod(m) + lateDecoration = {} + for node in ast.iter_child_nodes(classNode): + if not (isinstance(node, ast.Assign) and + isinstance(node.value, ast.Call) and + isinstance(node.value.func, ast.Name)): + continue + funcName = node.value.func.id + if funcName in ("classmethod", "staticmethod"): + meth = (len(node.value.args) == 1 and node.value.args[0]) + if isinstance(meth, ast.Name): + lateDecoration[meth.id] = funcName + + # iterate over all functions and tag them + for node in ast.iter_child_nodes(classNode): + if not isinstance(node, ast.FunctionDef): + continue + + node.function_type = 'method' + if node.name == "__new__": + node.function_type = "classmethod" + + if node.name in lateDecoration: + node.function_type = lateDecoration[node.name] + elif node.decorator_list: + names = [d.id for d in node.decorator_list + if isinstance(d, ast.Name) and + d.id in ("classmethod", "staticmethod")] + if names: + node.function_type = names[0] + + def __findGlobalDefs(self, functionNode): + """ + Private method amend a node with global definitions information. + + @param functionNode AST tree node to amend + """ + globalNames = set() + nodesToCheck = collections.deque(ast.iter_child_nodes(functionNode)) + while nodesToCheck: + node = nodesToCheck.pop() + if isinstance(node, ast.Global): + globalNames.update(node.names) + + if not isinstance(node, (ast.FunctionDef, ast.ClassDef)): + nodesToCheck.extend(ast.iter_child_nodes(node)) + functionNode.global_names = globalNames + + def __getArgNames(self, node): + """ + Private method to get the argument names of a function node. + + @param node AST node to extract arguments names from + @return list of argument names (list of string) + """ + posArgs = [arg.arg for arg in node.args.args] + kwOnly = [arg.arg for arg in node.args.kwonlyargs] + return posArgs + kwOnly + + def __error(self, node, code): + """ + Private method to build the error information. + + @param node AST node to report an error for + @param code error code to report (string) + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + if isinstance(node, ast.Module): + lineno = 0 + offset = 0 + else: + lineno = node.lineno + offset = node.col_offset + if isinstance(node, ast.ClassDef): + lineno += len(node.decorator_list) + offset += 6 + elif isinstance(node, ast.FunctionDef): + lineno += len(node.decorator_list) + offset += 4 + return (lineno, offset, code) + + def __isNameToBeAvoided(self, name): + """ + Private method to check, if the given name should be avoided. + + @param name name to be checked (string) + @return flag indicating to avoid it (boolen) + """ + 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 + @param parents list of parent nodes + @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). + + Almost without exception, class names use the CapWords convention. + Classes for internal use have a leading underscore in addition. + + @param node AST note to check + @param parents list of parent nodes + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + 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). + + Function names should be lowercase, with words separated by underscores + as necessary to improve readability. Functions <b>not</b> being + methods '__' in front and back are not allowed. Mixed case is allowed + only in contexts where that's already the prevailing style + (e.g. threading.py), to retain backwards compatibility. + + @param node AST note to check + @param parents list of parent nodes + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + functionType = getattr(node, "function_type", "function") + name = node.name + if (functionType == "function" and "__" in (name[:2], name[-2:])) or \ + not self.LowercaseRegex.match(name): + yield self.__error(node, "N802") + + def __checkFunctionArgumentNames(self, node, parents): + """ + Private class to check the argument names of functions + (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 + first argument. A method should have 'self' as the first argument. + + @param node AST note to check + @param parents list of parent nodes + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + if node.args.kwarg is not None: + if not self.LowercaseRegex.match(node.args.kwarg): + yield self.__error(node, "N803") + return + + if node.args.vararg is not None: + if not self.LowercaseRegex.match(node.args.vararg): + yield self.__error(node, "N803") + return + + argNames = self.__getArgNames(node) + functionType = getattr(node, "function_type", "function") + + if not argNames: + if functionType == "method": + yield self.__error(node, "N805") + elif functionType == "classmethod": + yield self.__error(node, "N804") + return + + if functionType == "method": + if argNames[0] != "self": + yield self.__error(node, "N805") + elif functionType == "classmethod": + if argNames[0] != "cls": + yield self.__error(node, "N804") + elif functionType == "staticmethod": + if argNames[0] in ("cls", "self"): + yield self.__error(node, "N806") + for arg in argNames: + 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). + + Local variables in functions should be lowercase. + + @param node AST note to check + @param parents list of parent nodes + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + for parentFunc in reversed(parents): + if isinstance(parentFunc, ast.ClassDef): + return + if isinstance(parentFunc, ast.FunctionDef): + break + else: + return + for target in node.targets: + name = isinstance(target, ast.Name) and target.id + if not name or name in parentFunc.global_names: + return + + if not self.LowercaseRegex.match(name) and name[:1] != '_': + yield self.__error(target, "N821") + + def __checkModule(self, node, parents): + """ + Private method to check module naming conventions (N807, N808). + + Module and package names should be lowercase. + + @param node AST note to check + @param parents list of parent nodes + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + if self.__filename: + moduleName = os.path.splitext(os.path.basename(self.__filename))[0] + if moduleName.lower() != moduleName: + yield self.__error(node, "N807") + + if moduleName == "__init__": + # we got a package + packageName = \ + os.path.split(os.path.dirname(self.__filename))[1] + if packageName.lower != packageName: + yield self.__error(node, "N808") + + def __checkImportAs(self, node, parents): + """ + Private method to check that imports don't change the + naming convention (N811, N812, N813, N814). + + @param node AST note to check + @param parents list of parent nodes + @return tuple giving line number, offset within line and error code + (integer, integer, string) + """ + for name in node.names: + if not name.asname: + continue + + if self.UppercaseRegexp.match(name.name): + if not self.UppercaseRegexp.match(name.asname): + yield self.__error(node, "N811") + elif self.LowercaseRegex.match(name.name): + if not self.LowercaseRegex.match(name.asname): + yield self.__error(node, "N812") + elif self.LowercaseRegex.match(name.asname): + yield self.__error(node, "N813") + elif self.UppercaseRegexp.match(name.asname): + yield self.__error(node, "N814")
--- a/Plugins/CheckerPlugins/Pep8/Pep8NamingChecker.py Tue Oct 01 18:31:05 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,460 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2013 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a checker for PEP-8 naming conventions. -""" - -import collections -import ast -import re -import os - -from PyQt4.QtCore import QT_TRANSLATE_NOOP, QCoreApplication - - -class Pep8NamingChecker(object): - """ - Class implementing a checker for PEP-8 naming conventions. - """ - LowercaseRegex = re.compile(r"[_a-z][_a-z0-9]*$") - UppercaseRegexp = re.compile(r"[_A-Z][_A-Z0-9]*$") - CamelcaseRegexp = re.compile(r"_?[A-Z][a-zA-Z0-9]*$") - MixedcaseRegexp = re.compile(r"_?[a-z][a-zA-Z0-9]*$") - - Codes = [ - "N801", "N802", "N803", "N804", "N805", "N806", "N807", "N808", - "N811", "N812", "N813", "N814", "N821", "N831" - ] - Messages = { - "N801": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "class names should use CapWords convention"), - "N802": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "function name should be lowercase"), - "N803": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "argument name should be lowercase"), - "N804": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "first argument of a class method should be named 'cls'"), - "N805": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "first argument of a method should be named 'self'"), - "N806": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "first argument of a static method should not be named" - " 'self' or 'cls"), - "N807": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "module names should be lowercase"), - "N808": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "package names should be lowercase"), - "N811": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "constant imported as non constant"), - "N812": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "lowercase imported as non lowercase"), - "N813": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "camelcase imported as lowercase"), - "N814": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "camelcase imported as constant"), - "N821": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "variable in function should be lowercase"), - "N831": QT_TRANSLATE_NOOP("Pep8NamingChecker", - "names 'l', 'O' and 'I' should be avoided"), - } - - def __init__(self, tree, filename, options): - """ - 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.__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): - """ - Public method run by the pep8.py checker. - - @return tuple giving line number, offset within line, code and - checker function - """ - if self.__tree and self.__checkers: - return self.__visitTree(self.__tree) - else: - return () - - @classmethod - def getMessage(cls, code, *args): - """ - Class method to get a translated and formatted message for a - given code. - - @param code message code (string) - @param args arguments for a formatted message (list) - @return translated and formatted message (string) - """ - if code in cls.Messages: - return code + " " + QCoreApplication.translate("Pep8NamingChecker", - cls.Messages[code]).format(*args) - else: - return code + " " + QCoreApplication.translate("Pep8NamingChecker", - "no message for this code defined") - - def __visitTree(self, node): - """ - Private method to scan the given AST tree. - - @param node AST tree node to scan - @return tuple giving line number, offset within line, code and - checker function - """ - for error in self.__visitNode(node): - yield error - self.__parents.append(node) - for child in ast.iter_child_nodes(node): - for error in self.__visitTree(child): - yield error - self.__parents.pop() - - def __visitNode(self, node): - """ - Private method to inspect the given AST node. - - @param node AST tree node to inspect - @return tuple giving line number, offset within line, code and - checker function - """ - if isinstance(node, ast.ClassDef): - self.__tagClassFunctions(node) - elif isinstance(node, ast.FunctionDef): - self.__findGlobalDefs(node) - - checkerName = node.__class__.__name__.lower() - if checkerName in self.__checkers: - for checker in self.__checkers[checkerName]: - for error in checker(node, self.__parents): - yield error + (self.__checkers[checkerName],) - - def __tagClassFunctions(self, classNode): - """ - Private method to tag functions if they are methods, class methods or - static methods. - - @param classNode AST tree node to tag - """ - # try to find all 'old style decorators' like - # m = staticmethod(m) - lateDecoration = {} - for node in ast.iter_child_nodes(classNode): - if not (isinstance(node, ast.Assign) and - isinstance(node.value, ast.Call) and - isinstance(node.value.func, ast.Name)): - continue - funcName = node.value.func.id - if funcName in ("classmethod", "staticmethod"): - meth = (len(node.value.args) == 1 and node.value.args[0]) - if isinstance(meth, ast.Name): - lateDecoration[meth.id] = funcName - - # iterate over all functions and tag them - for node in ast.iter_child_nodes(classNode): - if not isinstance(node, ast.FunctionDef): - continue - - node.function_type = 'method' - if node.name == "__new__": - node.function_type = "classmethod" - - if node.name in lateDecoration: - node.function_type = lateDecoration[node.name] - elif node.decorator_list: - names = [d.id for d in node.decorator_list - if isinstance(d, ast.Name) and - d.id in ("classmethod", "staticmethod")] - if names: - node.function_type = names[0] - - def __findGlobalDefs(self, functionNode): - """ - Private method amend a node with global definitions information. - - @param functionNode AST tree node to amend - """ - globalNames = set() - nodesToCheck = collections.deque(ast.iter_child_nodes(functionNode)) - while nodesToCheck: - node = nodesToCheck.pop() - if isinstance(node, ast.Global): - globalNames.update(node.names) - - if not isinstance(node, (ast.FunctionDef, ast.ClassDef)): - nodesToCheck.extend(ast.iter_child_nodes(node)) - functionNode.global_names = globalNames - - def __getArgNames(self, node): - """ - Private method to get the argument names of a function node. - - @param node AST node to extract arguments names from - @return list of argument names (list of string) - """ - posArgs = [arg.arg for arg in node.args.args] - kwOnly = [arg.arg for arg in node.args.kwonlyargs] - return posArgs + kwOnly - - def __error(self, node, code): - """ - Private method to build the error information. - - @param node AST node to report an error for - @param code error code to report (string) - @return tuple giving line number, offset within line and error code - (integer, integer, string) - """ - if isinstance(node, ast.Module): - lineno = 0 - offset = 0 - else: - lineno = node.lineno - offset = node.col_offset - if isinstance(node, ast.ClassDef): - lineno += len(node.decorator_list) - offset += 6 - elif isinstance(node, ast.FunctionDef): - lineno += len(node.decorator_list) - offset += 4 - return (lineno, offset, code) - - def __isNameToBeAvoided(self, name): - """ - Private method to check, if the given name should be avoided. - - @param name name to be checked (string) - @return flag indicating to avoid it (boolen) - """ - 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 - @param parents list of parent nodes - @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). - - Almost without exception, class names use the CapWords convention. - Classes for internal use have a leading underscore in addition. - - @param node AST note to check - @param parents list of parent nodes - @return tuple giving line number, offset within line and error code - (integer, integer, string) - """ - 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). - - Function names should be lowercase, with words separated by underscores - as necessary to improve readability. Functions <b>not</b> being - methods '__' in front and back are not allowed. Mixed case is allowed - only in contexts where that's already the prevailing style - (e.g. threading.py), to retain backwards compatibility. - - @param node AST note to check - @param parents list of parent nodes - @return tuple giving line number, offset within line and error code - (integer, integer, string) - """ - functionType = getattr(node, "function_type", "function") - name = node.name - if (functionType == "function" and "__" in (name[:2], name[-2:])) or \ - not self.LowercaseRegex.match(name): - yield self.__error(node, "N802") - - def __checkFunctionArgumentNames(self, node, parents): - """ - Private class to check the argument names of functions - (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 - first argument. A method should have 'self' as the first argument. - - @param node AST note to check - @param parents list of parent nodes - @return tuple giving line number, offset within line and error code - (integer, integer, string) - """ - if node.args.kwarg is not None: - if not self.LowercaseRegex.match(node.args.kwarg): - yield self.__error(node, "N803") - return - - if node.args.vararg is not None: - if not self.LowercaseRegex.match(node.args.vararg): - yield self.__error(node, "N803") - return - - argNames = self.__getArgNames(node) - functionType = getattr(node, "function_type", "function") - - if not argNames: - if functionType == "method": - yield self.__error(node, "N805") - elif functionType == "classmethod": - yield self.__error(node, "N804") - return - - if functionType == "method": - if argNames[0] != "self": - yield self.__error(node, "N805") - elif functionType == "classmethod": - if argNames[0] != "cls": - yield self.__error(node, "N804") - elif functionType == "staticmethod": - if argNames[0] in ("cls", "self"): - yield self.__error(node, "N806") - for arg in argNames: - 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). - - Local variables in functions should be lowercase. - - @param node AST note to check - @param parents list of parent nodes - @return tuple giving line number, offset within line and error code - (integer, integer, string) - """ - for parentFunc in reversed(parents): - if isinstance(parentFunc, ast.ClassDef): - return - if isinstance(parentFunc, ast.FunctionDef): - break - else: - return - for target in node.targets: - name = isinstance(target, ast.Name) and target.id - if not name or name in parentFunc.global_names: - return - - if not self.LowercaseRegex.match(name) and name[:1] != '_': - yield self.__error(target, "N821") - - def __checkModule(self, node, parents): - """ - Private method to check module naming conventions (N807, N808). - - Module and package names should be lowercase. - - @param node AST note to check - @param parents list of parent nodes - @return tuple giving line number, offset within line and error code - (integer, integer, string) - """ - if self.__filename: - moduleName = os.path.splitext(os.path.basename(self.__filename))[0] - if moduleName.lower() != moduleName: - yield self.__error(node, "N807") - - if moduleName == "__init__": - # we got a package - packageName = \ - os.path.split(os.path.dirname(self.__filename))[1] - if packageName.lower != packageName: - yield self.__error(node, "N808") - - def __checkImportAs(self, node, parents): - """ - Private method to check that imports don't change the - naming convention (N811, N812, N813, N814). - - @param node AST note to check - @param parents list of parent nodes - @return tuple giving line number, offset within line and error code - (integer, integer, string) - """ - for name in node.names: - if not name.asname: - continue - - if self.UppercaseRegexp.match(name.name): - if not self.UppercaseRegexp.match(name.asname): - yield self.__error(node, "N811") - elif self.LowercaseRegex.match(name.name): - if not self.LowercaseRegex.match(name.asname): - yield self.__error(node, "N812") - elif self.LowercaseRegex.match(name.asname): - yield self.__error(node, "N813") - elif self.UppercaseRegexp.match(name.asname): - yield self.__error(node, "N814")
--- a/eric5.e4p Tue Oct 01 18:31:05 2013 +0200 +++ b/eric5.e4p Tue Oct 01 18:34:19 2013 +0200 @@ -1101,7 +1101,6 @@ <Source>Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialUserDataDialog.py</Source> <Source>Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.py</Source> <Source>Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.py</Source> - <Source>Plugins/CheckerPlugins/Pep8/Pep8NamingChecker.py</Source> <Source>UtilitiesPython2/Pep8NamingCheckerPy2.py</Source> <Source>UtilitiesPython2/Pep257CheckerPy2.py</Source> <Source>Plugins/CheckerPlugins/Pep8/DocStyleChecker.py</Source> @@ -1110,6 +1109,7 @@ <Source>Plugins/CheckerPlugins/Pep8/CodeStyleCodeSelectionDialog.py</Source> <Source>Plugins/CheckerPlugins/Pep8/CodeStyleCheckerDialog.py</Source> <Source>Plugins/CheckerPlugins/Pep8/CodeStyleFixer.py</Source> + <Source>Plugins/CheckerPlugins/Pep8/NamingStyleChecker.py</Source> </Sources> <Forms> <Form>PyUnit/UnittestDialog.ui</Form>