Commits

Brian Kearns committed a9f6240

also fix longtype: try __long__ before str/unicode

Comments (0)

Files changed (2)

pypy/objspace/std/longtype.py

             return w_value
         elif type(w_value) is W_LongObject:
             return newbigint(space, w_longtype, w_value.num)
+        elif (space.lookup(w_value, '__long__') is not None or
+              space.lookup(w_value, '__int__') is not None):
+            w_obj = space.long(w_value)
+            return newbigint(space, w_longtype, space.bigint_w(w_obj))
+        elif space.lookup(w_value, '__trunc__') is not None:
+            w_obj = space.trunc(w_value)
+            # :-(  blame CPython 2.7
+            if space.lookup(w_obj, '__long__') is not None:
+                w_obj = space.long(w_obj)
+            else:
+                w_obj = space.int(w_obj)
+            return newbigint(space, w_longtype, space.bigint_w(w_obj))
         elif space.isinstance_w(w_value, space.w_str):
             return string_to_w_long(space, w_longtype, space.str_w(w_value))
         elif space.isinstance_w(w_value, space.w_unicode):
             return string_to_w_long(space, w_longtype,
                                     unicode_to_decimal_w(space, w_value))
         else:
-            # otherwise, use the __long__() or the __trunc__ methods
-            w_obj = w_value
-            if (space.lookup(w_obj, '__long__') is not None or
-                space.lookup(w_obj, '__int__') is not None):
-                w_obj = space.long(w_obj)
-            elif space.lookup(w_obj, '__trunc__') is not None:
-                w_obj = space.trunc(w_obj)
-                # :-(  blame CPython 2.7
-                if space.lookup(w_obj, '__long__') is not None:
-                    w_obj = space.long(w_obj)
-                else:
-                    w_obj = space.int(w_obj)
-            else:
-                raise operationerrfmt(space.w_TypeError,
-                    "long() argument must be a string or a number, not '%T'",
-                    w_obj)
-            bigint = space.bigint_w(w_obj)
-            return newbigint(space, w_longtype, bigint)
+            raise operationerrfmt(space.w_TypeError,
+                "long() argument must be a string or a number, not '%T'",
+                w_value)
     else:
         base = space.int_w(w_base)
 

pypy/objspace/std/test/test_longobject.py

                 return Integral()
         assert long(TruncReturnsNonLong()) == 42
 
+    def test_long_before_string(self):
+        class A(str):
+            def __long__(self):
+                return 42
+        assert long(A('abc')) == 42
+
     def test_conjugate(self):
         assert (7L).conjugate() == 7L
         assert (-7L).conjugate() == -7L