[pypy-svn] pypy default: Subclasses of unicode should call their eventual __unicode__ method when

amauryfa commits-noreply at bitbucket.org
Mon Feb 14 16:55:22 CET 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r41909:f63f339a7811
Date: 2011-02-14 16:54 +0100
http://bitbucket.org/pypy/pypy/changeset/f63f339a7811/

Log:	Subclasses of unicode should call their eventual __unicode__ method
	when they are rendered with %s or "{}".format

diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -7,6 +7,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib.rstring import StringBuilder, UnicodeBuilder
+from pypy.objspace.std.unicodetype import unicode_from_object
 
 class BaseStringFormatter(object):
     def __init__(self, space, values_w, w_valuedict):
@@ -430,6 +431,8 @@
             else:
                 if not got_unicode:
                     w_value = space.call_function(space.w_unicode, w_value)
+                else:
+                    w_value = unicode_from_object(space, w_value)
                 s = space.unicode_w(w_value)
             self.std_wp(s)
 

diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -812,6 +812,14 @@
 
         assert unicode(A()) == u'bar'
 
+    def test_format_unicode_subclass(self):
+        class U(unicode):
+            def __unicode__(self):
+                return u'__unicode__ overridden'
+        u = U(u'xxx')
+        assert repr("%s" % u) == "u'__unicode__ overridden'"
+        assert repr("{}".format(u)) == "'__unicode__ overridden'"
+
     def test_replace_with_buffer(self):
         assert u'abc'.replace(buffer('b'), buffer('e')) == u'aec'
         assert u'abc'.replace(buffer('b'), u'e') == u'aec'

diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -927,6 +927,8 @@
 def format__Unicode_ANY(space, w_unicode, w_format_spec):
     if not space.isinstance_w(w_format_spec, space.w_unicode):
         w_format_spec = space.call_function(space.w_unicode, w_format_spec)
+    from pypy.objspace.std.unicodetype import unicode_from_object
+    w_unicode = unicode_from_object(space, w_unicode)
     spec = space.unicode_w(w_format_spec)
     formatter = newformat.unicode_formatter(space, spec)
     return formatter.format_string(w_unicode._value)

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
@@ -293,7 +293,9 @@
     return w_retval
 
 def unicode_from_object(space, w_obj):
-    if space.is_w(space.type(w_obj), space.w_str):
+    if space.is_w(space.type(w_obj), space.w_unicode):
+        return w_obj
+    elif space.is_w(space.type(w_obj), space.w_str):
         w_res = w_obj
     else:
         w_unicode_method = space.lookup(w_obj, "__unicode__")


More information about the Pypy-commit mailing list