[Python-3000-checkins] r57976 - in python/branches/py3k: Lib/string.py Lib/test/test_unicode.py Objects/stringlib/string_format.h

eric.smith python-3000-checkins at python.org
Wed Sep 5 01:04:22 CEST 2007


Author: eric.smith
Date: Wed Sep  5 01:04:22 2007
New Revision: 57976

Modified:
   python/branches/py3k/Lib/string.py
   python/branches/py3k/Lib/test/test_unicode.py
   python/branches/py3k/Objects/stringlib/string_format.h
Log:
Changed some ValueError's to KeyError and IndexError.
Corrected code for invalid conversion specifier.
Added tests to verify.

Modified string.Formatter to correctly expand format_spec's,
and added a limit to recursion depth.  Added _vformat()
method to support both of these.


Modified: python/branches/py3k/Lib/string.py
==============================================================================
--- python/branches/py3k/Lib/string.py	(original)
+++ python/branches/py3k/Lib/string.py	Wed Sep  5 01:04:22 2007
@@ -202,6 +202,13 @@
 
     def vformat(self, format_string, args, kwargs):
         used_args = set()
+        result = self._vformat(format_string, args, kwargs, used_args, 2)
+        self.check_unused_args(used_args, args, kwargs)
+        return result
+
+    def _vformat(self, format_string, args, kwargs, used_args, recursion_depth):
+        if recursion_depth < 0:
+            raise ValueError('Max string recursion exceeded')
         result = []
         for literal_text, field_name, format_spec, conversion in \
                 self.parse(format_string):
@@ -223,10 +230,13 @@
                 # do any conversion on the resulting object
                 obj = self.convert_field(obj, conversion)
 
+                # expand the format spec, if needed
+                format_spec = self._vformat(format_spec, args, kwargs,
+                                            used_args, recursion_depth-1)
+
                 # format the object and append to the result
                 result.append(self.format_field(obj, format_spec))
 
-        self.check_unused_args(used_args, args, kwargs)
         return ''.join(result)
 
 
@@ -251,9 +261,9 @@
             return repr(value)
         elif conversion == 's':
             return str(value)
-        else:
-            assert conversion is None
+        elif conversion is None:
             return value
+        raise ValueError("Unknown converion specifier {0!s}".format(conversion))
 
 
     # returns an iterable that contains tuples of the form:

Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py	(original)
+++ python/branches/py3k/Lib/test/test_unicode.py	Wed Sep  5 01:04:22 2007
@@ -542,29 +542,30 @@
         self.assertRaises(ValueError, 'a}'.format)
         self.assertRaises(ValueError, '{a'.format)
         self.assertRaises(ValueError, '}a'.format)
-        self.assertRaises(ValueError, '{0}'.format)
-        self.assertRaises(ValueError, '{1}'.format, 'abc')
-        self.assertRaises(ValueError, '{x}'.format)
+        self.assertRaises(IndexError, '{0}'.format)
+        self.assertRaises(IndexError, '{1}'.format, 'abc')
+        self.assertRaises(KeyError,   '{x}'.format)
         self.assertRaises(ValueError, "}{".format)
         self.assertRaises(ValueError, "{".format)
         self.assertRaises(ValueError, "}".format)
         self.assertRaises(ValueError, "abc{0:{}".format)
         self.assertRaises(ValueError, "{0".format)
-        self.assertRaises(ValueError, "{0.}".format)
-        self.assertRaises(ValueError, "{0[}".format)
+        self.assertRaises(IndexError, "{0.}".format)
+        self.assertRaises(ValueError, "{0.}".format, 0)
+        self.assertRaises(IndexError, "{0[}".format)
         self.assertRaises(ValueError, "{0[}".format, [])
-        self.assertRaises(ValueError, "{0]}".format)
-        self.assertRaises(ValueError, "{0.[]}".format)
+        self.assertRaises(KeyError,   "{0]}".format)
+        self.assertRaises(ValueError, "{0.[]}".format, 0)
         self.assertRaises(ValueError, "{0..foo}".format, 0)
-        self.assertRaises(ValueError, "{0[0}".format)
-        self.assertRaises(ValueError, "{0[0:foo}".format)
-        self.assertRaises(ValueError, "{c]}".format)
-        self.assertRaises(ValueError, "{{ {{{0}}".format)
-        self.assertRaises(ValueError, "{0}}".format)
-        self.assertRaises(ValueError, "{foo}".format, bar=3)
+        self.assertRaises(ValueError, "{0[0}".format, 0)
+        self.assertRaises(ValueError, "{0[0:foo}".format, 0)
+        self.assertRaises(KeyError,   "{c]}".format)
+        self.assertRaises(ValueError, "{{ {{{0}}".format, 0)
+        self.assertRaises(ValueError, "{0}}".format, 0)
+        self.assertRaises(KeyError,   "{foo}".format, bar=3)
         self.assertRaises(ValueError, "{0!x}".format, 3)
-        self.assertRaises(ValueError, "{0!}".format)
-        self.assertRaises(ValueError, "{0!rs}".format)
+        self.assertRaises(ValueError, "{0!}".format, 0)
+        self.assertRaises(ValueError, "{0!rs}".format, 0)
         self.assertRaises(ValueError, "{!}".format)
         self.assertRaises(ValueError, "{:}".format)
         self.assertRaises(ValueError, "{:s}".format)

Modified: python/branches/py3k/Objects/stringlib/string_format.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/string_format.h	(original)
+++ python/branches/py3k/Objects/stringlib/string_format.h	Wed Sep  5 01:04:22 2007
@@ -414,8 +414,7 @@
         if (key == NULL)
             goto error;
         if ((kwargs == NULL) || (obj = PyDict_GetItem(kwargs, key)) == NULL) {
-            PyErr_SetString(PyExc_ValueError, "Keyword argument not found "
-                            "in format string");
+            PyErr_SetObject(PyExc_KeyError, key);
             Py_DECREF(key);
             goto error;
         }
@@ -425,12 +424,8 @@
     else {
         /* look up in args */
         obj = PySequence_GetItem(args, index);
-        if (obj == NULL) {
-            /* translate IndexError to a ValueError */
-            PyErr_SetString(PyExc_ValueError, "Not enough positional arguments "
-                            "in format string");
+        if (obj == NULL)
             goto error;
-        }
     }
 
     /* iterate over the rest of the field_name */


More information about the Python-3000-checkins mailing list