diff options
-rw-r--r-- | checkers/strings.py | 39 | ||||
-rw-r--r-- | test/input/func_string_format_py27.py | 51 | ||||
-rw-r--r-- | test/messages/func_string_format_py27.txt | 50 |
3 files changed, 75 insertions, 65 deletions
diff --git a/checkers/strings.py b/checkers/strings.py index a15206d..b04d1c6 100644 --- a/checkers/strings.py +++ b/checkers/strings.py @@ -74,34 +74,34 @@ MSGS = { "Used when a format string that uses unnamed conversion \ specifiers is given too few arguments"), - 'W1302': ("Invalid Python 3 format string", + 'W1302': ("Invalid format string", "bad-format-string", - "Used when a Python 3 format string is invalid"), + "Used when a PEP 3101 format string is invalid"), 'W1303': ("Missing keyword argument %r for format string", "missing-format-argument-key", - "Used when a Python 3 format string that uses named fields \ - doesn't receive one or more required keywords."), + "Used when a PEP 3101 format string that uses named fields " + "doesn't receive one or more required keywords."), 'W1304': ("Unused format argument %r", "unused-format-string-argument", - "Used when a Python 3 format string that uses named \ - fields is used with an argument that \ - is not required by the format string."), + "Used when a PEP 3101 format string that uses named " + "fields is used with an argument that " + "is not required by the format string."), 'W1305': ("Format string contains both automatic field numbering " "and manual field specification", "format-combined-specification", - "Usen when a format string contains both automatic \ - field numbering (e.g. '{}') and manual field \ - specification (e.g. '{0}')"), + "Usen when a PEP 3101 format string contains both automatic " + "field numbering (e.g. '{}') and manual field " + "specification (e.g. '{0}')"), 'W1306': ("Missing format attribute %r in format specifier %r", "missing-format-attribute", - "Used when a format string uses an attribute specifier " - "({0.length}), but the argument passed for formatting " - "doesn't have that attribute."), + "Used when a PEP 3101 format string uses an " + "attribute specifier ({0.length}), but the argument " + "passed for formatting doesn't have that attribute."), 'W1307': ("Using invalid lookup key %r in format specifier %r", "invalid-format-index", - "Used when a format string uses a lookup specifier " + "Used when a PEP 3101 format string uses a lookup specifier " "({a[1]}), but the argument passed for formatting " - "doesn't contain that key.") + "doesn't contain or doesn't have that key as an attribute.") } OTHER_NODES = (astroid.Const, astroid.List, astroid.Backquote, @@ -372,6 +372,11 @@ class StringMethodsChecker(BaseChecker): for key, specifiers in fields: # Obtain the argument. If it can't be obtained # or infered, skip this check. + if key == '': + # {[0]} will have an unnamed argument, defaulting + # to 0. It will not be present in `named`, so use the value + # 0 for it. + key = 0 if isinstance(key, int): try: argument = utils.get_argument_from_call(node, key) @@ -384,7 +389,7 @@ class StringMethodsChecker(BaseChecker): if argument in (astroid.YES, None): continue try: - argument = next(argument.infer()) + argument = argument.infer().next() except astroid.InferenceError: continue if not specifiers or argument is astroid.YES: @@ -435,7 +440,7 @@ class StringMethodsChecker(BaseChecker): break try: - previous = next(previous.infer()) + previous = previous.infer().next() except astroid.InferenceError: # can't check further if we can't infer it break diff --git a/test/input/func_string_format_py27.py b/test/input/func_string_format_py27.py index 868355f..d2f5599 100644 --- a/test/input/func_string_format_py27.py +++ b/test/input/func_string_format_py27.py @@ -29,14 +29,36 @@ def log(message, message_type="error"): """ Test """
return message
-def pprint():
+def print_good():
+ """ Good format strings """
+ print "{0} {1}".format(1, 2)
+ print "{0!r:20}".format("Hello")
+ print "{!r:20}".format("Hello")
+ print "{a!r:20}".format(a="Hello")
+ print "{pid}".format(pid=os.getpid())
+ print str("{}").format(2)
+ print "{0.missing.length}".format(ReturnYes())
+ print "{1.missing.length}".format(ReturnYes())
+ print "{a.ids[3][1]}".format(a=Test())
+ print "{a[0][0]}".format(a=[[1]])
+ print "{[0][0]}".format({0: {0: 1}})
+ print "{a.test}".format(a=Custom())
+ print "{a.__len__}".format(a=[])
+ print "{a.ids.__len__}".format(a=Test())
+ print "{a[0]}".format(a=Getitem())
+ print "{a[0][0]}".format(a=[Getitem()])
+ print "{[0][0]}".format(["test"])
+ # these are skipped
+ print "{0} {1}".format(*[1, 2])
+ print "{a} {b}".format(**{'a': 1, 'b': 2})
+ print "{a}".format(a=Missing())
+
+def pprint_bad():
"""Test string format """
print "{{}}".format(1)
print "{} {".format()
print "{} }".format()
print "{0} {}".format(1, 2)
- print "{0} {1}".format(1, 2)
- print "{0} {1} {a}".format(1, 2, 3)
print "{a} {b}".format(a=1, c=2)
print "{} {a}".format(1, 2)
print "{} {}".format(1)
@@ -44,32 +66,13 @@ def pprint(): print "{a} {b} {c}".format()
print "{} {}".format(a=1, b=2)
print "{a} {b}".format(1, 2)
- print "{0!r:20}".format("Hello")
- print "{!r:20}".format("Hello")
- print "{a!r:20}".format(a="Hello")
- print "{a.test}".format(a=Custom())
- print "{a.__len__}".format(a=[])
- print "{a.ids.__len__}".format(a=Test())
+ print "{0} {1} {a}".format(1, 2, 3)
print "{a.ids.__len__.length}".format(a=Test())
- print "{a[0]}".format(a=Getitem())
- print "{a[0][0]}".format(a=[Getitem()])
- print "{a[0][0]}".format(a=[[1]])
- print "{[0][0]}".format(((1, )))
- print "{[0][0]}".format({0: {0: 1}})
- print "{[0][0]}".format(["test"])
- print "{a.ids[3][1]}".format(a=Test())
print "{a.ids[3][400]}".format(a=Test())
print "{a.ids[3]['string']}".format(a=Test())
print "{[0][1]}".format(["a"])
- print "{0.missing.length}".format(ReturnYes())
- print "{1.missing.length}".format(ReturnYes())
+ print "{[0][0]}".format(((1, )))
print "{b[0]}".format(a=23)
print "{a[0]}".format(a=object)
- print "{a}".format(a=Missing())
print log("{}".format(2, "info"))
- print "{pid}".format(pid=os.getpid())
print "{0.missing}".format(2)
- print str("{}").format(2)
- # these are skipped
- print "{0} {1}".format(*[1, 2])
- print "{a} {b}".format(**{'a': 1, 'b': 2})
diff --git a/test/messages/func_string_format_py27.txt b/test/messages/func_string_format_py27.txt index 53edb8b..56f8c41 100644 --- a/test/messages/func_string_format_py27.txt +++ b/test/messages/func_string_format_py27.txt @@ -1,24 +1,26 @@ -E: 34:pprint: Too many arguments for format string
-E: 42:pprint: Not enough arguments for format string
-E: 43:pprint: Too many arguments for format string
-E: 45:pprint: Not enough arguments for format string
-E: 69:pprint: Too many arguments for format string
-W: 35:pprint: Invalid Python 3 format string
-W: 36:pprint: Invalid Python 3 format string
-W: 37:pprint: Format string contains both automatic field numbering and manual field specification
-W: 39:pprint: Missing keyword argument 'a' for format string
-W: 40:pprint: Missing keyword argument 'b' for format string
-W: 40:pprint: Unused format argument 'c'
-W: 41:pprint: Missing keyword argument 'a' for format string
-W: 44:pprint: Missing keyword argument 'a' for format string
-W: 44:pprint: Missing keyword argument 'b' for format string
-W: 44:pprint: Missing keyword argument 'c' for format string
-W: 46:pprint: Missing keyword argument 'a' for format string
-W: 46:pprint: Missing keyword argument 'b' for format string
-W: 53:pprint: Missing format attribute 'length' in format specifier 'a.ids.__len__.length'
-W: 61:pprint: Using invalid lookup key 400 in format specifier 'a.ids[3][400]'
-W: 62:pprint: Using invalid lookup key "'string'" in format specifier 'a.ids[3]["\'string\'"]'
-W: 66:pprint: Missing keyword argument 'b' for format string
-W: 66:pprint: Unused format argument 'a'
-W: 67:pprint: Using invalid lookup key 0 in format specifier 'a[0]'
-W: 71:pprint: Missing format attribute 'missing' in format specifier '0.missing'
\ No newline at end of file +E: 58:pprint_bad: Too many arguments for format string
+E: 64:pprint_bad: Not enough arguments for format string
+E: 65:pprint_bad: Too many arguments for format string
+E: 67:pprint_bad: Not enough arguments for format string
+E: 77:pprint_bad: Too many arguments for format string
+W: 59:pprint_bad: Invalid format string
+W: 60:pprint_bad: Invalid format string
+W: 61:pprint_bad: Format string contains both automatic field numbering and manual field specification
+W: 62:pprint_bad: Missing keyword argument 'b' for format string
+W: 62:pprint_bad: Unused format argument 'c'
+W: 63:pprint_bad: Missing keyword argument 'a' for format string
+W: 66:pprint_bad: Missing keyword argument 'a' for format string
+W: 66:pprint_bad: Missing keyword argument 'b' for format string
+W: 66:pprint_bad: Missing keyword argument 'c' for format string
+W: 68:pprint_bad: Missing keyword argument 'a' for format string
+W: 68:pprint_bad: Missing keyword argument 'b' for format string
+W: 69:pprint_bad: Missing keyword argument 'a' for format string
+W: 70:pprint_bad: Missing format attribute 'length' in format specifier 'a.ids.__len__.length'
+W: 71:pprint_bad: Using invalid lookup key 400 in format specifier 'a.ids[3][400]'
+W: 72:pprint_bad: Using invalid lookup key "'string'" in format specifier 'a.ids[3]["\'string\'"]'
+W: 73:pprint_bad: Using invalid lookup key 1 in format specifier '0[0][1]'
+W: 74:pprint_bad: Using invalid lookup key 0 in format specifier '0[0][0]'
+W: 75:pprint_bad: Missing keyword argument 'b' for format string
+W: 75:pprint_bad: Unused format argument 'a'
+W: 76:pprint_bad: Using invalid lookup key 0 in format specifier 'a[0]'
+W: 78:pprint_bad: Missing format attribute 'missing' in format specifier '0.missing'
\ No newline at end of file |