[pypy-svn] pypy default: Add the internal method str._formatter_field_name_split().

arigo commits-noreply at bitbucket.org
Mon Feb 7 17:49:21 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r41674:85c84e92a83e
Date: 2011-02-07 17:48 +0100
http://bitbucket.org/pypy/pypy/changeset/85c84e92a83e/

Log:	Add the internal method str._formatter_field_name_split().

diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py
--- a/pypy/objspace/std/unicodetype.py
+++ b/pypy/objspace/std/unicodetype.py
@@ -152,13 +152,19 @@
                              ' field\nof the specified width. The string x is'
                              ' never truncated.')
 
-unicode_formatter_parser = SMM('_formatter_parser', 1)
+unicode_formatter_parser           = SMM('_formatter_parser', 1)
+unicode_formatter_field_name_split = SMM('_formatter_field_name_split', 1)
 
 def unicode_formatter_parser__ANY(space, w_unicode):
     from pypy.objspace.std.newformat import unicode_template_formatter
     tformat = unicode_template_formatter(space, space.unicode_w(w_unicode))
     return tformat.formatter_parser()
 
+def unicode_formatter_field_name_split__ANY(space, w_unicode):
+    from pypy.objspace.std.newformat import unicode_template_formatter
+    tformat = unicode_template_formatter(space, space.unicode_w(w_unicode))
+    return tformat.formatter_field_name_split()
+
 # stuff imported from stringtype for interoperability
 
 from pypy.objspace.std.stringtype import str_endswith as unicode_endswith

diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -192,9 +192,12 @@
             except IndexError:
                 w_msg = space.wrap("index out of range")
                 raise OperationError(space.w_IndexError, w_msg)
+        return self._resolve_lookups(w_arg, name, i, end)
+
+    def _resolve_lookups(self, w_obj, name, start, end):
         # Resolve attribute and item lookups.
-        w_obj = w_arg
-        is_attribute = False
+        space = self.space
+        i = start
         while i < end:
             c = name[i]
             if c == ".":
@@ -208,7 +211,12 @@
                 if start == i:
                     w_msg = space.wrap("Empty attribute in format string")
                     raise OperationError(space.w_ValueError, w_msg)
-                w_obj = space.getattr(w_obj, space.wrap(name[start:i]))
+                w_attr = space.wrap(name[start:i])
+                if w_obj is not None:
+                    w_obj = space.getattr(w_obj, w_attr)
+                else:
+                    self.parser_list_w.append(space.newtuple([
+                        space.w_True, w_attr]))
             elif c == "[":
                 got_bracket = False
                 i += 1
@@ -228,12 +236,32 @@
                 else:
                     w_item = space.wrap(name[start:i])
                 i += 1 # Skip "]"
-                w_obj = space.getitem(w_obj, w_item)
+                if w_obj is not None:
+                    w_obj = space.getitem(w_obj, w_item)
+                else:
+                    self.parser_list_w.append(space.newtuple([
+                        space.w_False, w_item]))
             else:
                 msg = "Only '[' and '.' may follow ']'"
                 raise OperationError(space.w_ValueError, space.wrap(msg))
         return w_obj
 
+    def formatter_field_name_split(self):
+        name = self.template
+        i = 0
+        end = len(name)
+        while i < end:
+            c = name[i]
+            if c == "[" or c == ".":
+                break
+            i += 1
+        self.parser_list_w = []
+        self._resolve_lookups(None, name, i, end)
+        #
+        space = self.space
+        return space.newtuple([space.wrap(name[:i]),
+                               space.iter(space.newlist(self.parser_list_w))])
+
     def _convert(self, w_obj, conversion):
         space = self.space
         conv = conversion[0]

diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py
--- a/pypy/objspace/std/stringtype.py
+++ b/pypy/objspace/std/stringtype.py
@@ -273,13 +273,19 @@
                          ' with\ncodecs.register_error that is able to handle'
                          ' UnicodeEncodeErrors.')
 
-str_formatter_parser = SMM('_formatter_parser', 1)
+str_formatter_parser           = SMM('_formatter_parser', 1)
+str_formatter_field_name_split = SMM('_formatter_field_name_split', 1)
 
 def str_formatter_parser__ANY(space, w_str):
     from pypy.objspace.std.newformat import str_template_formatter
     tformat = str_template_formatter(space, space.str_w(w_str))
     return tformat.formatter_parser()
 
+def str_formatter_field_name_split__ANY(space, w_str):
+    from pypy.objspace.std.newformat import str_template_formatter
+    tformat = str_template_formatter(space, space.str_w(w_str))
+    return tformat.formatter_field_name_split()
+
 register_all(vars(), globals())
 
 # ____________________________________________________________

diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -359,3 +359,33 @@
         assert l == [(u'', u'0', u'12{sdd}3', u'x')]
         for x in l[0]:
             assert isinstance(x, unicode)
+
+    def test_formatter_field_name_split(self):
+        first, rest = 'foo'._formatter_field_name_split()
+        assert first == 'foo'
+        assert list(rest) == []
+        #
+        first, rest = 'foo.bar'._formatter_field_name_split()
+        assert first == 'foo'
+        assert list(rest) == [(True, 'bar')]
+        #
+        first, rest = 'foo[123]'._formatter_field_name_split()
+        assert first == 'foo'
+        assert list(rest) == [(False, 123)]
+        #
+        first, rest = 'foo.baz[123].bok'._formatter_field_name_split()
+        assert first == 'foo'
+        assert list(rest) == [(True, 'baz'), (False, 123), (True, 'bok')]
+        #
+        first, rest = 'foo.baz[hi].bok'._formatter_field_name_split()
+        assert first == 'foo'
+        assert list(rest) == [(True, 'baz'), (False, 'hi'), (True, 'bok')]
+
+    def test_u_formatter_field_name_split(self):
+        first, rest = u'foo.baz[hi].bok'._formatter_field_name_split()
+        l = list(rest)
+        assert first == u'foo'
+        assert l == [(True, u'baz'), (False, u'hi'), (True, u'bok')]
+        assert isinstance(first, unicode)
+        for x, y in l:
+            assert isinstance(y, unicode)


More information about the Pypy-commit mailing list