[Python-checkins] cpython (2.7): Issue #23671: string.Template now allows to specify the "self" parameter as

serhiy.storchaka python-checkins at python.org
Tue Mar 24 21:31:55 CET 2015


https://hg.python.org/cpython/rev/1c19778123a3
changeset:   95177:1c19778123a3
branch:      2.7
parent:      95171:0c72cdf3ff22
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Tue Mar 24 22:27:50 2015 +0200
summary:
  Issue #23671: string.Template now allows to specify the "self" parameter as
keyword argument.  string.Formatter now allows to specify the "self" and
the "format_string" parameters as keyword arguments.

files:
  Lib/string.py           |  26 +++++++++++++++++++++++---
  Lib/test/test_pep292.py |   7 +++++++
  Lib/test/test_string.py |  12 ++++++++++++
  Misc/NEWS               |   4 ++++
  4 files changed, 46 insertions(+), 3 deletions(-)


diff --git a/Lib/string.py b/Lib/string.py
--- a/Lib/string.py
+++ b/Lib/string.py
@@ -145,7 +145,11 @@
         raise ValueError('Invalid placeholder in string: line %d, col %d' %
                          (lineno, colno))
 
-    def substitute(self, *args, **kws):
+    def substitute(*args, **kws):
+        if not args:
+            raise TypeError("descriptor 'substitute' of 'Template' object "
+                            "needs an argument")
+        self, args = args[0], args[1:]  # allow the "self" keyword be passed
         if len(args) > 1:
             raise TypeError('Too many positional arguments')
         if not args:
@@ -171,7 +175,11 @@
                              self.pattern)
         return self.pattern.sub(convert, self.template)
 
-    def safe_substitute(self, *args, **kws):
+    def safe_substitute(*args, **kws):
+        if not args:
+            raise TypeError("descriptor 'safe_substitute' of 'Template' object "
+                            "needs an argument")
+        self, args = args[0], args[1:]  # allow the "self" keyword be passed
         if len(args) > 1:
             raise TypeError('Too many positional arguments')
         if not args:
@@ -535,7 +543,19 @@
 # The field name parser is implemented in str._formatter_field_name_split
 
 class Formatter(object):
-    def format(self, format_string, *args, **kwargs):
+    def format(*args, **kwargs):
+        if not args:
+            raise TypeError("descriptor 'format' of 'Formatter' object "
+                            "needs an argument")
+        self, args = args[0], args[1:]  # allow the "self" keyword be passed
+        try:
+            format_string, args = args[0], args[1:] # allow the "format_string" keyword be passed
+        except IndexError:
+            if 'format_string' in kwargs:
+                format_string = kwargs.pop('format_string')
+            else:
+                raise TypeError("format() missing 1 required positional "
+                                "argument: 'format_string'")
         return self.vformat(format_string, args, kwargs)
 
     def vformat(self, format_string, args, kwargs):
diff --git a/Lib/test/test_pep292.py b/Lib/test/test_pep292.py
--- a/Lib/test/test_pep292.py
+++ b/Lib/test/test_pep292.py
@@ -26,6 +26,7 @@
         self.assertEqual(s.substitute(dict(who='tim', what='ham')),
                          'tim likes to eat a bag of ham worth $100')
         self.assertRaises(KeyError, s.substitute, dict(who='tim'))
+        self.assertRaises(TypeError, Template.substitute)
 
     def test_regular_templates_with_braces(self):
         s = Template('$who likes ${what} for ${meal}')
@@ -178,6 +179,9 @@
         eq(s.substitute(dict(mapping='one'), mapping='two'),
            'the mapping is two')
 
+        s = Template('the self is $self')
+        eq(s.substitute(self='bozo'), 'the self is bozo')
+
     def test_keyword_arguments_safe(self):
         eq = self.assertEqual
         raises = self.assertRaises
@@ -196,6 +200,9 @@
         raises(TypeError, s.substitute, d, {})
         raises(TypeError, s.safe_substitute, d, {})
 
+        s = Template('the self is $self')
+        eq(s.safe_substitute(self='bozo'), 'the self is bozo')
+
     def test_delimiter_override(self):
         eq = self.assertEqual
         raises = self.assertRaises
diff --git a/Lib/test/test_string.py b/Lib/test/test_string.py
--- a/Lib/test/test_string.py
+++ b/Lib/test/test_string.py
@@ -196,6 +196,18 @@
         self.assertRaises(ValueError, format, '', '#')
         self.assertRaises(ValueError, format, '', '#20')
 
+    def test_format_keyword_arguments(self):
+        fmt = string.Formatter()
+        self.assertEqual(fmt.format("-{arg}-", arg='test'), '-test-')
+        self.assertRaises(KeyError, fmt.format, "-{arg}-")
+        self.assertEqual(fmt.format("-{self}-", self='test'), '-test-')
+        self.assertRaises(KeyError, fmt.format, "-{self}-")
+        self.assertEqual(fmt.format("-{format_string}-", format_string='test'),
+                         '-test-')
+        self.assertRaises(KeyError, fmt.format, "-{format_string}-")
+        self.assertEqual(fmt.format(arg='test', format_string="-{arg}-"),
+                         '-test-')
+
 class BytesAliasTest(unittest.TestCase):
 
     def test_builtin(self):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,10 @@
 Library
 -------
 
+- Issue #23671: string.Template now allows to specify the "self" parameter as
+  keyword argument.  string.Formatter now allows to specify the "self" and
+  the "format_string" parameters as keyword arguments.
+
 - Issue #21560: An attempt to write a data of wrong type no longer cause
   GzipFile corruption.  Original patch by Wolfgang Maier.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list