[pypy-commit] pypy default: Tests and fix:

arigo noreply at buildbot.pypy.org
Tue Sep 6 19:35:01 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r47119:09816858a87a
Date: 2011-09-06 19:33 +0200
http://bitbucket.org/pypy/pypy/changeset/09816858a87a/

Log:	Tests and fix:

	object.__str__() was implemented by calling space.repr(), instead of
	directly calling the __repr__() method. The difference is that the
	first does type checking on the result, while the latter does not.
	It's not the job of object.__str__() to do type checking, but of its
	callers.

diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py
--- a/pypy/objspace/std/objecttype.py
+++ b/pypy/objspace/std/objecttype.py
@@ -24,7 +24,12 @@
     return w_obj.getrepr(space, '%s object' % (classname,))
 
 def descr__str__(space, w_obj):
-    return space.repr(w_obj)
+    w_type = space.type(w_obj)
+    w_impl = w_type.lookup("__repr__")
+    if w_impl is None:
+        raise OperationError(space.w_TypeError,      # can it really occur?
+                             space.wrap("operand does not support unary str"))
+    return space.get_and_call_function(w_impl, w_obj)
 
 def descr__class__(space, w_obj):
     return space.type(w_obj)
diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -94,3 +94,10 @@
         #assert len(log) == 1
         #assert log[0].message.args == ("object.__init__() takes no parameters",)
         #assert type(log[0].message) is DeprecationWarning
+
+    def test_object_str(self):
+        # obscure case
+        class A(object):
+            def __repr__(self):
+                return 123456
+        assert A().__str__() == 123456
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
@@ -780,8 +780,22 @@
         assert type(s) is unicode
         assert s == u'\u1234'
 
+        # now the same with a new-style class...
+        class A(object):
+            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'
@@ -798,9 +812,22 @@
         s = '%s %s' % (a, b)
         assert s == u'baz bar'
 
+        skip("but this case here is completely insane")
         s = '%s %s' % (b, a)
         assert s == u'foo baz'
 
+    def test_formatting_unicode__str__3(self):
+        # "bah" is all I can say
+        class X(object):
+            def __repr__(self):
+                return u'\u1234'
+        '%s' % X()
+        #
+        class X(object):
+            def __str__(self):
+                return u'\u1234'
+        '%s' % X()
+
     def test_str_subclass(self):
         class Foo9(str):
             def __unicode__(self):


More information about the pypy-commit mailing list