# HG changeset patch
# User Mike Bryant <leachim@leachim.info>
# Date 1354815877 0
# Thu Dec 06 17:44:37 2012 +0000
# Node ID 27d5a6ff3ea8c51a263381c59306b66a7be2e2aa
# Parent dc6a12f97c9a9fb6c9a5fc3db545e66ed6d28528
closes #113231. logging checker now looks at instances of Logger classes in addition to the base logging module.
# User Mike Bryant <leachim@leachim.info>
# Date 1354815877 0
# Thu Dec 06 17:44:37 2012 +0000
# Node ID 27d5a6ff3ea8c51a263381c59306b66a7be2e2aa
# Parent dc6a12f97c9a9fb6c9a5fc3db545e66ed6d28528
closes #113231. logging checker now looks at instances of Logger classes in addition to the base logging module.
@@ -22,10 +22,13 @@
1 and useless suppression pragmas. (patch by Torsten Marek) 2 3 * #112728: Add warning E0604 for non-string objects in __all__ 4 (patch by Torsten Marek) 5 6 + * #113231: logging checker now looks at instances of Logger classes 7 + in addition to the base logging module. (patch by Mike Bryant) 8 + 9 -- 10 * #115580: fix erroneous W0212 (access to protected member) on super call 11 (patch by Martin Pool) 12 13 * #110853: fix a crash when an __init__ method in a base class has been
@@ -78,12 +78,21 @@
14 self._logging_name = 'logging' 15 16 def visit_callfunc(self, node): 17 """Checks calls to (simple forms of) logging methods.""" 18 if (not isinstance(node.func, astng.Getattr) 19 - or not isinstance(node.func.expr, astng.Name) 20 - or node.func.expr.name != self._logging_name): 21 + or not isinstance(node.func.expr, astng.Name)): 22 + return 23 + try: 24 + logger_class = [inferred for inferred in node.func.expr.infer() if ( 25 + isinstance(inferred, astng.Instance) 26 + and [ancestor for ancestor in inferred._proxied.ancestors() if ( 27 + ancestor.name == 'Logger' 28 + and ancestor.parent.name == 'logging')])] 29 + except astng.exceptions.InferenceError: 30 + return 31 + if (node.func.expr.name != self._logging_name and not logger_class): 32 return 33 self._check_convenience_methods(node) 34 self._check_log_methods(node) 35 36 def _check_convenience_methods(self, node):
@@ -0,0 +1,24 @@
37 +# pylint: disable=E1101 38 +# pylint: disable=C0103 39 +# pylint: disable=R0903 40 +"""test bugfix for #113231 in logging checker 41 +""" 42 + 43 +__revision__ = '' 44 + 45 +# Muck up the names in an effort to confuse... 46 +import logging as renamed_logging 47 + 48 +class Logger(object): 49 + """Fake logger""" 50 + pass 51 + 52 +logger = renamed_logging.getLogger(__name__) 53 +fake_logger = Logger() 54 + 55 +# Statements that should be flagged: 56 +renamed_logging.warn('%s, %s' % (4, 5)) 57 +logger.warn('%s' % 5) 58 + 59 +# Statements that should not be flagged: 60 +fake_logger.warn('%s' % 5)
@@ -0,0 +1,2 @@
61 +W: 20: Specify string format arguments as logging function parameters 62 +W: 21: Specify string format arguments as logging function parameters