summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--checkers/strings.py39
-rw-r--r--test/input/func_string_format_py27.py51
-rw-r--r--test/messages/func_string_format_py27.txt50
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