[pypy-svn] r61255 - in pypy/trunk/pypy: module/__builtin__ objspace/std objspace/std/test

arigo at codespeak.net arigo at codespeak.net
Thu Jan 22 18:09:15 CET 2009


Author: arigo
Date: Thu Jan 22 18:09:15 2009
New Revision: 61255

Modified:
   pypy/trunk/pypy/module/__builtin__/interp_classobj.py
   pypy/trunk/pypy/objspace/std/formatting.py
   pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py
   pypy/trunk/pypy/objspace/std/unicodetype.py
Log:
(antocuni, arigo)  Fix various minor issues with unicodes,
in particular the case of __str__ returning a unicode.


Modified: pypy/trunk/pypy/module/__builtin__/interp_classobj.py
==============================================================================
--- pypy/trunk/pypy/module/__builtin__/interp_classobj.py	(original)
+++ pypy/trunk/pypy/module/__builtin__/interp_classobj.py	Thu Jan 22 18:09:15 2009
@@ -423,7 +423,7 @@
     def descr_unicode(self, space):
         w_meth = self.getattr(space, space.wrap('__unicode__'), False)
         if w_meth is None:
-            return self.descr_repr(space)
+            return self.descr_str(space)
         return space.call_function(w_meth)
 
     def descr_len(self, space):

Modified: pypy/trunk/pypy/objspace/std/formatting.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/formatting.py	(original)
+++ pypy/trunk/pypy/objspace/std/formatting.py	Thu Jan 22 18:09:15 2009
@@ -385,6 +385,19 @@
             if padnumber == '<':           # spaces on the right
                 result.append_multiple_char(const(' '), padding)
 
+        def string_formatting(self, w_value):
+            space = self.space
+            w_impl = space.lookup(w_value, '__str__')
+            if w_impl is None:
+                raise OperationError(space.w_TypeError,
+                                     space.wrap("operand does not support "
+                                                "unary str"))
+            w_result = space.get_and_call_function(w_impl, w_value)
+            if space.is_true(space.isinstance(w_result,
+                                              space.w_unicode)):
+                raise NeedUnicodeFormattingError
+            return space.str_w(w_result)
+
         def fmt_s(self, w_value):
             space = self.space
             got_unicode = space.is_true(space.isinstance(w_value,
@@ -392,7 +405,7 @@
             if not do_unicode:
                 if got_unicode:
                     raise NeedUnicodeFormattingError
-                s = space.str_w(space.str(w_value))
+                s = self.string_formatting(w_value)
             else:
                 if not got_unicode:
                     w_value = space.call_function(space.w_unicode, w_value)

Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py	(original)
+++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py	Thu Jan 22 18:09:15 2009
@@ -677,17 +677,39 @@
         u = unicode(buf, 'utf-8', 'strict')
         assert u == u'character buffers are decoded to unicode'
 
-    def test_formatting_unicode__str__(self):
-        skip('fixme!')
+    def test_unicode_conversion_with__str__(self):
+        # new-style classes
+        class A(object):
+            def __str__(self):
+                return u'\u1234'
+        s = unicode(A())
+        assert type(s) is unicode
+        assert s == u'\u1234'
+        # with old-style classes, it's different, but it should work as well
         class A:
             def __str__(self):
                 return u'\u1234'
+        s = unicode(A())
+        assert type(s) is unicode
+        assert s == u'\u1234'
 
-        s = '%s' % A()
+    def test_formatting_unicode__str__(self):
+        class A:
+            def __init__(self, num):
+                self.num = num
+            def __str__(self):
+                return unichr(self.num)
+
+        s = '%s' % A(111)    # this is ASCII
+        assert type(s) is unicode
+        assert s == chr(111)
+
+        s = '%s' % A(0x1234)    # this is not ASCII
         assert type(s) is unicode
         assert s == u'\u1234'
 
     def test_formatting_unicode__str__2(self):
+        skip("this is completely insane")
         class A:
             def __str__(self):
                 return u'baz'
@@ -701,6 +723,9 @@
     
         a = A()
         b = B()
+        s = '%s %s' % (a, b)
+        assert s == u'baz bar'
+
         s = '%s %s' % (b, a)
         assert s == u'foo baz'
 

Modified: pypy/trunk/pypy/objspace/std/unicodetype.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/unicodetype.py	(original)
+++ pypy/trunk/pypy/objspace/std/unicodetype.py	Thu Jan 22 18:09:15 2009
@@ -216,6 +216,10 @@
         w_res = w_obj
     else:
         w_unicode_method = space.lookup(w_obj, "__unicode__")
+        # obscure workaround: for the next two lines see
+        # test_unicode_conversion_with__str__
+        if w_unicode_method is None:
+            w_unicode_method = space.lookup(w_obj, "__str__")
         if w_unicode_method is not None:
             w_res = space.get_and_call_function(w_unicode_method, w_obj)
         else:



More information about the Pypy-commit mailing list