summaryrefslogtreecommitdiff
path: root/checkers/strings.py
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2014-07-29 02:41:50 +0300
committercpopa <devnull@localhost>2014-07-29 02:41:50 +0300
commitbe5921dd65f379f2dbdbd0f32d546bde9d517403 (patch)
treeaa99472002b527de43ee2befab8755eed7f444fa /checkers/strings.py
parentd4b715c69ae9ac2da43f555e3d92b7339a96e368 (diff)
downloadpylint-be5921dd65f379f2dbdbd0f32d546bde9d517403.tar.gz
Fix a false positive with string formatting checker, when encountering a string which uses only position-based arguments. Closes issue #285.
Diffstat (limited to 'checkers/strings.py')
-rw-r--r--checkers/strings.py23
1 files changed, 13 insertions, 10 deletions
diff --git a/checkers/strings.py b/checkers/strings.py
index 8251a80..a07482a 100644
--- a/checkers/strings.py
+++ b/checkers/strings.py
@@ -136,12 +136,14 @@ else:
def parse_format_method_string(format_string):
"""
Parses a PEP 3101 format string, returning a tuple of
- (keys, num_args),
- where keys is the set of mapping keys in the format string and num_args
- is the number of arguments required by the format string.
+ (keys, num_args, manual_pos_arg),
+ where keys is the set of mapping keys in the format string, num_args
+ is the number of arguments required by the format string and
+ manual_pos_arg is the number of arguments passed with the position.
"""
keys = []
num_args = 0
+ manual_pos_arg = 0
formatter = string.Formatter()
parseiterator = formatter.parse(format_string)
try:
@@ -150,7 +152,9 @@ def parse_format_method_string(format_string):
# not a replacement format
continue
name = result[1]
- if name:
+ if name and str(name).isdigit():
+ manual_pos_arg += 1
+ elif name:
keyname, fielditerator = split_format_field_names(name)
if not isinstance(keyname, str):
# In Python 2 it will return long which will lead
@@ -163,7 +167,7 @@ def parse_format_method_string(format_string):
# probably the format string is invalid
# should we check the argument of the ValueError?
raise utils.IncompleteFormatString(format_string)
- return keys, num_args
+ return keys, num_args, manual_pos_arg
def get_args(callfunc):
""" Get the arguments from the given `CallFunc` node.
@@ -327,7 +331,7 @@ class StringMethodsChecker(BaseChecker):
except astroid.InferenceError:
return
try:
- fields, num_args = parse_format_method_string(strnode.value)
+ fields, num_args, manual_pos = parse_format_method_string(strnode.value)
except utils.IncompleteFormatString:
self.add_message('bad-format-string', node=node)
return
@@ -336,7 +340,7 @@ class StringMethodsChecker(BaseChecker):
if isinstance(field[0], int))
named_fields = set(field[0] for field in fields
if isinstance(field[0], str))
- if manual_fields and num_args:
+ if num_args and manual_pos:
self.add_message('format-combined-specification',
node=node)
return
@@ -353,6 +357,8 @@ class StringMethodsChecker(BaseChecker):
node=node,
args=(field, ))
else:
+ # num_args can be 0 if manual_pos is not.
+ num_args = num_args or manual_pos
if positional > num_args:
# We can have two possibilities:
# * "{0} {1}".format(a, b)
@@ -363,9 +369,6 @@ class StringMethodsChecker(BaseChecker):
elif positional < num_args:
self.add_message('too-few-format-args', node=node)
- if manual_fields and positional < len(manual_fields):
- self.add_message('too-few-format-args', node=node)
-
self._check_new_format_specifiers(node, fields, named)
def _check_new_format_specifiers(self, node, fields, named):