]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Simplified tuple returned by string._formatter_parser to only have
authorEric Smith <eric@trueblade.com>
Tue, 28 Aug 2007 11:15:20 +0000 (11:15 +0000)
committerEric Smith <eric@trueblade.com>
Tue, 28 Aug 2007 11:15:20 +0000 (11:15 +0000)
4 elements.  No need for old is_markup element, the same information
is indicated by literal_string being None.

Factored string.Formatter class to make subclasses easier to write.

Lib/string.py
Objects/stringlib/string_format.h

index 0663f31a76109da1a8de70354cc1eb50d8b1ea54..cef5029cbe97cec7294922c46a4c1b666ab6a5cd 100644 (file)
@@ -208,49 +208,83 @@ class Formatter:
         return self.vformat(format_string, args, kwargs)
 
     def vformat(self, format_string, args, kwargs):
-        used_args = set()
+        used_args = self.get_empty_used_args()
         result = []
-        for (is_markup, literal, field_name, format_spec, conversion) in \
-                format_string._formatter_parser():
-            if is_markup:
-                # given the field_name, find the object it references
-
-                # split it into the first part, and and iterator that
-                #  looks over the rest
-                first, rest = field_name._formatter_field_name_split()
-
-                used_args.add(first)
-                obj = self.get_value(first, args, kwargs)
+        for literal_text, field_name, format_spec, conversion in \
+                self.parse(format_string):
+            if literal_text is None:
+                # this is some markup, find the object and do
+                #  the formatting
 
-                # loop through the rest of the field_name, doing
-                #  getattr or getitem as needed
-                for is_attr, i in rest:
-                    if is_attr:
-                        obj = getattr(obj, i)
-                    else:
-                        obj = obj[i]
+                # given the field_name, find the object it references
+                obj = self.get_field(field_name, args, kwargs, used_args)
 
                 # do any conversion on the resulting object
-                if conversion == 'r':
-                    obj = repr(obj)
-                elif conversion == 's':
-                    obj = str(obj)
+                obj = self.convert_field(obj, conversion)
 
                 # format the object and append to the result
                 result.append(self.format_field(obj, format_spec))
             else:
-                result.append(literal)
+                # this is literal text, use it directly
+                result.append(literal_text)
         self.check_unused_args(used_args, args, kwargs)
         return ''.join(result)
 
+
+    def get_empty_used_args(self):
+        return set()
+
+
     def get_value(self, key, args, kwargs):
         if isinstance(key, int):
             return args[key]
         else:
             return kwargs[key]
 
+
     def check_unused_args(self, used_args, args, kwargs):
         pass
 
+
     def format_field(self, value, format_spec):
         return format(value, format_spec)
+
+
+    def convert_field(self, value, conversion):
+        # do any conversion on the resulting object
+        if conversion == 'r':
+            return repr(value)
+        elif conversion == 's':
+            return str(value)
+        else:
+            assert conversion is None
+            return value
+
+
+    # returns an iterable that contains tuples of the form:
+    # (literal_text, field_name, format_spec, conversion)
+    def parse(self, format_string):
+        return format_string._formatter_parser()
+
+
+    # given a field_name, find the object it references.
+    #  field_name:   the field being looked up, e.g. "0.name"
+    #                 or "lookup[3]"
+    #  used_args:    a set of which args have been used
+    #  args, kwargs: as passed in to vformat
+    # also, mark it as used in 'used_args'
+    def get_field(self, field_name, args, kwargs, used_args):
+        first, rest = field_name._formatter_field_name_split()
+
+        used_args.add(first)
+        obj = self.get_value(first, args, kwargs)
+
+        # loop through the rest of the field_name, doing
+        #  getattr or getitem as needed
+        for is_attr, i in rest:
+            if is_attr:
+                obj = getattr(obj, i)
+            else:
+                obj = obj[i]
+
+        return obj
index 44c5442e988bf887b25b2ab3fcfdebd5790f56ae..b8ea03f51fbd69a698aadec78f25d6913eb71736 100644 (file)
@@ -979,17 +979,12 @@ formatteriter_next(formatteriterobject *it)
         /* if 0, error has already been set, if 1, iterator is empty */
         return NULL;
     else {
-        PyObject *is_markup_bool = NULL;
         PyObject *literal_str = NULL;
         PyObject *field_name_str = NULL;
         PyObject *format_spec_str = NULL;
         PyObject *conversion_str = NULL;
         PyObject *tuple = NULL;
 
-        is_markup_bool = PyBool_FromLong(is_markup);
-        if (!is_markup_bool)
-            return NULL;
-
         if (is_markup) {
             /* field_name, format_spec, and conversion are returned */
             literal_str = Py_None;
@@ -1030,11 +1025,9 @@ formatteriter_next(formatteriterobject *it)
             Py_INCREF(format_spec_str);
             Py_INCREF(conversion_str);
         }
-        tuple = PyTuple_Pack(5, is_markup_bool, literal_str,
-                             field_name_str, format_spec_str,
+        tuple = PyTuple_Pack(4, literal_str, field_name_str, format_spec_str,
                              conversion_str);
     error:
-        Py_XDECREF(is_markup_bool);
         Py_XDECREF(literal_str);
         Py_XDECREF(field_name_str);
         Py_XDECREF(format_spec_str);