diff options
author | Anthony Truchet <anthony.truchet@logilab.fr> | 2013-06-18 16:23:55 +0200 |
---|---|---|
committer | Anthony Truchet <anthony.truchet@logilab.fr> | 2013-06-18 16:23:55 +0200 |
commit | 466c8a983de64106ab0226d16d944c2bca8d2518 (patch) | |
tree | fe2c36e481d82716f1aeb389a5872bd304e9350b | |
parent | f6b5fc84a2ff8935e1f2d1f0304d7290adb8c6af (diff) | |
download | pylint-466c8a983de64106ab0226d16d944c2bca8d2518.tar.gz |
Add @check_messages(...) annotations to help not to spend time on unneeded checks.
We only add such annotations is reasonably simple cases.
Some visit methods are quite involved and build a checker's state ;
such methods are skipped in the first phase.
-rw-r--r-- | checkers/base.py | 12 | ||||
-rw-r--r-- | checkers/design_analysis.py | 12 | ||||
-rw-r--r-- | checkers/exceptions.py | 5 | ||||
-rw-r--r-- | checkers/imports.py | 5 | ||||
-rw-r--r-- | checkers/logging.py | 3 | ||||
-rw-r--r-- | checkers/strings.py | 5 | ||||
-rw-r--r-- | checkers/typecheck.py | 3 | ||||
-rw-r--r-- | checkers/variables.py | 8 |
8 files changed, 38 insertions, 15 deletions
diff --git a/checkers/base.py b/checkers/base.py index 6cb6b9a..5ebac40 100644 --- a/checkers/base.py +++ b/checkers/base.py @@ -396,7 +396,7 @@ functions, methods self._tryfinallys = [] self.stats = self.linter.add_stats(module=0, function=0, method=0, class_=0) - + @check_messages('C0121') def visit_module(self, node): """check module name, docstring and required arguments """ @@ -411,7 +411,7 @@ functions, methods """ self.stats['class'] += 1 - @check_messages('W0104', 'W0105') + @check_messages('W0104', 'W0105', 'W0106') def visit_discard(self, node): """check for various kind of statements without effect""" expr = node.value @@ -487,6 +487,7 @@ functions, methods return self.add_message('W0108', line=node.fromlineno, node=node) + @check_messages('W0102') def visit_function(self, node): """check function name, docstring, arguments, redefinition, variable names, max locals @@ -812,14 +813,15 @@ class DocStringChecker(_BasicChecker): undocumented_function=0, undocumented_method=0, undocumented_class=0) - + @check_messages('C0111', 'C0112') def visit_module(self, node): self._check_docstring('module', node) + @check_messages('C0111', 'C0112') def visit_class(self, node): if self.config.no_docstring_rgx.match(node.name) is None: self._check_docstring('class', node) - + @check_messages('C0111', 'C0112') def visit_function(self, node): if self.config.no_docstring_rgx.match(node.name) is None: ftype = node.is_method() and 'method' or 'function' @@ -854,7 +856,7 @@ class PassChecker(_BasicChecker): 'Used when a "pass" statement that can be avoided is ' 'encountered.'), } - + @check_messages('W0107') def visit_pass(self, node): if len(node.parent.child_sequence(node)) > 1: self.add_message('W0107', node=node) diff --git a/checkers/design_analysis.py b/checkers/design_analysis.py index 2a6b308..5e60ccb 100644 --- a/checkers/design_analysis.py +++ b/checkers/design_analysis.py @@ -19,6 +19,7 @@ from astroid import Function, If, InferenceError from pylint.interfaces import IAstroidChecker from pylint.checkers import BaseChecker +from pylint.checkers.utils import check_messages import re @@ -78,11 +79,11 @@ MSGS = { 'R0901': ('Too many ancestors (%s/%s)', 'too-many-ancestors', 'Used when class has too many parent classes, try to reduce \ - this to get a more simple (and so easier to use) class.'), + this to get a simpler (and so easier to use) class.'), 'R0902': ('Too many instance attributes (%s/%s)', 'too-many-instance-attributes', 'Used when class has too many instance attributes, try to reduce \ - this to get a more simple (and so easier to use) class.'), + this to get a simpler (and so easier to use) class.'), 'R0903': ('Too few public methods (%s/%s)', 'too-few-public-methods', 'Used when class has too few public methods, so be sure it\'s \ @@ -90,7 +91,7 @@ MSGS = { 'R0904': ('Too many public methods (%s/%s)', 'too-many-public-methods', 'Used when class has too many public methods, try to reduce \ - this to get a more simple (and so easier to use) class.'), + this to get a simpler (and so easier to use) class.'), 'R0911': ('Too many return statements (%s/%s)', 'too-many-return-statements', @@ -220,6 +221,7 @@ class MisdesignChecker(BaseChecker): self._abstracts = [] self._ifaces = [] + # Check 'R0921', 'R0922', 'R0923' def close(self): """check that abstract/interface classes are used""" for abstract in self._abstracts: @@ -232,6 +234,7 @@ class MisdesignChecker(BaseChecker): if not iface in self._used_ifaces: self.add_message('R0923', node=iface) + @check_messages('R0901', 'R0902', 'R0903', 'R0904', 'R0921', 'R0922', 'R0923') def visit_class(self, node): """check size of inheritance hierarchy and number of instance attributes """ @@ -269,6 +272,7 @@ class MisdesignChecker(BaseChecker): except KeyError: self._used_abstracts[parent] = 1 + @check_messages('R0901', 'R0902', 'R0903', 'R0904', 'R0921', 'R0922', 'R0923') def leave_class(self, node): """check number of public methods""" nb_public_methods = 0 @@ -299,6 +303,7 @@ class MisdesignChecker(BaseChecker): args=(nb_public_methods, self.config.min_public_methods)) + @check_messages('R0911', 'R0912', 'R0913', 'R0914', 'R0915') def visit_function(self, node): """check function name, docstring, arguments, redefinition, variable names, max locals @@ -327,6 +332,7 @@ class MisdesignChecker(BaseChecker): # init statements counter self._stmts = 1 + @check_messages('R0911', 'R0912', 'R0913', 'R0914', 'R0915') def leave_function(self, node): """most of the work is done here on close: checks for max returns, branch, return in __init__ diff --git a/checkers/exceptions.py b/checkers/exceptions.py index b681c6d..f5bde30 100644 --- a/checkers/exceptions.py +++ b/checkers/exceptions.py @@ -22,7 +22,7 @@ import astroid from astroid import YES, Instance, unpack_infer from pylint.checkers import BaseChecker -from pylint.checkers.utils import is_empty, is_raising +from pylint.checkers.utils import is_empty, is_raising, check_messages from pylint.interfaces import IAstroidChecker @@ -99,6 +99,7 @@ class ExceptionsChecker(BaseChecker): ), ) + @check_messages('W0701', 'W0710', 'E0702', 'E0710', 'E0711') def visit_raise(self, node): """visit raise possibly inferring value""" # ignore empty raise @@ -153,7 +154,7 @@ class ExceptionsChecker(BaseChecker): value_found = False return value_found - + @check_messages('W0702', 'W0703', 'W0704', 'W0711', 'E0701') def visit_tryexcept(self, node): """check for empty except""" exceptions_classes = [] diff --git a/checkers/imports.py b/checkers/imports.py index c289b86..0047c1d 100644 --- a/checkers/imports.py +++ b/checkers/imports.py @@ -24,6 +24,7 @@ from astroid import are_exclusive from pylint.interfaces import IAstroidChecker from pylint.checkers import BaseChecker, EmptyReport +from pylint.checkers.utils import check_messages def get_first_import(node, context, name, base, level): @@ -232,7 +233,9 @@ given file (report RP0402 must not be disabled)'} self._check_deprecated_module(node, name) self._check_reimport(node, name) - + # TODO This appears to be the list of all messages of the checker... + # @check_messages('W0410', 'W0401', 'W0403', 'W0402', 'W0404', 'W0406', 'F0401') + @check_messages(*(MSGS.keys())) def visit_from(self, node): """triggered when a from statement is seen""" basename = node.modname diff --git a/checkers/logging.py b/checkers/logging.py index 2cbdedc..6986ca4 100644 --- a/checkers/logging.py +++ b/checkers/logging.py @@ -18,7 +18,7 @@ import astroid from pylint import checkers from pylint import interfaces from pylint.checkers import utils - +from pylint.checkers.utils import check_messages MSGS = { 'W1201': ('Specify string format arguments as logging function parameters', @@ -77,6 +77,7 @@ class LoggingChecker(checkers.BaseChecker): else: self._logging_name = 'logging' + @check_messages(*(MSGS.keys())) def visit_callfunc(self, node): """Checks calls to (simple forms of) logging methods.""" if (not isinstance(node.func, astroid.Getattr) diff --git a/checkers/strings.py b/checkers/strings.py index 5bb187a..6a4ab7b 100644 --- a/checkers/strings.py +++ b/checkers/strings.py @@ -26,6 +26,7 @@ import astroid from pylint.interfaces import ITokenChecker, IAstroidChecker from pylint.checkers import BaseChecker, BaseTokenChecker from pylint.checkers import utils +from pylint.checkers.utils import check_messages _PY3K = sys.version_info >= (3, 0) @@ -84,7 +85,8 @@ class StringFormatChecker(BaseChecker): __implements__ = (IAstroidChecker,) name = 'string' msgs = MSGS - + + @check_messages(*(MSGS.keys())) def visit_binop(self, node): if node.op != '%': return @@ -175,6 +177,7 @@ class StringMethodsChecker(BaseChecker): " duplicate character, "), } + @check_messages(*(MSGS.keys())) def visit_callfunc(self, node): func = utils.safe_infer(node.func) if (isinstance(func, astroid.BoundMethod) diff --git a/checkers/typecheck.py b/checkers/typecheck.py index fba00d4..4783d22 100644 --- a/checkers/typecheck.py +++ b/checkers/typecheck.py @@ -212,7 +212,7 @@ accessed. Python regular expressions are accepted.'} args=(owner.display_type(), name, node.attrname)) - + @check_messages('E1111', 'W1111') def visit_assign(self, node): """check that if assigning to a function call, the function is possibly returning something valuable @@ -239,6 +239,7 @@ accessed. Python regular expressions are accepted.'} else: self.add_message('W1111', node=node) + @check_messages(*(MSGS.keys())) def visit_callfunc(self, node): """check that called functions/methods are inferred to callable objects, and that the arguments passed to the function match the parameters in diff --git a/checkers/variables.py b/checkers/variables.py index 3c93d17..dca13b5 100644 --- a/checkers/variables.py +++ b/checkers/variables.py @@ -156,6 +156,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' self._to_consume = None self._checking_mod_attr = None + def visit_module(self, node): """visit module : update consumption analysis variable checks globals doesn't overrides builtins @@ -166,7 +167,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' # do not print Redefining builtin for additional builtins self.add_message('W0622', args=name, node=stmts[0]) - @check_messages('W0611', 'W0614') + @check_messages('W0611', 'W0614', 'W0622', 'E0603', 'E0604') def leave_module(self, node): """leave module: check globals """ @@ -261,6 +262,8 @@ builtins. Remember that you should avoid to define new builtins when possible.' # do not check for not used locals here self._to_consume.pop() + + @check_messages('W0621', 'W0622') def visit_function(self, node): """visit function: update consumption analysis variable and check locals """ @@ -280,6 +283,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' # do not print Redefining builtin for additional builtins self.add_message('W0622', args=name, node=stmt) + @check_messages('W0612', 'W0613') def leave_function(self, node): """leave function: check function's locals are consumed""" not_consumed = self._to_consume.pop()[0] @@ -405,6 +409,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' and not ass.statement() is node.statement(): self.add_message('W0631', args=name, node=node) + @check_messages('W0623') def visit_excepthandler(self, node): for name in get_all_elements(node.name): clobbering, args = clobber_in_except(name) @@ -418,6 +423,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' def visit_delname(self, node): self.visit_name(node) + @check_messages(*(MSGS.keys())) def visit_name(self, node): """check that a name is defined if the current scope and doesn't redefine a built-in |