Author: Christian Hudon <[email protected]>
Branch: stdlib-2.7.4
Changeset: r66138:028723fd3b86
Date: 2013-08-12 15:20 -0400
http://bitbucket.org/pypy/pypy/changeset/028723fd3b86/

Log:    In string formatting, if conversion to a number with __int__()
        fails, we should retry with __long__(). Makes a new testcase
        introduced in Python 2.7.4 pass.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -231,6 +231,18 @@
         msg = "__int__ returned non-int (type '%T')"
         raise operationerrfmt(space.w_TypeError, msg, w_result)
 
+    def long(self, space):
+        w_impl = space.lookup(self, '__long__')
+        if w_impl is None:
+            raise operationerrfmt(space.w_TypeError,
+                  "unsupported operand type for long(): '%T'", self)
+        w_result = space.get_and_call_function(w_impl, self)
+
+        if space.isinstance_w(w_result, space.w_long):
+            return w_result
+        msg = "__long__ returned non-long (type '%T')"
+        raise operationerrfmt(space.w_TypeError, msg, w_result)
+
     def __spacebind__(self, space):
         return self
 
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
@@ -543,7 +543,10 @@
 
 def format_num_helper_generator(fmt, digits):
     def format_num_helper(space, w_value):
-        w_value = maybe_int(space, w_value)
+        try:
+            w_value = maybe_int(space, w_value)
+        except OperationError:
+            w_value = space.long(w_value)
         try:
             value = space.int_w(w_value)
             return fmt % (value,)
diff --git a/pypy/objspace/std/test/test_stringformat.py 
b/pypy/objspace/std/test/test_stringformat.py
--- a/pypy/objspace/std/test/test_stringformat.py
+++ b/pypy/objspace/std/test/test_stringformat.py
@@ -186,6 +186,16 @@
     def test_broken_unicode(self):
         raises(UnicodeDecodeError, 'N&#225;zov: %s'.__mod__, u'Jerry')
 
+    def test_format_retry_with_long_if_int_fails(self):
+        class IntFails(object):
+            def __int__(self):
+                raise Exception
+            def __long__(self):
+                return 0L
+
+        assert "%x" % IntFails() == '0'
+
+
 class AppTestWidthPrec:
     def test_width(self):
         a = 'a'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to