[pypy-commit] pypy remove-intlong-smm: add docs, cleanup and rearrange. do the commutative check when building

pjenvey noreply at buildbot.pypy.org
Sat Jan 4 00:51:41 CET 2014


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: remove-intlong-smm
Changeset: r68582:dbe309c00c2a
Date: 2014-01-03 15:50 -0800
http://bitbucket.org/pypy/pypy/changeset/dbe309c00c2a/

Log:	add docs, cleanup and rearrange. do the commutative check when
	building smalllong's descriptors

diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -23,6 +23,8 @@
 from pypy.interpreter.gateway import (
     WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
 from pypy.objspace.std import newformat
+from pypy.objspace.std.model import (
+    BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_INT)
 from pypy.objspace.std.stdtypedef import StdTypeDef
 
 
@@ -31,8 +33,163 @@
     __slots__ = ()
 
     def int(self, space):
+        """x.__int__() <==> int(x)"""
         raise NotImplementedError
 
+    def descr_coerce(self, space, w_other):
+        """x.__coerce__(y) <==> coerce(x, y)"""
+        if not isinstance(w_other, W_AbstractIntObject):
+            return space.w_NotImplemented
+        return space.newtuple([self, w_other])
+
+    def descr_long(self, space):
+        """x.__long__() <==> long(x)"""
+        from pypy.objspace.std.longobject import W_LongObject
+        return W_LongObject.fromint(space, self.int_w(space))
+
+    def descr_hash(self, space):
+        """x.__hash__() <==> hash(x)"""
+        # unlike CPython, we don't special-case the value -1 in most of
+        # our hash functions, so there is not much sense special-casing
+        # it here either.  Make sure this is consistent with the hash of
+        # floats and longs.
+        return self.int(space)
+
+    def descr_nonzero(self, space):
+        """x.__nonzero__() <==> x != 0"""
+        return space.newbool(space.int_w(self) != 0)
+
+    def descr_invert(self, space):
+        """x.__invert__() <==> ~x"""
+        return wrapint(space, ~space.int_w(self))
+
+    def descr_pos(self, space):
+        """x.__pos__() <==> +x"""
+        return self.int(space)
+    descr_trunc = func_with_new_name(descr_pos, 'descr_trunc')
+    descr_trunc.__doc__ = 'Truncating an Integral returns itself.'
+
+    def descr_neg(self, space):
+        """x.__neg__() <==> -x"""
+        a = space.int_w(self)
+        try:
+            x = ovfcheck(-a)
+        except OverflowError:
+            if _recover_with_smalllong(space):
+                from pypy.objspace.std.smalllongobject import neg_ovr
+                return neg_ovr(space, self)
+            return self.descr_long(space).descr_neg(space)
+        return wrapint(space, x)
+
+    def descr_abs(self, space):
+        """x.__abs__() <==> abs(x)"""
+        pos = space.int_w(self) >= 0
+        return self.int(space) if pos else self.descr_neg(space)
+
+    def descr_index(self, space):
+        """x[y:z] <==> x[y.__index__():z.__index__()]"""
+        return self.int(space)
+
+    def descr_float(self, space):
+        """x.__float__() <==> float(x)"""
+        a = space.int_w(self)
+        x = float(a)
+        return space.newfloat(x)
+
+    def descr_oct(self, space):
+        """x.__oct__() <==> oct(x)"""
+        return space.wrap(oct(space.int_w(self)))
+
+    def descr_hex(self, space):
+        """x.__hex__() <==> hex(x)"""
+        return space.wrap(hex(space.int_w(self)))
+
+    def descr_getnewargs(self, space):
+        return space.newtuple([wrapint(space, space.int_w(self))])
+
+    def descr_conjugate(self, space):
+        """Returns self, the complex conjugate of any int."""
+        return space.int(self)
+
+    def descr_bit_length(self, space):
+        """int.bit_length() -> int
+
+        Number of bits necessary to represent self in binary.
+        >>> bin(37)
+        '0b100101'
+        >>> (37).bit_length()
+        6
+        """
+        val = space.int_w(self)
+        if val < 0:
+            val = -val
+        bits = 0
+        while val:
+            bits += 1
+            val >>= 1
+        return space.wrap(bits)
+
+    def descr_repr(self, space):
+        """x.__repr__() <==> repr(x)"""
+        res = str(self.int_w(space))
+        return space.wrap(res)
+    descr_str = func_with_new_name(descr_repr, 'descr_str')
+    descr_str.__doc__ = "x.__str__() <==> str(x)"
+
+    def descr_format(self, space, w_format_spec):
+        return newformat.run_formatter(space, w_format_spec,
+                                       "format_int_or_long", self,
+                                       newformat.INT_KIND)
+
+    def descr_get_denominator(self, space):
+        return space.wrap(1)
+
+    def descr_get_imag(self, space):
+        return space.wrap(0)
+
+    descr_get_numerator = descr_get_real = descr_conjugate
+
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_pow(self, space, w_exponent, w_modulus=None):
+        """x.__pow__(y[, z]) <==> pow(x, y[, z])"""
+        if not isinstance(w_exponent, W_AbstractIntObject):
+            return space.w_NotImplemented
+
+        if space.is_none(w_modulus):
+            z = 0
+        elif isinstance(w_modulus, W_AbstractIntObject):
+            z = space.int_w(w_modulus)
+            if z == 0:
+                raise operationerrfmt(space.w_ValueError,
+                                      "pow() 3rd argument cannot be 0")
+        else:
+            # can't return NotImplemented (space.pow doesn't do full
+            # ternary, i.e. w_modulus.__zpow__(self, w_exponent)), so
+            # handle it ourselves
+            return self._ovfpow2long(space, w_exponent, w_modulus)
+
+        x = space.int_w(self)
+        y = space.int_w(w_exponent)
+        try:
+            result = _pow_impl(space, x, y, z)
+        except (OverflowError, ValueError):
+            return self._ovfpow2long(space, w_exponent, w_modulus)
+        return space.wrap(result)
+
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_rpow(self, space, w_base, w_modulus=None):
+        """y.__rpow__(x[, z]) <==> pow(x, y[, z])"""
+        if not isinstance(w_base, W_AbstractIntObject):
+            return space.w_NotImplemented
+        return w_base.descr_pow(space, self, w_modulus)
+
+    def _ovfpow2long(self, space, w_exponent, w_modulus):
+        if space.is_none(w_modulus) and _recover_with_smalllong(space):
+            from pypy.objspace.std.smalllongobject import pow_ovr
+            return pow_ovr(space, self, w_exponent)
+        self = self.descr_long(space)
+        return self.descr_pow(space, w_exponent, w_modulus)
+
     def _make_descr_cmp(opname):
         op = getattr(operator, opname)
         @func_renamer('descr_' + opname)
@@ -42,6 +199,7 @@
             i = space.int_w(self)
             j = space.int_w(w_other)
             return space.newbool(op(i, j))
+        descr_cmp.__doc__ = 'x.__%s__(y) <==> x%sy' % (opname, CMP_OPS[opname])
         return descr_cmp
 
     descr_lt = _make_descr_cmp('lt')
@@ -54,7 +212,9 @@
     def _make_generic_descr_binop(opname, ovf=True):
         op = getattr(operator,
                      opname + '_' if opname in ('and', 'or') else opname)
-        commutative = opname in ('add', 'mul', 'and', 'or', 'xor')
+        oper = BINARY_OPS.get(opname)
+        doc = "x.__%s__(y) <==> x%sy" % (opname, oper)
+        rdoc = "x.__r%s__(y) <==> y%sx" % (opname, oper)
 
         @func_renamer('descr_' + opname)
         def descr_binop(self, space, w_other):
@@ -67,43 +227,47 @@
                 try:
                     z = ovfcheck(op(x, y))
                 except OverflowError:
-                    return ovf2long(space, opname, self, w_other)
+                    return _ovf2long(space, opname, self, w_other)
             else:
                 z = op(x, y)
             return wrapint(space, z)
+        descr_binop.__doc__ = doc
 
-        if commutative:
-            return descr_binop, func_with_new_name(descr_binop,
-                                                   'descr_r' + opname)
+        if opname in COMMUTATIVE_OPS:
+            descr_rbinop = func_with_new_name(descr_binop, 'descr_r' + opname)
+        else:
+            @func_renamer('descr_r' + opname)
+            def descr_rbinop(self, space, w_other):
+                if not isinstance(w_other, W_AbstractIntObject):
+                    return space.w_NotImplemented
 
-        @func_renamer('descr_r' + opname)
-        def descr_rbinop(self, space, w_other):
-            if not isinstance(w_other, W_AbstractIntObject):
-                return space.w_NotImplemented
-
-            x = space.int_w(self)
-            y = space.int_w(w_other)
-            if ovf:
-                try:
-                    z = ovfcheck(op(y, x))
-                except OverflowError:
-                    return ovf2long(space, opname, w_other, self)
-            else:
-                z = op(y, x)
-            return wrapint(space, z)
+                x = space.int_w(self)
+                y = space.int_w(w_other)
+                if ovf:
+                    try:
+                        z = ovfcheck(op(y, x))
+                    except OverflowError:
+                        return _ovf2long(space, opname, w_other, self)
+                else:
+                    z = op(y, x)
+                return wrapint(space, z)
+        descr_rbinop.__doc__ = rdoc
 
         return descr_binop, descr_rbinop
 
     descr_add, descr_radd = _make_generic_descr_binop('add')
     descr_sub, descr_rsub = _make_generic_descr_binop('sub')
     descr_mul, descr_rmul = _make_generic_descr_binop('mul')
-
     descr_and, descr_rand = _make_generic_descr_binop('and', ovf=False)
     descr_or, descr_ror = _make_generic_descr_binop('or', ovf=False)
     descr_xor, descr_rxor = _make_generic_descr_binop('xor', ovf=False)
 
     def _make_descr_binop(func):
         opname = func.__name__[1:]
+        oper = BINARY_OPS.get(opname)
+        if oper == '%':
+            oper = '%%'
+        oper = '%s(%%s, %%s)' % opname if not oper else '%%s%s%%s' % oper
 
         @func_renamer('descr_' + opname)
         def descr_binop(self, space, w_other):
@@ -112,7 +276,9 @@
             try:
                 return func(self, space, w_other)
             except OverflowError:
-                return ovf2long(space, opname, self, w_other)
+                return _ovf2long(space, opname, self, w_other)
+        descr_binop.__doc__ = "x.__%s__(y) <==> %s" % (opname,
+                                                       oper % ('x', 'y'))
 
         @func_renamer('descr_r' + opname)
         def descr_rbinop(self, space, w_other):
@@ -121,7 +287,9 @@
             try:
                 return func(w_other, space, self)
             except OverflowError:
-                return ovf2long(space, opname, w_other, self)
+                return _ovf2long(space, opname, w_other, self)
+        descr_rbinop.__doc__ = "x.__r%s__(y) <==> %s" % (opname,
+                                                         oper % ('y', 'x'))
 
         return descr_binop, descr_rbinop
 
@@ -181,10 +349,10 @@
             return wrapint(space, c)
         if b < 0:
             raise operationerrfmt(space.w_ValueError, "negative shift count")
-        else: # b >= LONG_BIT
-            if a == 0:
-                return self.int(space)
-            raise OverflowError
+        # b >= LONG_BIT
+        if a == 0:
+            return self.int(space)
+        raise OverflowError
     descr_lshift, descr_rlshift = _make_descr_binop(_lshift)
 
     def _rshift(self, space, w_other):
@@ -203,143 +371,6 @@
         return wrapint(space, a)
     descr_rshift, descr_rrshift = _make_descr_binop(_rshift)
 
-    @unwrap_spec(w_modulus=WrappedDefault(None))
-    def descr_pow(self, space, w_exponent, w_modulus=None):
-        if not isinstance(w_exponent, W_AbstractIntObject):
-            return space.w_NotImplemented
-
-        if space.is_none(w_modulus):
-            z = 0
-        elif isinstance(w_modulus, W_AbstractIntObject):
-            z = space.int_w(w_modulus)
-            if z == 0:
-                raise operationerrfmt(space.w_ValueError,
-                                      "pow() 3rd argument cannot be 0")
-        else:
-            # can't return NotImplemented (space.pow doesn't do full
-            # ternary, i.e. w_modulus.__zpow__(self, w_exponent)), so
-            # handle it ourselves
-            return self._ovfpow2long(space, w_exponent, w_modulus)
-
-        x = space.int_w(self)
-        y = space.int_w(w_exponent)
-        try:
-            result = _pow_impl(space, x, y, z)
-        except (OverflowError, ValueError):
-            return self._ovfpow2long(space, w_exponent, w_modulus)
-        return space.wrap(result)
-
-    @unwrap_spec(w_modulus=WrappedDefault(None))
-    def descr_rpow(self, space, w_base, w_modulus=None):
-        if not isinstance(w_base, W_AbstractIntObject):
-            return space.w_NotImplemented
-        return w_base.descr_pow(space, self, w_modulus)
-
-    def _ovfpow2long(self, space, w_exponent, w_modulus):
-        if space.is_none(w_modulus) and recover_with_smalllong(space):
-            from pypy.objspace.std.smalllongobject import pow_ovr
-            return pow_ovr(space, self, w_exponent)
-        self = self.descr_long(space)
-        return self.descr_pow(space, w_exponent, w_modulus)
-
-    def descr_coerce(self, space, w_other):
-        if not isinstance(w_other, W_AbstractIntObject):
-            return space.w_NotImplemented
-        return space.newtuple([self, w_other])
-
-    def descr_long(self, space):
-        from pypy.objspace.std.longobject import W_LongObject
-        return W_LongObject.fromint(space, self.int_w(space))
-
-    def descr_hash(self, space):
-        # unlike CPython, we don't special-case the value -1 in most of
-        # our hash functions, so there is not much sense special-casing
-        # it here either.  Make sure this is consistent with the hash of
-        # floats and longs.
-        return self.int(space)
-
-    def descr_nonzero(self, space):
-        return space.newbool(space.int_w(self) != 0)
-
-    def descr_invert(self, space):
-        return wrapint(space, ~space.int_w(self))
-
-    def descr_pos(self, space):
-        return self.int(space)
-    descr_trunc = func_with_new_name(descr_pos, 'descr_trunc')
-
-    def descr_neg(self, space):
-        a = space.int_w(self)
-        try:
-            x = ovfcheck(-a)
-        except OverflowError:
-            if recover_with_smalllong(space):
-                from pypy.objspace.std.smalllongobject import neg_ovr
-                return neg_ovr(space, self)
-            return self.descr_long(space).descr_neg(space)
-        return wrapint(space, x)
-
-    def descr_abs(self, space):
-        pos = space.int_w(self) >= 0
-        return self.int(space) if pos else self.descr_neg(space)
-
-    def descr_index(self, space):
-        return self.int(space)
-
-    def descr_float(self, space):
-        a = space.int_w(self)
-        x = float(a)
-        return space.newfloat(x)
-
-    def descr_oct(self, space):
-        return space.wrap(oct(space.int_w(self)))
-
-    def descr_hex(self, space):
-        return space.wrap(hex(space.int_w(self)))
-
-    def descr_getnewargs(self, space):
-        return space.newtuple([wrapint(space, space.int_w(self))])
-
-    def descr_conjugate(self, space):
-        """Returns self, the complex conjugate of any int."""
-        return space.int(self)
-
-    def descr_bit_length(self, space):
-        """int.bit_length() -> int
-
-        Number of bits necessary to represent self in binary.
-        >>> bin(37)
-        '0b100101'
-        >>> (37).bit_length()
-        6
-        """
-        val = space.int_w(self)
-        if val < 0:
-            val = -val
-        bits = 0
-        while val:
-            bits += 1
-            val >>= 1
-        return space.wrap(bits)
-
-    def descr_repr(self, space):
-        res = str(self.int_w(space))
-        return space.wrap(res)
-    descr_str = descr_repr
-
-    def descr_format(self, space, w_format_spec):
-        return newformat.run_formatter(space, w_format_spec,
-                                       "format_int_or_long", self,
-                                       newformat.INT_KIND)
-
-    def descr_get_denominator(self, space):
-        return space.wrap(1)
-
-    def descr_get_imag(self, space):
-        return space.wrap(0)
-
-    descr_get_numerator = descr_get_real = descr_conjugate
-
 
 class W_IntObject(W_AbstractIntObject):
 
@@ -364,9 +395,8 @@
     def immutable_unique_id(self, space):
         if self.user_overridden_class:
             return None
-        from pypy.objspace.std.model import IDTAG_INT as tag
         b = space.bigint_w(self)
-        b = b.lshift(3).or_(rbigint.fromint(tag))
+        b = b.lshift(3).or_(rbigint.fromint(IDTAG_INT))
         return space.newlong_from_rbigint(b)
 
     def int_w(self, space):
@@ -397,7 +427,7 @@
         return space.newint(a)
 
 
-def recover_with_smalllong(space):
+def _recover_with_smalllong(space):
     # True if there is a chance that a SmallLong would fit when an Int
     # does not
     return (space.config.objspace.std.withsmalllong and
@@ -405,8 +435,8 @@
 
 
 @specialize.arg(1)
-def ovf2long(space, opname, self, w_other):
-    if recover_with_smalllong(space) and opname != 'truediv':
+def _ovf2long(space, opname, self, w_other):
+    if _recover_with_smalllong(space) and opname != 'truediv':
         from pypy.objspace.std import smalllongobject
         op = getattr(smalllongobject, opname + '_ovr')
         return op(space, self, w_other)
@@ -443,7 +473,6 @@
         ix %= iz
     return ix
 
-# ____________________________________________________________
 
 def wrapint(space, x):
     if not space.config.objspace.std.withprebuiltint:
@@ -465,10 +494,9 @@
     w_res.intval = x
     return w_res
 
-# ____________________________________________________________
 
 @jit.elidable
-def string_to_int_or_long(space, string, base=10):
+def _string_to_int_or_long(space, string, base=10):
     w_longval = None
     value = 0
     try:
@@ -476,10 +504,11 @@
     except ParseStringError as e:
         raise OperationError(space.w_ValueError, space.wrap(e.msg))
     except ParseStringOverflowError as e:
-        w_longval = retry_to_w_long(space, e.parser)
+        w_longval = _retry_to_w_long(space, e.parser)
     return value, w_longval
 
-def retry_to_w_long(space, parser):
+
+def _retry_to_w_long(space, parser):
     parser.rewind()
     try:
         bigint = rbigint._from_numberstring_parser(parser)
@@ -487,6 +516,7 @@
         raise OperationError(space.w_ValueError, space.wrap(e.msg))
     return space.newlong_from_rbigint(bigint)
 
+
 @unwrap_spec(w_x=WrappedDefault(0))
 def descr__new__(space, w_inttype, w_x, w_base=None):
     w_longval = None
@@ -512,12 +542,12 @@
             # an overflowing long
             value = space.int_w(w_obj)
         elif space.isinstance_w(w_value, space.w_str):
-            value, w_longval = string_to_int_or_long(space,
-                                                     space.str_w(w_value))
+            value, w_longval = _string_to_int_or_long(space,
+                                                      space.str_w(w_value))
         elif space.isinstance_w(w_value, space.w_unicode):
             from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
             string = unicode_to_decimal_w(space, w_value)
-            value, w_longval = string_to_int_or_long(space, string)
+            value, w_longval = _string_to_int_or_long(space, string)
         else:
             # If object supports the buffer interface
             try:
@@ -530,7 +560,7 @@
                     w_value)
             else:
                 buf = space.interp_w(Buffer, w_buffer)
-                value, w_longval = string_to_int_or_long(space, buf.as_str())
+                value, w_longval = _string_to_int_or_long(space, buf.as_str())
                 ok = True
     else:
         base = space.int_w(w_base)
@@ -546,7 +576,7 @@
                                       "int() can't convert non-string with "
                                       "explicit base")
 
-        value, w_longval = string_to_int_or_long(space, s, base)
+        value, w_longval = _string_to_int_or_long(space, s, base)
 
     if w_longval is not None:
         if not space.is_w(w_inttype, space.w_int):
@@ -561,35 +591,67 @@
         W_IntObject.__init__(w_obj, value)
         return w_obj
 
-# ____________________________________________________________
-
 
 W_AbstractIntObject.typedef = StdTypeDef("int",
-    __doc__ = """int(x[, base]) -> integer
+    __doc__ = """int(x=0) -> int or long
+int(x, base=10) -> int or long
 
-Convert a string or number to an integer, if possible.  A floating point
-argument will be truncated towards zero (this does not include a string
-representation of a floating point number!)  When converting a string, use
-the optional base.  It is an error to supply a base when converting a
-non-string. If the argument is outside the integer range a long object
-will be returned instead.""",
+Convert a number or string to an integer, or return 0 if no arguments
+are given.  If x is floating point, the conversion truncates towards zero.
+If x is outside the integer range, the function returns a long instead.
+
+If x is not a number or if base is given, then x must be a string or
+Unicode object representing an integer literal in the given base.  The
+literal can be preceded by '+' or '-' and be surrounded by whitespace.
+The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to
+interpret the base from the string as an integer literal.
+>>> int('0b100', base=0)
+4""",
     __new__ = interp2app(descr__new__),
 
     numerator = typedef.GetSetProperty(
-        W_AbstractIntObject.descr_get_numerator),
+        W_AbstractIntObject.descr_get_numerator,
+        doc="the numerator of a rational number in lowest terms"),
     denominator = typedef.GetSetProperty(
-        W_AbstractIntObject.descr_get_denominator),
-    real = typedef.GetSetProperty(W_AbstractIntObject.descr_get_real),
-    imag = typedef.GetSetProperty(W_AbstractIntObject.descr_get_imag),
+        W_AbstractIntObject.descr_get_denominator,
+        doc="the denominator of a rational number in lowest terms"),
+    real = typedef.GetSetProperty(
+        W_AbstractIntObject.descr_get_real,
+        doc="the real part of a complex number"),
+    imag = typedef.GetSetProperty(
+        W_AbstractIntObject.descr_get_imag,
+        doc="the imaginary part of a complex number"),
+
+    __repr__ = interp2app(W_AbstractIntObject.descr_repr),
+    __str__ = interp2app(W_AbstractIntObject.descr_str),
+
     conjugate = interpindirect2app(W_AbstractIntObject.descr_conjugate),
     bit_length = interpindirect2app(W_AbstractIntObject.descr_bit_length),
+    __format__ = interpindirect2app(W_AbstractIntObject.descr_format),
+    __hash__ = interpindirect2app(W_AbstractIntObject.descr_hash),
+    __coerce__ = interpindirect2app(W_AbstractIntObject.descr_coerce),
+    __oct__ = interpindirect2app(W_AbstractIntObject.descr_oct),
+    __hex__ = interpindirect2app(W_AbstractIntObject.descr_hex),
+    __getnewargs__ = interpindirect2app(W_AbstractIntObject.descr_getnewargs),
 
     __int__ = interpindirect2app(W_AbstractIntObject.int),
     __long__ = interpindirect2app(W_AbstractIntObject.descr_long),
+    __index__ = interpindirect2app(W_AbstractIntObject.descr_index),
+    __trunc__ = interpindirect2app(W_AbstractIntObject.descr_trunc),
+    __float__ = interpindirect2app(W_AbstractIntObject.descr_float),
 
-    __format__ = interpindirect2app(W_AbstractIntObject.descr_format),
-    __hash__ = interpindirect2app(W_AbstractIntObject.descr_hash),
-    __coerce__ = interpindirect2app(W_AbstractIntObject.descr_coerce),
+    __pos__ = interpindirect2app(W_AbstractIntObject.descr_pos),
+    __neg__ = interpindirect2app(W_AbstractIntObject.descr_neg),
+    __abs__ = interpindirect2app(W_AbstractIntObject.descr_abs),
+    __nonzero__ = interpindirect2app(W_AbstractIntObject.descr_nonzero),
+    __invert__ = interpindirect2app(W_AbstractIntObject.descr_invert),
+
+    __lt__ = interpindirect2app(W_AbstractIntObject.descr_lt),
+    __le__ = interpindirect2app(W_AbstractIntObject.descr_le),
+    __eq__ = interpindirect2app(W_AbstractIntObject.descr_eq),
+    __ne__ = interpindirect2app(W_AbstractIntObject.descr_ne),
+    __gt__ = interpindirect2app(W_AbstractIntObject.descr_gt),
+    __ge__ = interpindirect2app(W_AbstractIntObject.descr_ge),
 
     __add__ = interpindirect2app(W_AbstractIntObject.descr_add),
     __radd__ = interpindirect2app(W_AbstractIntObject.descr_radd),
@@ -597,12 +659,18 @@
     __rsub__ = interpindirect2app(W_AbstractIntObject.descr_rsub),
     __mul__ = interpindirect2app(W_AbstractIntObject.descr_mul),
     __rmul__ = interpindirect2app(W_AbstractIntObject.descr_rmul),
-    __lt__ = interpindirect2app(W_AbstractIntObject.descr_lt),
-    __le__ = interpindirect2app(W_AbstractIntObject.descr_le),
-    __eq__ = interpindirect2app(W_AbstractIntObject.descr_eq),
-    __ne__ = interpindirect2app(W_AbstractIntObject.descr_ne),
-    __gt__ = interpindirect2app(W_AbstractIntObject.descr_gt),
-    __ge__ = interpindirect2app(W_AbstractIntObject.descr_ge),
+
+    __and__ = interpindirect2app(W_AbstractIntObject.descr_and),
+    __rand__ = interpindirect2app(W_AbstractIntObject.descr_rand),
+    __or__ = interpindirect2app(W_AbstractIntObject.descr_or),
+    __ror__ = interpindirect2app(W_AbstractIntObject.descr_ror),
+    __xor__ = interpindirect2app(W_AbstractIntObject.descr_xor),
+    __rxor__ = interpindirect2app(W_AbstractIntObject.descr_rxor),
+
+    __lshift__ = interpindirect2app(W_AbstractIntObject.descr_lshift),
+    __rlshift__ = interpindirect2app(W_AbstractIntObject.descr_rlshift),
+    __rshift__ = interpindirect2app(W_AbstractIntObject.descr_rshift),
+    __rrshift__ = interpindirect2app(W_AbstractIntObject.descr_rrshift),
 
     __floordiv__ = interpindirect2app(W_AbstractIntObject.descr_floordiv),
     __rfloordiv__ = interpindirect2app(W_AbstractIntObject.descr_rfloordiv),
@@ -615,32 +683,6 @@
     __divmod__ = interpindirect2app(W_AbstractIntObject.descr_divmod),
     __rdivmod__ = interpindirect2app(W_AbstractIntObject.descr_rdivmod),
 
-    __lshift__ = interpindirect2app(W_AbstractIntObject.descr_lshift),
-    __rlshift__ = interpindirect2app(W_AbstractIntObject.descr_rlshift),
-    __rshift__ = interpindirect2app(W_AbstractIntObject.descr_rshift),
-    __rrshift__ = interpindirect2app(W_AbstractIntObject.descr_rrshift),
-
     __pow__ = interpindirect2app(W_AbstractIntObject.descr_pow),
     __rpow__ = interpindirect2app(W_AbstractIntObject.descr_rpow),
-    __neg__ = interpindirect2app(W_AbstractIntObject.descr_neg),
-    __abs__ = interpindirect2app(W_AbstractIntObject.descr_abs),
-    __nonzero__ = interpindirect2app(W_AbstractIntObject.descr_nonzero),
-    __invert__ = interpindirect2app(W_AbstractIntObject.descr_invert),
-    __and__ = interpindirect2app(W_AbstractIntObject.descr_and),
-    __rand__ = interpindirect2app(W_AbstractIntObject.descr_rand),
-    __xor__ = interpindirect2app(W_AbstractIntObject.descr_xor),
-    __rxor__ = interpindirect2app(W_AbstractIntObject.descr_rxor),
-    __or__ = interpindirect2app(W_AbstractIntObject.descr_or),
-    __ror__ = interpindirect2app(W_AbstractIntObject.descr_ror),
-
-    __pos__ = interpindirect2app(W_AbstractIntObject.descr_pos),
-    __trunc__ = interpindirect2app(W_AbstractIntObject.descr_trunc),
-    __index__ = interpindirect2app(W_AbstractIntObject.descr_index),
-    __float__ = interpindirect2app(W_AbstractIntObject.descr_float),
-    __oct__ = interpindirect2app(W_AbstractIntObject.descr_oct),
-    __hex__ = interpindirect2app(W_AbstractIntObject.descr_hex),
-    __getnewargs__ = interpindirect2app(W_AbstractIntObject.descr_getnewargs),
-
-    __repr__ = interp2app(W_AbstractIntObject.descr_repr),
-    __str__ = interp2app(W_AbstractIntObject.descr_str),
 )
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -14,6 +14,8 @@
     WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
 from pypy.objspace.std import newformat
 from pypy.objspace.std.intobject import W_AbstractIntObject
+from pypy.objspace.std.model import (
+    BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_LONG)
 from pypy.objspace.std.stdtypedef import StdTypeDef
 
 
@@ -42,9 +44,8 @@
     def immutable_unique_id(self, space):
         if self.user_overridden_class:
             return None
-        from pypy.objspace.std.model import IDTAG_LONG as tag
         b = space.bigint_w(self)
-        b = b.lshift(3).or_(rbigint.fromint(tag))
+        b = b.lshift(3).or_(rbigint.fromint(IDTAG_LONG))
         return space.newlong_from_rbigint(b)
 
     def unwrap(self, space):
@@ -56,85 +57,22 @@
     def asbigint(self):
         raise NotImplementedError
 
-    # XXX: cleanup, docstrings etc
-    def descr_long(self, space):
-        raise NotImplementedError
-    descr_index = func_with_new_name(descr_long, 'descr_index')
-    descr_trunc = func_with_new_name(descr_long, 'descr_trunc')
-    descr_pos = func_with_new_name(descr_long, 'descr_pos')
-
-    descr_float = func_with_new_name(descr_long, 'descr_float')
-    descr_neg = func_with_new_name(descr_long, 'descr_neg')
-    descr_pos = func_with_new_name(descr_long, 'descr_pos')
-    descr_abs = func_with_new_name(descr_long, 'descr_abs')
-    descr_nonzero = func_with_new_name(descr_long, 'descr_nonzero')
-    descr_invert = func_with_new_name(descr_long, 'descr_invert')
-
-    def descr_lt(self, space, w_other):
-        raise NotImplementedError
-    descr_le = func_with_new_name(descr_lt, 'descr_le')
-    descr_eq = func_with_new_name(descr_lt, 'descr_eq')
-    descr_ne = func_with_new_name(descr_lt, 'descr_ne')
-    descr_gt = func_with_new_name(descr_lt, 'descr_gt')
-    descr_ge = func_with_new_name(descr_lt, 'descr_ge')
-
-    descr_add = func_with_new_name(descr_lt, 'descr_add')
-    descr_radd = func_with_new_name(descr_lt, 'descr_radd')
-    descr_sub = func_with_new_name(descr_lt, 'descr_sub')
-    descr_rsub = func_with_new_name(descr_lt, 'descr_rsub')
-    descr_mul = func_with_new_name(descr_lt, 'descr_mul')
-    descr_rmul = func_with_new_name(descr_lt, 'descr_rmul')
-
-    descr_and = func_with_new_name(descr_lt, 'descr_and')
-    descr_rand = func_with_new_name(descr_lt, 'descr_rand')
-    descr_or = func_with_new_name(descr_lt, 'descr_or')
-    descr_ror = func_with_new_name(descr_lt, 'descr_ror')
-    descr_xor = func_with_new_name(descr_lt, 'descr_xor')
-    descr_rxor = func_with_new_name(descr_lt, 'descr_rxor')
-
-    descr_lshift = func_with_new_name(descr_lt, 'descr_lshift')
-    descr_rlshift = func_with_new_name(descr_lt, 'descr_rlshift')
-    descr_rshift = func_with_new_name(descr_lt, 'descr_rshift')
-    descr_rrshift = func_with_new_name(descr_lt, 'descr_rrshift')
-
-    descr_floordiv = func_with_new_name(descr_lt, 'descr_floordiv')
-    descr_rfloordiv = func_with_new_name(descr_lt, 'descr_rfloordiv')
-    descr_div = func_with_new_name(descr_lt, 'descr_div')
-    descr_rdiv = func_with_new_name(descr_lt, 'descr_rdiv')
-    descr_mod = func_with_new_name(descr_lt, 'descr_mod')
-    descr_rmod = func_with_new_name(descr_lt, 'descr_rmod')
-    descr_divmod = func_with_new_name(descr_lt, 'descr_divmod')
-    descr_rdivmod = func_with_new_name(descr_lt, 'descr_rdivmod')
-
-    def descr_pow(self, space, w_exponent, w_modulus=None):
-        raise NotImplementedError
-    descr_rpow = func_with_new_name(descr_pow, 'descr_rpow')
-
-    def descr_format(self, space, w_format_spec):
-        return newformat.run_formatter(space, w_format_spec,
-                                       "format_int_or_long", self,
-                                       newformat.LONG_KIND)
-
-    def _make_descr_unaryop(opname):
-        op = getattr(rbigint, opname)
-        @func_renamer('descr_' + opname)
-        def descr_unaryop(self, space):
-            return space.wrap(op(self.asbigint()))
-        return descr_unaryop
-
-    descr_repr = _make_descr_unaryop('repr')
-    descr_str = _make_descr_unaryop('str')
-    descr_hash = _make_descr_unaryop('hash')
-    descr_oct = _make_descr_unaryop('oct')
-    descr_hex = _make_descr_unaryop('hex')
-
     def descr_getnewargs(self, space):
-        return space.newtuple([W_LongObject(self.asbigint())])
+        return space.newtuple([newlong(space, self.asbigint())])
 
     def descr_conjugate(self, space):
+        """Returns self, the complex conjugate of any long."""
         return space.long(self)
 
     def descr_bit_length(self, space):
+        """long.bit_length() -> int or long
+
+        Number of bits necessary to represent self in binary.
+        >>> bin(37L)
+        '0b100101'
+        >>> (37L).bit_length()
+        6
+        """
         bigint = space.bigint_w(self)
         try:
             return space.wrap(bigint.bit_length())
@@ -155,26 +93,118 @@
 
     @delegate_other
     def descr_truediv(self, space, w_other):
+        """x.__truediv__(y) <==> x/y"""
         return W_AbstractLongObject._truediv(self, space, w_other)
 
     @delegate_other
     def descr_rtruediv(self, space, w_other):
+        """x.__rtruediv__(y) <==> y/x"""
         return W_AbstractLongObject._truediv(w_other, space, self)
 
     @delegate_other
     def descr_coerce(self, space, w_other):
+        """x.__coerce__(y) <==> coerce(x, y)"""
         return space.newtuple([self, w_other])
 
     def descr_get_numerator(self, space):
         return space.long(self)
     descr_get_real = func_with_new_name(descr_get_numerator, 'descr_get_real')
 
+    def descr_format(self, space, w_format_spec):
+        return newformat.run_formatter(space, w_format_spec,
+                                       "format_int_or_long", self,
+                                       newformat.LONG_KIND)
+
     def descr_get_denominator(self, space):
         return space.newlong(1)
 
     def descr_get_imag(self, space):
         return space.newlong(0)
 
+    def _make_descr_unaryop(opname):
+        op = getattr(rbigint, opname)
+        @func_renamer('descr_' + opname)
+        def descr_unaryop(self, space):
+            return space.wrap(op(self.asbigint()))
+        descr_unaryop.__doc__ = 'x.__%s__(y) <==> %s(x, y)' % (opname, opname)
+        return descr_unaryop
+
+    descr_repr = _make_descr_unaryop('repr')
+    descr_str = _make_descr_unaryop('str')
+    descr_hash = _make_descr_unaryop('hash')
+    descr_oct = _make_descr_unaryop('oct')
+    descr_hex = _make_descr_unaryop('hex')
+
+    def descr_pow(self, space, w_exponent, w_modulus=None):
+        """x.__pow__(y[, z]) <==> pow(x, y[, z])"""
+        raise NotImplementedError
+    descr_rpow = func_with_new_name(descr_pow, 'descr_rpow')
+    descr_rpow.__doc__ = "y.__rpow__(x[, z]) <==> pow(x, y[, z])"
+
+    def _abstract_unaryop(opname, doc=None):
+        @func_renamer('descr_' + opname)
+        def descr_unaryop(self, space):
+            raise NotImplementedError
+        descr_unaryop.__doc__ = doc
+        return descr_unaryop
+
+    descr_long = _abstract_unaryop('long', "x.__long__() <==> long(x)")
+    descr_float = _abstract_unaryop('float', "x.__float__() <==> float(x)")
+    descr_index = _abstract_unaryop(
+        'index', "x[y:z] <==> x[y.__index__():z.__index__()]")
+    descr_trunc = _abstract_unaryop('trunc',
+                                    "Truncating an Integral returns itself.")
+    descr_pos = _abstract_unaryop('pos', "x.__pos__() <==> +x")
+    descr_neg = _abstract_unaryop('neg', "x.__neg__() <==> -x")
+    descr_abs = _abstract_unaryop('abs', "x.__abs__() <==> abs(x)")
+    descr_nonzero = _abstract_unaryop('nonzero', "x.__nonzero__() <==> x != 0")
+    descr_invert = _abstract_unaryop('invert', "x.__invert__() <==> ~x")
+
+    def _abstract_cmpop(opname):
+        @func_renamer('descr_' + opname)
+        def descr_cmp(self, space, w_other):
+            raise NotImplementedError
+        descr_cmp.__doc__ = 'x.__%s__(y) <==> x%sy' % (opname, CMP_OPS[opname])
+        return descr_cmp
+
+    descr_lt = _abstract_cmpop('lt')
+    descr_le = _abstract_cmpop('le')
+    descr_eq = _abstract_cmpop('eq')
+    descr_ne = _abstract_cmpop('ne')
+    descr_gt = _abstract_cmpop('gt')
+    descr_ge = _abstract_cmpop('ge')
+
+    def _abstract_binop(opname):
+        oper = BINARY_OPS.get(opname)
+        if oper == '%':
+            oper = '%%'
+        oper = '%s(%%s, %%s)' % opname if not oper else '%%s%s%%s' % oper
+        @func_renamer('descr_' + opname)
+        def descr_binop(self, space, w_other):
+            raise NotImplementedError
+        descr_binop.__doc__ = "x.__%s__(y) <==> %s" % (opname,
+                                                       oper % ('x', 'y'))
+        descr_rbinop = func_with_new_name(descr_binop, 'descr_r' + opname)
+        descr_rbinop.__doc__ = "x.__r%s__(y) <==> %s" % (opname,
+                                                         oper % ('y', 'x'))
+        return descr_binop, descr_rbinop
+
+    descr_add, descr_radd = _abstract_binop('add')
+    descr_sub, descr_rsub = _abstract_binop('sub')
+    descr_mul, descr_rmul = _abstract_binop('mul')
+
+    descr_and, descr_rand = _abstract_binop('and')
+    descr_or, descr_ror = _abstract_binop('or')
+    descr_xor, descr_rxor = _abstract_binop('xor')
+
+    descr_lshift, descr_rlshift = _abstract_binop('lshift')
+    descr_rshift, descr_rrshift = _abstract_binop('rshift')
+
+    descr_floordiv, descr_rfloordiv = _abstract_binop('floordiv')
+    descr_div, descr_rdiv = _abstract_binop('div')
+    descr_mod, descr_rmod = _abstract_binop('mod')
+    descr_divmod, descr_rdivmod = _abstract_binop('divmod')
+
 
 class W_LongObject(W_AbstractLongObject):
     """This is a wrapper of rbigint."""
@@ -265,6 +295,57 @@
     def descr_float(self, space):
         return space.newfloat(self.tofloat(space))
 
+    def descr_nonzero(self, space):
+        return space.newbool(self.num.tobool())
+
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_pow(self, space, w_exponent, w_modulus=None):
+        if isinstance(w_exponent, W_AbstractIntObject):
+            w_exponent = w_exponent.descr_long(space)
+        elif not isinstance(w_exponent, W_AbstractLongObject):
+            return space.w_NotImplemented
+
+        if space.is_none(w_modulus):
+            if w_exponent.asbigint().sign < 0:
+                self = self.descr_float(space)
+                w_exponent = w_exponent.descr_float(space)
+                return space.pow(self, w_exponent, space.w_None)
+            return W_LongObject(self.num.pow(w_exponent.asbigint()))
+        elif isinstance(w_modulus, W_AbstractIntObject):
+            w_modulus = w_modulus.descr_long(space)
+        elif not isinstance(w_modulus, W_AbstractLongObject):
+            return space.w_NotImplemented
+
+        if w_exponent.asbigint().sign < 0:
+            raise operationerrfmt(space.w_TypeError,
+                                  "pow() 2nd argument cannot be negative when "
+                                  "3rd argument specified")
+        try:
+            result = self.num.pow(w_exponent.asbigint(), w_modulus.asbigint())
+        except ValueError:
+            raise operationerrfmt(space.w_ValueError,
+                                  "pow 3rd argument cannot be 0")
+        return W_LongObject(result)
+
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_rpow(self, space, w_base, w_modulus=None):
+        if isinstance(w_base, W_AbstractIntObject):
+            w_base = w_base.descr_long(space)
+        elif not isinstance(w_base, W_AbstractLongObject):
+            return space.w_NotImplemented
+        return w_base.descr_pow(space, self, w_modulus)
+
+    def _make_descr_unaryop(opname):
+        op = getattr(rbigint, opname)
+        @func_renamer('descr_' + opname)
+        def descr_unaryop(self, space):
+            return W_LongObject(op(self.num))
+        return descr_unaryop
+
+    descr_neg = _make_descr_unaryop('neg')
+    descr_abs = _make_descr_unaryop('abs')
+    descr_invert = _make_descr_unaryop('invert')
+
     def _make_descr_cmp(opname):
         op = getattr(rbigint, opname)
         @delegate_other
@@ -290,11 +371,14 @@
         def descr_binop(self, space, w_other):
             return W_LongObject(op(self.num, w_other.asbigint()))
 
-        @func_renamer('descr_r' + opname)
-        @delegate_other
-        def descr_rbinop(self, space, w_other):
-            # XXX: delegate, for --objspace-std-withsmalllong
-            return W_LongObject(op(w_other.asbigint(), self.num))
+        if opname in COMMUTATIVE_OPS:
+            descr_rbinop = func_with_new_name(descr_binop, 'descr_r' + opname)
+        else:
+            @func_renamer('descr_r' + opname)
+            @delegate_other
+            def descr_rbinop(self, space, w_other):
+                # XXX: delegate, for --objspace-std-withsmalllong
+                return W_LongObject(op(w_other.asbigint(), self.num))
 
         return descr_binop, descr_rbinop
 
@@ -305,20 +389,6 @@
     descr_or, descr_ror = _make_generic_descr_binop('or')
     descr_xor, descr_rxor = _make_generic_descr_binop('xor')
 
-    def _make_descr_unaryop(opname):
-        op = getattr(rbigint, opname)
-        @func_renamer('descr_' + opname)
-        def descr_unaryop(self, space):
-            return W_LongObject(op(self.num))
-        return descr_unaryop
-
-    descr_neg = _make_descr_unaryop('neg')
-    descr_abs = _make_descr_unaryop('abs')
-    descr_invert = _make_descr_unaryop('invert')
-
-    def descr_nonzero(self, space):
-        return space.newbool(self.num.tobool())
-
     def _make_descr_binop(func):
         opname = func.__name__[1:]
 
@@ -389,43 +459,6 @@
         return space.newtuple([newlong(space, div), newlong(space, mod)])
     descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
 
-    @unwrap_spec(w_modulus=WrappedDefault(None))
-    def descr_pow(self, space, w_exponent, w_modulus=None):
-        if isinstance(w_exponent, W_AbstractIntObject):
-            w_exponent = w_exponent.descr_long(space)
-        elif not isinstance(w_exponent, W_AbstractLongObject):
-            return space.w_NotImplemented
-
-        if space.is_none(w_modulus):
-            if w_exponent.asbigint().sign < 0:
-                self = self.descr_float(space)
-                w_exponent = w_exponent.descr_float(space)
-                return space.pow(self, w_exponent, space.w_None)
-            return W_LongObject(self.num.pow(w_exponent.asbigint()))
-        elif isinstance(w_modulus, W_AbstractIntObject):
-            w_modulus = w_modulus.descr_long(space)
-        elif not isinstance(w_modulus, W_AbstractLongObject):
-            return space.w_NotImplemented
-
-        if w_exponent.asbigint().sign < 0:
-            raise operationerrfmt(space.w_TypeError,
-                                  "pow() 2nd argument cannot be negative when "
-                                  "3rd argument specified")
-        try:
-            result = self.num.pow(w_exponent.asbigint(), w_modulus.asbigint())
-        except ValueError:
-            raise operationerrfmt(space.w_ValueError,
-                                  "pow 3rd argument cannot be 0")
-        return W_LongObject(result)
-
-    @unwrap_spec(w_modulus=WrappedDefault(None))
-    def descr_rpow(self, space, w_base, w_modulus=None):
-        if isinstance(w_base, W_AbstractIntObject):
-            w_base = w_base.descr_long(space)
-        elif not isinstance(w_base, W_AbstractLongObject):
-            return space.w_NotImplemented
-        return w_base.descr_pow(space, self, w_modulus)
-
 
 def newlong(space, bigint):
     """Turn the bigint into a W_LongObject.  If withsmalllong is
@@ -471,11 +504,11 @@
                 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))
+            return _string_to_w_long(space, w_longtype, space.str_w(w_value))
         elif space.isinstance_w(w_value, space.w_unicode):
             from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
-            return string_to_w_long(space, w_longtype,
-                                    unicode_to_decimal_w(space, w_value))
+            return _string_to_w_long(space, w_longtype,
+                                     unicode_to_decimal_w(space, w_value))
         else:
             try:
                 w_buffer = space.buffer(w_value)
@@ -487,7 +520,7 @@
                     w_value)
             else:
                 buf = space.interp_w(Buffer, w_buffer)
-                return string_to_w_long(space, w_longtype, buf.as_str())
+                return _string_to_w_long(space, w_longtype, buf.as_str())
     else:
         base = space.int_w(w_base)
 
@@ -501,16 +534,16 @@
                 raise operationerrfmt(space.w_TypeError,
                                       "long() can't convert non-string with "
                                       "explicit base")
-        return string_to_w_long(space, w_longtype, s, base)
+        return _string_to_w_long(space, w_longtype, s, base)
 
 
-def string_to_w_long(space, w_longtype, s, base=10):
+def _string_to_w_long(space, w_longtype, s, base=10):
     try:
         bigint = rbigint.fromstr(s, base)
     except ParseStringError as e:
         raise OperationError(space.w_ValueError, space.wrap(e.msg))
     return newbigint(space, w_longtype, bigint)
-string_to_w_long._dont_inline_ = True
+_string_to_w_long._dont_inline_ = True
 
 
 def newbigint(space, w_longtype, bigint):
@@ -534,23 +567,45 @@
 
 
 W_AbstractLongObject.typedef = StdTypeDef("long",
-    __doc__ = """long(x[, base]) -> integer
+    __doc__ = """long(x=0) -> long
+long(x, base=10) -> long
 
-Convert a string or number to a long integer, if possible.  A floating
-point argument will be truncated towards zero (this does not include a
-string representation of a floating point number!)  When converting a
-string, use the optional base.  It is an error to supply a base when
-converting a non-string.""",
+Convert a number or string to a long integer, or return 0L if no arguments
+are given.  If x is floating point, the conversion truncates towards zero.
+
+If x is not a number or if base is given, then x must be a string or
+Unicode object representing an integer literal in the given base.  The
+literal can be preceded by '+' or '-' and be surrounded by whitespace.
+The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to
+interpret the base from the string as an integer literal.
+>>> int('0b100', base=0)
+4L""",
     __new__ = interp2app(descr__new__),
 
     numerator = typedef.GetSetProperty(
-        W_AbstractLongObject.descr_get_numerator),
+        W_AbstractLongObject.descr_get_numerator,
+        doc="the numerator of a rational number in lowest terms"),
     denominator = typedef.GetSetProperty(
-        W_AbstractLongObject.descr_get_denominator),
-    real = typedef.GetSetProperty(W_AbstractLongObject.descr_get_real),
-    imag = typedef.GetSetProperty(W_AbstractLongObject.descr_get_imag),
-    conjugate = interp2app(W_AbstractLongObject.descr_conjugate),
-    bit_length = interp2app(W_AbstractLongObject.descr_bit_length),
+        W_AbstractLongObject.descr_get_denominator,
+        doc="the denominator of a rational number in lowest terms"),
+    real = typedef.GetSetProperty(
+        W_AbstractLongObject.descr_get_real,
+        doc="the real part of a complex number"),
+    imag = typedef.GetSetProperty(
+        W_AbstractLongObject.descr_get_imag,
+        doc="the imaginary part of a complex number"),
+
+    __repr__ = interp2app(W_AbstractLongObject.descr_repr),
+    __str__ = interp2app(W_AbstractLongObject.descr_str),
+
+    conjugate = interpindirect2app(W_AbstractLongObject.descr_conjugate),
+    bit_length = interpindirect2app(W_AbstractLongObject.descr_bit_length),
+    __format__ = interpindirect2app(W_AbstractLongObject.descr_format),
+    __hash__ = interpindirect2app(W_AbstractLongObject.descr_hash),
+    __coerce__ = interpindirect2app(W_AbstractLongObject.descr_coerce),
+    __oct__ = interpindirect2app(W_AbstractLongObject.descr_oct),
+    __hex__ = interpindirect2app(W_AbstractLongObject.descr_hex),
+    __getnewargs__ = interpindirect2app(W_AbstractLongObject.descr_getnewargs),
 
     __int__ = interpindirect2app(W_AbstractLongObject.int),
     __long__ = interpindirect2app(W_AbstractLongObject.descr_long),
@@ -558,12 +613,11 @@
     __trunc__ = interpindirect2app(W_AbstractLongObject.descr_trunc),
     __float__ = interpindirect2app(W_AbstractLongObject.descr_float),
 
-    __repr__ = interp2app(W_AbstractLongObject.descr_repr),
-    __str__ = interp2app(W_AbstractLongObject.descr_str),
-    __format__ = interp2app(W_AbstractLongObject.descr_format),
-
-    __hash__ = interp2app(W_AbstractLongObject.descr_hash),
-    __coerce__ = interp2app(W_AbstractLongObject.descr_coerce),
+    __pos__ = interpindirect2app(W_AbstractLongObject.descr_pos),
+    __neg__ = interpindirect2app(W_AbstractLongObject.descr_neg),
+    __abs__ = interpindirect2app(W_AbstractLongObject.descr_abs),
+    __nonzero__ = interpindirect2app(W_AbstractLongObject.descr_nonzero),
+    __invert__ = interpindirect2app(W_AbstractLongObject.descr_invert),
 
     __lt__ = interpindirect2app(W_AbstractLongObject.descr_lt),
     __le__ = interpindirect2app(W_AbstractLongObject.descr_le),
@@ -586,26 +640,17 @@
     __xor__ = interpindirect2app(W_AbstractLongObject.descr_xor),
     __rxor__ = interpindirect2app(W_AbstractLongObject.descr_rxor),
 
-    __neg__ = interpindirect2app(W_AbstractLongObject.descr_neg),
-    __pos__ = interpindirect2app(W_AbstractLongObject.descr_pos),
-    __abs__ = interpindirect2app(W_AbstractLongObject.descr_abs),
-    __nonzero__ = interpindirect2app(W_AbstractLongObject.descr_nonzero),
-    __invert__ = interpindirect2app(W_AbstractLongObject.descr_invert),
-
-    __oct__ = interp2app(W_AbstractLongObject.descr_oct),
-    __hex__ = interp2app(W_AbstractLongObject.descr_hex),
-
     __lshift__ = interpindirect2app(W_AbstractLongObject.descr_lshift),
     __rlshift__ = interpindirect2app(W_AbstractLongObject.descr_rlshift),
     __rshift__ = interpindirect2app(W_AbstractLongObject.descr_rshift),
     __rrshift__ = interpindirect2app(W_AbstractLongObject.descr_rrshift),
 
-    __truediv__ = interp2app(W_AbstractLongObject.descr_truediv),
-    __rtruediv__ = interp2app(W_AbstractLongObject.descr_rtruediv),
     __floordiv__ = interpindirect2app(W_AbstractLongObject.descr_floordiv),
     __rfloordiv__ = interpindirect2app(W_AbstractLongObject.descr_rfloordiv),
     __div__ = interpindirect2app(W_AbstractLongObject.descr_div),
     __rdiv__ = interpindirect2app(W_AbstractLongObject.descr_rdiv),
+    __truediv__ = interpindirect2app(W_AbstractLongObject.descr_truediv),
+    __rtruediv__ = interpindirect2app(W_AbstractLongObject.descr_rtruediv),
     __mod__ = interpindirect2app(W_AbstractLongObject.descr_mod),
     __rmod__ = interpindirect2app(W_AbstractLongObject.descr_rmod),
     __divmod__ = interpindirect2app(W_AbstractLongObject.descr_divmod),
@@ -613,6 +658,4 @@
 
     __pow__ = interpindirect2app(W_AbstractLongObject.descr_pow),
     __rpow__ = interpindirect2app(W_AbstractLongObject.descr_rpow),
-
-    __getnewargs__ = interp2app(W_AbstractLongObject.descr_getnewargs),
 )
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -232,8 +232,9 @@
         return space.not_(function(space, w_2, w_1))
     return op
 
-OPERATORS = ['lt', 'le', 'eq', 'ne', 'gt', 'ge']
-OP_CORRESPONDANCES = [
+
+CMP_OPS = dict(lt='<', le='<=', eq='==', ne='!=', gt='>', ge='>=')
+CMP_CORRESPONDANCES = [
     ('eq', 'ne', _op_negated),
     ('lt', 'gt', _op_swapped),
     ('le', 'ge', _op_swapped),
@@ -242,22 +243,27 @@
     ('lt', 'le', _op_swapped_negated),
     ('gt', 'ge', _op_swapped_negated),
     ]
-for op1, op2, value in OP_CORRESPONDANCES[:]:
-    i = OP_CORRESPONDANCES.index((op1, op2, value))
-    OP_CORRESPONDANCES.insert(i+1, (op2, op1, value))
+for op1, op2, value in CMP_CORRESPONDANCES[:]:
+    i = CMP_CORRESPONDANCES.index((op1, op2, value))
+    CMP_CORRESPONDANCES.insert(i+1, (op2, op1, value))
+BINARY_BITWISE_OPS = {'and': '&', 'lshift': '<<', 'or': '|', 'rshift': '>>',
+                      'xor': '^'}
+BINARY_OPS = dict(add='+', div='/', floordiv='//', mod='%', mul='*', sub='-',
+                  truediv='/', **BINARY_BITWISE_OPS)
+COMMUTATIVE_OPS = ('add', 'mul', 'and', 'or', 'xor')
 
 def add_extra_comparisons():
     """
     Add the missing comparison operators if they were not explicitly
     defined:  eq <-> ne  and  lt <-> le <-> gt <-> ge.
-    We try to add them in the order defined by the OP_CORRESPONDANCES
+    We try to add them in the order defined by the CMP_CORRESPONDANCES
     table, thus favouring swapping the arguments over negating the result.
     """
     originalentries = {}
-    for op in OPERATORS:
+    for op in CMP_OPS.iterkeys():
         originalentries[op] = getattr(MM, op).signatures()
 
-    for op1, op2, correspondance in OP_CORRESPONDANCES:
+    for op1, op2, correspondance in CMP_CORRESPONDANCES:
         mirrorfunc = getattr(MM, op2)
         for types in originalentries[op1]:
             t1, t2 = types
diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py
--- a/pypy/objspace/std/smalllongobject.py
+++ b/pypy/objspace/std/smalllongobject.py
@@ -13,6 +13,7 @@
 from pypy.interpreter.gateway import WrappedDefault, unwrap_spec
 from pypy.objspace.std.intobject import W_AbstractIntObject
 from pypy.objspace.std.longobject import W_AbstractLongObject, W_LongObject
+from pypy.objspace.std.model import COMMUTATIVE_OPS
 
 # XXX: breaks translation
 #LONGLONG_MIN = r_longlong(-1 << (LONGLONG_BIT - 1))
@@ -83,6 +84,75 @@
     def descr_float(self, space):
         return space.newfloat(float(self.longlong))
 
+    def descr_neg(self, space):
+        a = self.longlong
+        try:
+            if a == r_longlong(-1 << (LONGLONG_BIT-1)):
+                raise OverflowError
+            x = -a
+        except OverflowError:
+            self = _small2long(space, self)
+            return self.descr_neg(space)
+        return W_SmallLongObject(x)
+
+    def descr_abs(self, space):
+        return self if self.longlong >= 0 else self.descr_neg(space)
+
+    def descr_nonzero(self, space):
+        return space.newbool(bool(self.longlong))
+
+    def descr_invert(self, space):
+        x = ~self.longlong
+        return W_SmallLongObject(x)
+
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_pow(self, space, w_exponent, w_modulus=None):
+        if isinstance(w_exponent, W_AbstractLongObject):
+            self = _small2long(space, self)
+            return self.descr_pow(space, w_exponent, w_modulus)
+        elif not isinstance(w_exponent, W_AbstractIntObject):
+            return space.w_NotImplemented
+
+        if space.is_none(w_modulus):
+            try:
+                return _pow_impl(space, self.longlong, w_exponent,
+                                 r_longlong(0))
+            except ValueError:
+                self = self.descr_float(space)
+                return space.pow(self, w_exponent, space.w_None)
+            except OverflowError:
+                self = _small2long(space, self)
+                return self.descr_pow(space, w_exponent, w_modulus)
+        elif isinstance(w_modulus, W_AbstractIntObject):
+            w_modulus = _int2small(space, w_modulus)
+        elif not isinstance(w_modulus, W_AbstractLongObject):
+            return space.w_NotImplemented
+        elif not isinstance(w_modulus, W_SmallLongObject):
+            self = _small2long(space, self)
+            return self.descr_pow(space, w_exponent, w_modulus)
+
+        z = w_modulus.longlong
+        if z == 0:
+            raise operationerrfmt(space.w_ValueError,
+                                  "pow() 3rd argument cannot be 0")
+        try:
+            return _pow_impl(space, self.longlong, w_exponent, z)
+        except ValueError:
+            self = self.descr_float(space)
+            return space.pow(self, w_exponent, w_modulus)
+        except OverflowError:
+            self = _small2long(space, self)
+            return self.descr_pow(space, w_exponent, w_modulus)
+
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_rpow(self, space, w_base, w_modulus=None):
+        if isinstance(w_base, W_AbstractIntObject):
+            # Defer to w_base<W_SmallLongObject>.descr_pow
+            w_base = _int2small(space, w_base)
+        elif not isinstance(w_base, W_AbstractLongObject):
+            return space.w_NotImplemented
+        return w_base.descr_pow(space, self, w_modulus)
+
     def _make_descr_cmp(opname):
         op = getattr(operator, opname)
         bigint_op = getattr(rbigint, opname)
@@ -108,42 +178,46 @@
 
     def _make_descr_binop(func):
         opname = func.__name__[1:]
-        descr_name = 'descr_' + opname
-        descr_rname = 'descr_r' + opname
+        descr_name, descr_rname = 'descr_' + opname, 'descr_r' + opname
+        long_op = getattr(W_LongObject, descr_name)
 
         @func_renamer(descr_name)
         def descr_binop(self, space, w_other):
             if isinstance(w_other, W_AbstractIntObject):
-                w_other = delegate_Int2SmallLong(space, w_other)
+                w_other = _int2small(space, w_other)
             elif not isinstance(w_other, W_AbstractLongObject):
                 return space.w_NotImplemented
             elif not isinstance(w_other, W_SmallLongObject):
-                self = delegate_SmallLong2Long(space, self)
-                return getattr(self, descr_name)(space, w_other)
+                self = _small2long(space, self)
+                return long_op(self, space, w_other)
 
             try:
                 return func(self, space, w_other)
             except OverflowError:
-                self = delegate_SmallLong2Long(space, self)
-                w_other = delegate_SmallLong2Long(space, w_other)
-                return getattr(self, descr_name)(space, w_other)
+                self = _small2long(space, self)
+                w_other = _small2long(space, w_other)
+                return long_op(self, space, w_other)
 
-        @func_renamer(descr_rname)
-        def descr_rbinop(self, space, w_other):
-            if isinstance(w_other, W_AbstractIntObject):
-                w_other = delegate_Int2SmallLong(space, w_other)
-            elif not isinstance(w_other, W_AbstractLongObject):
-                return space.w_NotImplemented
-            elif not isinstance(w_other, W_SmallLongObject):
-                self = delegate_SmallLong2Long(space, self)
-                return getattr(self, descr_rname)(space, w_other)
+        if opname in COMMUTATIVE_OPS:
+            descr_rbinop = func_with_new_name(descr_binop, descr_rname)
+        else:
+            long_rop = getattr(W_LongObject, descr_rname)
+            @func_renamer(descr_rname)
+            def descr_rbinop(self, space, w_other):
+                if isinstance(w_other, W_AbstractIntObject):
+                    w_other = _int2small(space, w_other)
+                elif not isinstance(w_other, W_AbstractLongObject):
+                    return space.w_NotImplemented
+                elif not isinstance(w_other, W_SmallLongObject):
+                    self = _small2long(space, self)
+                    return long_rop(self, space, w_other)
 
-            try:
-                return func(w_other, space, self)
-            except OverflowError:
-                self = delegate_SmallLong2Long(space, self)
-                w_other = delegate_SmallLong2Long(space, w_other)
-                return getattr(self, descr_rname)(space, w_other)
+                try:
+                    return func(w_other, space, self)
+                except OverflowError:
+                    self = _small2long(space, self)
+                    w_other = _small2long(space, w_other)
+                    return long_rop(self, space, w_other)
 
         return descr_binop, descr_rbinop
 
@@ -168,7 +242,7 @@
     def _mul(self, space, w_other):
         x = self.longlong
         y = w_other.longlong
-        z = llong_mul_ovf(x, y)
+        z = _llong_mul_ovf(x, y)
         return W_SmallLongObject(z)
     descr_mul, descr_rmul = _make_descr_binop(_mul)
 
@@ -216,57 +290,6 @@
         return space.newtuple([W_SmallLongObject(z), W_SmallLongObject(m)])
     descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
 
-    @unwrap_spec(w_modulus=WrappedDefault(None))
-    def descr_pow(self, space, w_exponent, w_modulus=None):
-        if isinstance(w_exponent, W_AbstractLongObject):
-            self = delegate_SmallLong2Long(space, self)
-            return self.descr_pow(space, w_exponent, w_modulus)
-        elif not isinstance(w_exponent, W_AbstractIntObject):
-            return space.w_NotImplemented
-
-        if space.is_none(w_modulus):
-            try:
-                return _pow_impl(space, self.longlong, w_exponent,
-                                 r_longlong(0))
-            except ValueError:
-                self = self.descr_float(space)
-                return space.pow(self, w_exponent, space.w_None)
-            except OverflowError:
-                self = delegate_SmallLong2Long(space, self)
-                return self.descr_pow(space, w_exponent, w_modulus)
-        elif isinstance(w_modulus, W_AbstractIntObject):
-            w_modulus = delegate_Int2SmallLong(space, w_modulus)
-        elif not isinstance(w_modulus, W_AbstractLongObject):
-            return space.w_NotImplemented
-        elif not isinstance(w_modulus, W_SmallLongObject):
-            self = delegate_SmallLong2Long(space, self)
-            return self.descr_pow(space, w_exponent, w_modulus)
-
-        z = w_modulus.longlong
-        if z == 0:
-            raise operationerrfmt(space.w_ValueError,
-                                  "pow() 3rd argument cannot be 0")
-        try:
-            return _pow_impl(space, self.longlong, w_exponent, z)
-        except ValueError:
-            self = self.descr_float(space)
-            return space.pow(self, w_exponent, w_modulus)
-        except OverflowError:
-            self = delegate_SmallLong2Long(space, self)
-            return self.descr_pow(space, w_exponent, w_modulus)
-
-    @unwrap_spec(w_modulus=WrappedDefault(None))
-    def descr_rpow(self, space, w_base, w_modulus=None):
-        if isinstance(w_base, W_AbstractIntObject):
-            # Defer to w_base<W_SmallLongObject>.descr_pow
-            # XXX: W_AbstractIntObject.descr_long could return
-            # SmallLongs then it could used instead of
-            # delegate_Int2SmallLong
-            w_base = delegate_Int2SmallLong(space, w_base)
-        elif not isinstance(w_base, W_AbstractLongObject):
-            return space.w_NotImplemented
-        return w_base.descr_pow(space, self, w_modulus)
-
     def _lshift(self, space, w_other):
         a = self.longlong
         # May overflow
@@ -322,32 +345,10 @@
         return W_SmallLongObject(res)
     descr_or, descr_ror = _make_descr_binop(_or)
 
-    def descr_neg(self, space):
-        a = self.longlong
-        try:
-            if a == r_longlong(-1 << (LONGLONG_BIT-1)):
-                raise OverflowError
-            x = -a
-        except OverflowError:
-            self = delegate_SmallLong2Long(space, self)
-            return self.descr_neg(space)
-        return W_SmallLongObject(x)
-
-    def descr_abs(self, space):
-        return self if self.longlong >= 0 else self.descr_neg(space)
-
-    def descr_nonzero(self, space):
-        return space.newbool(bool(self.longlong))
-
-    def descr_invert(self, space):
-        x = self.longlong
-        a = ~x
-        return W_SmallLongObject(a)
-
 
 # ____________________________________________________________
 
-def llong_mul_ovf(a, b):
+def _llong_mul_ovf(a, b):
     # xxx duplication of the logic from translator/c/src/int.h
     longprod = a * b
     doubleprod = float(a) * float(b)
@@ -373,18 +374,44 @@
 
 # ____________________________________________________________
 
-def delegate_Int2SmallLong(space, w_int):
-    return W_SmallLongObject(r_longlong(w_int.int_w(space)))
-
-def delegate_SmallLong2Long(space, w_small):
-    return W_LongObject(w_small.asbigint())
-
 def delegate_SmallLong2Float(space, w_small):
     return space.newfloat(float(w_small.longlong))
 
 def delegate_SmallLong2Complex(space, w_small):
     return space.newcomplex(float(w_small.longlong), 0.0)
 
+def _int2small(space, w_int):
+    # XXX: W_IntObject.descr_long should probably return W_SmallLongs
+    return W_SmallLongObject(r_longlong(w_int.int_w(space)))
+
+def _small2long(space, w_small):
+    return W_LongObject(w_small.asbigint())
+
+def _pow_impl(space, iv, w_int2, iz):
+    iw = space.int_w(w_int2)
+    if iw < 0:
+        if iz != 0:
+            raise operationerrfmt(space.w_TypeError,
+                                  "pow() 2nd argument cannot be negative when "
+                                  "3rd argument specified")
+        raise ValueError
+    temp = iv
+    ix = r_longlong(1)
+    while iw > 0:
+        if iw & 1:
+            ix = _llong_mul_ovf(ix, temp)
+        iw >>= 1   # Shift exponent down by 1 bit
+        if iw == 0:
+            break
+        temp = _llong_mul_ovf(temp, temp) # Square the value of temp
+        if iz:
+            # If we did a multiplication, perform a modulo
+            ix %= iz
+            temp %= iz
+    if iz:
+        ix %= iz
+    return W_SmallLongObject(ix)
+
 def add_ovr(space, w_int1, w_int2):
     x = r_longlong(space.int_w(w_int1))
     y = r_longlong(space.int_w(w_int2))
@@ -415,31 +442,6 @@
     return space.newtuple([div_ovr(space, w_int1, w_int2),
                            mod_ovr(space, w_int1, w_int2)])
 
-def _pow_impl(space, iv, w_int2, iz):
-    iw = space.int_w(w_int2)
-    if iw < 0:
-        if iz != 0:
-            raise operationerrfmt(space.w_TypeError,
-                                  "pow() 2nd argument cannot be negative when "
-                                  "3rd argument specified")
-        raise ValueError
-    temp = iv
-    ix = r_longlong(1)
-    while iw > 0:
-        if iw & 1:
-            ix = llong_mul_ovf(ix, temp)
-        iw >>= 1   # Shift exponent down by 1 bit
-        if iw == 0:
-            break
-        temp = llong_mul_ovf(temp, temp) # Square the value of temp
-        if iz:
-            # If we did a multiplication, perform a modulo
-            ix %= iz
-            temp %= iz
-    if iz:
-        ix %= iz
-    return W_SmallLongObject(ix)
-
 def pow_ovr(space, w_int1, w_int2):
     try:
         return _pow_impl(space, r_longlong(space.int_w(w_int1)), w_int2)
@@ -459,5 +461,5 @@
     return W_SmallLongObject(a)
 
 def lshift_ovr(space, w_int1, w_int2):
-    w_a = delegate_Int2SmallLong(space, w_int1)
+    w_a = _int2small(space, w_int1)
     return w_a.descr_lshift(space, w_int2)


More information about the pypy-commit mailing list