← Back to team overview

divmod-dev team mailing list archive

Patch to check count of string formatting arguments

 

Hi -

I love pyflakes, so thanks for your work on it. For me, the only bugs that
crept past pyflakes were where I had bad string formatting arguments, so I
dived in and added a simple check for this.

If the attached patch (against 0.5.0) is any use to you, I would be very
happy to contribute it to your project. I guess it could be extended to
check types too, but that's for another day...

Cheers!
Greg Fawcett.

Phone: +64 3 409 8165
Mobile: +64 21 333 291
Web: www.schoolinterviews.co.nz
diff --git a/checker.py b/checker.py
index 6d711f1..79e3626 100644
--- a/checker.py
+++ b/checker.py
@@ -322,7 +322,8 @@ class Checker(object):
     CONTINUE = BREAK = PASS = ignore
 
     # "expr" type nodes
-    BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = YIELD = COMPARE = \
+#GCF    BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = YIELD = COMPARE = \
+    BOOLOP = UNARYOP = IFEXP = DICT = SET = YIELD = COMPARE = \
     CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = handleChildren
 
     NUM = STR = ELLIPSIS = ignore
@@ -622,3 +623,18 @@ class Checker(object):
             if node.module == '__future__':
                 importation.used = (self.scope, node.lineno)
             self.addBinding(node.lineno, importation)
+
+    #GCF Added to catch string format errors
+    def BINOP(self, node):
+        if isinstance(node.op, _ast.Mod) and isinstance(node.left, _ast.Str) \
+              and isinstance(node.right, _ast.Tuple):
+            needs_args=node.left.s.count('%')-(2*node.left.s.count('%%'))
+            has_args=len(node.right.elts)
+            if needs_args!=has_args:
+                self.report(messages.StringFormattingProblem,
+                                        node.lineno, needs_args, has_args)
+            self.handleNode(node.left, node)
+            self.handleNode(node.right, node)
+        else:
+            self.handleNode(node.left, node)
+            self.handleNode(node.right, node)
diff --git a/messages.py b/messages.py
index 147b562..bf6d83e 100644
--- a/messages.py
+++ b/messages.py
@@ -92,3 +92,10 @@ class UnusedVariable(Message):
     def __init__(self, filename, lineno, names):
         Message.__init__(self, filename, lineno)
         self.message_args = (names,)
+
+#GCF
+class StringFormattingProblem(Message):
+    message = 'string formatting needs %r arguments but has %r'
+    def __init__(self, filename, lineno, needs_args, has_args):
+        Message.__init__(self, filename, lineno)
+        self.message_args = (needs_args, has_args)