Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Unified Diff: third_party/pylint/checkers/string_format.py

Issue 719313003: Revert "pylint: upgrade to 1.3.1" (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/pylint/checkers/stdlib.py ('k') | third_party/pylint/checkers/strings.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/pylint/checkers/string_format.py
diff --git a/third_party/pylint/checkers/string_format.py b/third_party/pylint/checkers/string_format.py
new file mode 100644
index 0000000000000000000000000000000000000000..c420a604b74fcf8d7755cc23be8e24f840cad79d
--- /dev/null
+++ b/third_party/pylint/checkers/string_format.py
@@ -0,0 +1,157 @@
+# Copyright (c) 2009-2010 Arista Networks, Inc. - James Lingard
+# Copyright (c) 2004-2010 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+"""Checker for string formatting operations.
+"""
+
+import string
+from logilab import astng
+from pylint.interfaces import IASTNGChecker
+from pylint.checkers import BaseChecker
+from pylint.checkers import utils
+
+
+MSGS = {
+ 'E1300': ("Unsupported format character %r (%#02x) at index %d",
+ "Used when a unsupported format character is used in a format\
+ string."),
+ 'E1301': ("Format string ends in middle of conversion specifier",
+ "Used when a format string terminates before the end of a \
+ conversion specifier."),
+ 'E1302': ("Mixing named and unnamed conversion specifiers in format string",
+ "Used when a format string contains both named (e.g. '%(foo)d') \
+ and unnamed (e.g. '%d') conversion specifiers. This is also \
+ used when a named conversion specifier contains * for the \
+ minimum field width and/or precision."),
+ 'E1303': ("Expected mapping for format string, not %s",
+ "Used when a format string that uses named conversion specifiers \
+ is used with an argument that is not a mapping."),
+ 'W1300': ("Format string dictionary key should be a string, not %s",
+ "Used when a format string that uses named conversion specifiers \
+ is used with a dictionary whose keys are not all strings."),
+ 'W1301': ("Unused key %r in format string dictionary",
+ "Used when a format string that uses named conversion specifiers \
+ is used with a dictionary that conWtains keys not required by the \
+ format string."),
+ 'E1304': ("Missing key %r in format string dictionary",
+ "Used when a format string that uses named conversion specifiers \
+ is used with a dictionary that doesn't contain all the keys \
+ required by the format string."),
+ 'E1305': ("Too many arguments for format string",
+ "Used when a format string that uses unnamed conversion \
+ specifiers is given too few arguments."),
+ 'E1306': ("Not enough arguments for format string",
+ "Used when a format string that uses unnamed conversion \
+ specifiers is given too many arguments"),
+ }
+
+OTHER_NODES = (astng.Const, astng.List, astng.Backquote,
+ astng.Lambda, astng.Function,
+ astng.ListComp, astng.SetComp, astng.GenExpr)
+
+class StringFormatChecker(BaseChecker):
+ """Checks string formatting operations to ensure that the format string
+ is valid and the arguments match the format string.
+ """
+
+ __implements__ = (IASTNGChecker,)
+ name = 'string_format'
+ msgs = MSGS
+
+ def visit_binop(self, node):
+ if node.op != '%':
+ return
+ left = node.left
+ args = node.right
+
+ if not (isinstance(left, astng.Const)
+ and isinstance(left.value, basestring)):
+ return
+ format_string = left.value
+ try:
+ required_keys, required_num_args = \
+ utils.parse_format_string(format_string)
+ except utils.UnsupportedFormatCharacter, e:
+ c = format_string[e.index]
+ self.add_message('E1300', node=node, args=(c, ord(c), e.index))
+ return
+ except utils.IncompleteFormatString:
+ self.add_message('E1301', node=node)
+ return
+ if required_keys and required_num_args:
+ # The format string uses both named and unnamed format
+ # specifiers.
+ self.add_message('E1302', node=node)
+ elif required_keys:
+ # The format string uses only named format specifiers.
+ # Check that the RHS of the % operator is a mapping object
+ # that contains precisely the set of keys required by the
+ # format string.
+ if isinstance(args, astng.Dict):
+ keys = set()
+ unknown_keys = False
+ for k, v in args.items:
+ if isinstance(k, astng.Const):
+ key = k.value
+ if isinstance(key, basestring):
+ keys.add(key)
+ else:
+ self.add_message('W1300', node=node, args=key)
+ else:
+ # One of the keys was something other than a
+ # constant. Since we can't tell what it is,
+ # supress checks for missing keys in the
+ # dictionary.
+ unknown_keys = True
+ if not unknown_keys:
+ for key in required_keys:
+ if key not in keys:
+ self.add_message('E1304', node=node, args=key)
+ for key in keys:
+ if key not in required_keys:
+ self.add_message('W1301', node=node, args=key)
+ elif isinstance(args, OTHER_NODES + (astng.Tuple,)):
+ type_name = type(args).__name__
+ self.add_message('E1303', node=node, args=type_name)
+ # else:
+ # The RHS of the format specifier is a name or
+ # expression. It may be a mapping object, so
+ # there's nothing we can check.
+ else:
+ # The format string uses only unnamed format specifiers.
+ # Check that the number of arguments passed to the RHS of
+ # the % operator matches the number required by the format
+ # string.
+ if isinstance(args, astng.Tuple):
+ num_args = len(args.elts)
+ elif isinstance(args, OTHER_NODES + (astng.Dict, astng.DictComp)):
+ num_args = 1
+ else:
+ # The RHS of the format specifier is a name or
+ # expression. It could be a tuple of unknown size, so
+ # there's nothing we can check.
+ num_args = None
+ if num_args is not None:
+ if num_args > required_num_args:
+ self.add_message('E1305', node=node)
+ elif num_args < required_num_args:
+ self.add_message('E1306', node=node)
+
+
+def register(linter):
+ """required method to auto register this checker """
+ linter.register_checker(StringFormatChecker(linter))
« no previous file with comments | « third_party/pylint/checkers/stdlib.py ('k') | third_party/pylint/checkers/strings.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698