diff options
| author | Claudiu Popa <pcmanticore@gmail.com> | 2014-09-10 21:29:41 +0300 |
|---|---|---|
| committer | Claudiu Popa <pcmanticore@gmail.com> | 2014-09-10 21:29:41 +0300 |
| commit | 099da645ea9c3fc33eb0fdbb060c9b1054a2828a (patch) | |
| tree | 339e17a8627d18922190f6579dfd174b271136d4 /checkers/logging.py | |
| parent | f06bc4471171eac5698e478f1839557fb616a63d (diff) | |
| parent | c84f1c6ea5a92c57f17997f54dc4cd69d4f63a80 (diff) | |
| download | pylint-git-099da645ea9c3fc33eb0fdbb060c9b1054a2828a.tar.gz | |
Merge branches.
Diffstat (limited to 'checkers/logging.py')
| -rw-r--r-- | checkers/logging.py | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/checkers/logging.py b/checkers/logging.py index 39c4d9cee..277b8c0ef 100644 --- a/checkers/logging.py +++ b/checkers/logging.py @@ -35,6 +35,14 @@ MSGS = { 'interpolation in those cases in which no message will be ' 'logged. For more, see ' 'http://www.python.org/dev/peps/pep-0282/.'), + 'W1202': ('Use % formatting in logging functions but pass the % ' + 'parameters as arguments', + 'logging-format-interpolation', + 'Used when a logging statement has a call form of ' + '"logging.<logging method>(format_string.format(format_args...))"' + '. Such calls should use % formatting instead, but leave ' + 'interpolation to the logging function by passing the parameters ' + 'as arguments.'), 'E1200': ('Unsupported logging format character %r (%#02x) at index %d', 'logging-unsupported-format', 'Used when an unsupported format character is used in a logging\ @@ -65,11 +73,11 @@ class LoggingChecker(checkers.BaseChecker): msgs = MSGS options = (('logging-modules', - {'default' : ('logging',), - 'type' : 'csv', - 'metavar' : '<comma separated list>', - 'help' : 'Logging modules to check that the string format ' - 'arguments are in logging function parameter format'} + {'default': ('logging',), + 'type': 'csv', + 'metavar': '<comma separated list>', + 'help': 'Logging modules to check that the string format ' + 'arguments are in logging function parameter format'} ), ) @@ -134,6 +142,26 @@ class LoggingChecker(checkers.BaseChecker): return self._check_log_method(node, name) + def is_method_call(self, callfunc_node, types=(), methods=()): + """Determines if a CallFunc node represents a method call. + + Args: + callfunc_node: The CallFunc AST node to check. + types: Optional sequence of caller type names to restrict check. + methods: Optional sequence of method names to restrict check. + + Returns: + True, if the node represents a method call for the given type and + method names, False otherwise. + """ + if not isinstance(callfunc_node, astroid.CallFunc): + return False + func = utils.safe_infer(callfunc_node.func) + return (isinstance(func, astroid.BoundMethod) + and isinstance(func.bound, astroid.Instance) + and (func.bound.name in types if types else True) + and (func.name in methods if methods else True)) + def _check_log_method(self, node, name): """Checks calls to logging.log(level, format, *format_args).""" if name == 'log': @@ -153,9 +181,20 @@ class LoggingChecker(checkers.BaseChecker): if isinstance(node.args[format_pos], astroid.BinOp) and node.args[format_pos].op == '%': self.add_message('logging-not-lazy', node=node) + elif isinstance(node.args[format_pos], astroid.CallFunc): + self._check_call_func(node.args[format_pos]) elif isinstance(node.args[format_pos], astroid.Const): self._check_format_string(node, format_pos) + def _check_call_func(self, callfunc_node): + """Checks that function call is not format_string.format(). + + Args: + callfunc_node: CallFunc AST node to be checked. + """ + if self.is_method_call(callfunc_node, ('str', 'unicode'), ('format',)): + self.add_message('logging-format-interpolation', node=callfunc_node) + def _check_format_string(self, node, format_arg): """Checks that format string tokens match the supplied arguments. |
