Commits

Philip Jenvey committed 9b4aa01 Merge

merge remove-intlong-smm, kills int/long/smalllong/bool multimethods

Comments (0)

Files changed (27)

pypy/config/pypyoption.py

         IntOption("methodcachesizeexp",
                   " 2 ** methodcachesizeexp is the size of the of the method cache ",
                   default=11),
-        BoolOption("optimized_int_add",
-                   "special case the addition of two integers in BINARY_ADD",
+        BoolOption("intshortcut",
+                   "special case addition and subtraction of two integers in BINARY_ADD/"
+                   "/BINARY_SUBTRACT and their inplace counterparts",
                    default=False),
         BoolOption("optimized_list_getitem",
                    "special case the 'list[integer]' expressions",
                    default=False),
         BoolOption("builtinshortcut",
-                   "a shortcut for operations between built-in types",
+                   "a shortcut for operations between built-in types. XXX: "
+                   "deprecated, not really a shortcut any more.",
                    default=False),
         BoolOption("getattributeshortcut",
                    "track types that override __getattribute__",
         config.objspace.std.suggest(withrangelist=True)
         config.objspace.std.suggest(withmethodcache=True)
         config.objspace.std.suggest(withprebuiltchar=True)
-        config.objspace.std.suggest(builtinshortcut=True)
+        config.objspace.std.suggest(intshortcut=True)
         config.objspace.std.suggest(optimized_list_getitem=True)
         config.objspace.std.suggest(getattributeshortcut=True)
         #config.objspace.std.suggest(newshortcut=True)

pypy/doc/config/objspace.std.intshortcut.txt

+Optimize the addition and subtraction of two integers. Enabling this
+option gives small speedups.

pypy/doc/config/objspace.std.optimized_int_add.txt

-Optimize the addition of two integers a bit. Enabling this option gives small
-speedups.

pypy/module/_csv/interp_reader.py

             try:
                 ff = string_to_float(field)
             except ParseStringError as e:
-                from pypy.objspace.std.inttype import wrap_parsestringerror
+                from pypy.objspace.std.intobject import wrap_parsestringerror
                 raise wrap_parsestringerror(space, e, space.wrap(field))
             w_obj = space.wrap(ff)
         else:

pypy/module/micronumpy/compile.py

 
     def is_true(self, w_obj):
         assert isinstance(w_obj, BoolObject)
-        return w_obj.boolval
+        return bool(w_obj.intval)
 
     def is_w(self, w_obj, w_what):
         return w_obj is w_what
 class BoolObject(W_Root):
     tp = FakeSpace.w_bool
     def __init__(self, boolval):
-        self.boolval = boolval
+        self.intval = boolval
 
 class IntObject(W_Root):
     tp = FakeSpace.w_int

pypy/module/micronumpy/interp_boxes.py

 from pypy.objspace.std.bytesobject import W_BytesObject
 from pypy.objspace.std.floattype import float_typedef
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
-from pypy.objspace.std.inttype import int_typedef
+from pypy.objspace.std.intobject import W_IntObject
 from pypy.objspace.std.complextype import complex_typedef
 from rpython.rlib.rarithmetic import LONG_BIT
 from rpython.rtyper.lltypesystem import rffi
 from pypy.module.micronumpy.constants import *
 
 
-MIXIN_32 = (int_typedef,) if LONG_BIT == 32 else ()
-MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else ()
+MIXIN_32 = (W_IntObject.typedef,) if LONG_BIT == 32 else ()
+MIXIN_64 = (W_IntObject.typedef,) if LONG_BIT == 64 else ()
 
 #long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True)
 #import os
 )
 
 W_LongBox.typedef = TypeDef("int%d" % LONG_BIT,
-    (W_SignedIntegerBox.typedef, int_typedef),
+    (W_SignedIntegerBox.typedef, W_IntObject.typedef),
     __module__ = "numpy",
     __new__ = interp2app(W_LongBox.descr__new__.im_func),
     __index__ = interp2app(W_LongBox.descr_index),

pypy/module/pypyjit/test/test_policy.py

 pypypolicy = policy.PyPyJitPolicy()
 
 def test_id_any():
-    from pypy.objspace.std.intobject import add__Int_Int
-    assert pypypolicy.look_inside_function(add__Int_Int)
+    from pypy.objspace.std.intobject import W_IntObject
+    assert pypypolicy.look_inside_function(W_IntObject.descr_add)
 
 def test_bigint():
     from rpython.rlib.rbigint import rbigint

pypy/objspace/std/boolobject.py

-from rpython.rlib.rbigint import rbigint
+"""The builtin bool implementation"""
+
+import operator
+
 from rpython.rlib.rarithmetic import r_uint
-from pypy.interpreter.error import OperationError
-from pypy.objspace.std import newformat
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.intobject import W_IntObject
+from rpython.tool.sourcetools import func_renamer, func_with_new_name
 
+from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
+from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject
+from pypy.objspace.std.stdtypedef import StdTypeDef
 
-class W_BoolObject(W_Object):
-    from pypy.objspace.std.booltype import bool_typedef as typedef
-    _immutable_fields_ = ['boolval']
+
+class W_BoolObject(W_IntObject):
 
     def __init__(self, boolval):
-        self.boolval = not not boolval
+        self.intval = not not boolval
 
     def __nonzero__(self):
         raise Exception("you cannot do that, you must use space.is_true()")
 
     def __repr__(self):
-        """ representation for debugging purposes """
-        return "%s(%s)" % (self.__class__.__name__, self.boolval)
+        """representation for debugging purposes"""
+        return "%s(%s)" % (self.__class__.__name__, bool(self.intval))
+
+    def is_w(self, space, w_other):
+        return self is w_other
+
+    def immutable_unique_id(self, space):
+        return None
 
     def unwrap(self, space):
-        return self.boolval
-
-    def int_w(self, space):
-        return int(self.boolval)
+        return bool(self.intval)
 
     def uint_w(self, space):
-        intval = int(self.boolval)
-        return r_uint(intval)
-
-    def bigint_w(self, space):
-        return rbigint.fromint(int(self.boolval))
-
-    def float_w(self, space):
-        return float(self.boolval)
+        return r_uint(self.intval)
 
     def int(self, space):
-        return space.newint(int(self.boolval))
+        return space.newint(self.intval)
 
-registerimplementation(W_BoolObject)
+    @staticmethod
+    @unwrap_spec(w_obj=WrappedDefault(False))
+    def descr_new(space, w_booltype, w_obj):
+        """T.__new__(S, ...) -> a new object with type S, a subtype of T"""
+        space.w_bool.check_user_subclass(w_booltype)
+        return space.newbool(space.is_true(w_obj))
+
+    def descr_repr(self, space):
+        return space.wrap('True' if self.intval else 'False')
+    descr_str = func_with_new_name(descr_repr, 'descr_str')
+
+    def descr_nonzero(self, space):
+        return self
+
+    def _make_bitwise_binop(opname):
+        descr_name = 'descr_' + opname
+        int_op = getattr(W_IntObject, descr_name)
+        op = getattr(operator,
+                     opname + '_' if opname in ('and', 'or') else opname)
+
+        @func_renamer(descr_name)
+        def descr_binop(self, space, w_other):
+            if not isinstance(w_other, W_BoolObject):
+                return int_op(self, space, w_other)
+            a = bool(self.intval)
+            b = bool(w_other.intval)
+            return space.newbool(op(a, b))
+
+        @func_renamer('descr_r' + opname)
+        def descr_rbinop(self, space, w_other):
+            return descr_binop(self, space, w_other)
+
+        return descr_binop, descr_rbinop
+
+    descr_and, descr_rand = _make_bitwise_binop('and')
+    descr_or, descr_ror = _make_bitwise_binop('or')
+    descr_xor, descr_rxor = _make_bitwise_binop('xor')
+
 
 W_BoolObject.w_False = W_BoolObject(False)
-W_BoolObject.w_True  = W_BoolObject(True)
+W_BoolObject.w_True = W_BoolObject(True)
 
-# bool-to-int delegation requires translating the .boolvar attribute
-# to an .intval one
-def delegate_Bool2IntObject(space, w_bool):
-    return W_IntObject(int(w_bool.boolval))
 
+W_BoolObject.typedef = StdTypeDef("bool", W_IntObject.typedef,
+    __doc__ = """bool(x) -> bool
 
-def nonzero__Bool(space, w_bool):
-    return w_bool
+Returns True when the argument x is true, False otherwise.
+The builtins True and False are the only two instances of the class bool.
+The class bool is a subclass of the class int, and cannot be subclassed.""",
+    __new__ = interp2app(W_BoolObject.descr_new),
+    __repr__ = interp2app(W_BoolObject.descr_repr,
+                          doc=W_AbstractIntObject.descr_repr.__doc__),
+    __str__ = interp2app(W_BoolObject.descr_str,
+                         doc=W_AbstractIntObject.descr_str.__doc__),
+    __nonzero__ = interp2app(W_BoolObject.descr_nonzero,
+                             doc=W_AbstractIntObject.descr_nonzero.__doc__),
 
-def repr__Bool(space, w_bool):
-    if w_bool.boolval:
-        return space.wrap('True')
-    else:
-        return space.wrap('False')
-
-def and__Bool_Bool(space, w_bool1, w_bool2):
-    return space.newbool(w_bool1.boolval & w_bool2.boolval)
-
-def or__Bool_Bool(space, w_bool1, w_bool2):
-    return space.newbool(w_bool1.boolval | w_bool2.boolval)
-
-def xor__Bool_Bool(space, w_bool1, w_bool2):
-    return space.newbool(w_bool1.boolval ^ w_bool2.boolval)
-
-str__Bool = repr__Bool
-
-def format__Bool_ANY(space, w_bool, w_format_spec):
-    return newformat.run_formatter(
-            space, w_format_spec, "format_int_or_long", w_bool,
-            newformat.INT_KIND)
-
-register_all(vars())
+    __and__ = interp2app(W_BoolObject.descr_and,
+                         doc=W_AbstractIntObject.descr_and.__doc__),
+    __rand__ = interp2app(W_BoolObject.descr_rand,
+                          doc=W_AbstractIntObject.descr_rand.__doc__),
+    __or__ = interp2app(W_BoolObject.descr_or,
+                        doc=W_AbstractIntObject.descr_or.__doc__),
+    __ror__ = interp2app(W_BoolObject.descr_ror,
+                         doc=W_AbstractIntObject.descr_ror.__doc__),
+    __xor__ = interp2app(W_BoolObject.descr_xor,
+                         doc=W_AbstractIntObject.descr_xor.__doc__),
+    __rxor__ = interp2app(W_BoolObject.descr_rxor,
+                          doc=W_AbstractIntObject.descr_rxor.__doc__),
+    )
+W_BoolObject.typedef.acceptable_as_base_class = False

pypy/objspace/std/booltype.py

-from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from pypy.objspace.std.stdtypedef import StdTypeDef
-from pypy.objspace.std.inttype import int_typedef
-
-@unwrap_spec(w_obj = WrappedDefault(False))
-def descr__new__(space, w_booltype, w_obj):
-    space.w_bool.check_user_subclass(w_booltype)
-    if space.is_true(w_obj):
-        return space.w_True
-    else:
-        return space.w_False
-
-# ____________________________________________________________
-
-bool_typedef = StdTypeDef("bool", int_typedef,
-    __doc__ = '''bool(x) -> bool
-
-Returns True when the argument x is true, False otherwise.
-The builtins True and False are the only two instances of the class bool.
-The class bool is a subclass of the class int, and cannot be subclassed.''',
-    __new__ = interp2app(descr__new__),
-    )
-bool_typedef.acceptable_as_base_class = False

pypy/objspace/std/builtinshortcut.py

             # always directly return a Bool; however, the __len__ method
             # of built-in objects typically returns an unwrappable integer
             if isinstance(w_res, W_BoolObject):
-                return w_res.boolval
+                return bool(w_res.intval)
             try:
                 return space.int_w(w_res) != 0
             except OperationError:

pypy/objspace/std/complexobject.py

 from pypy.interpreter import gateway
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std import newformat
+from pypy.objspace.std.intobject import W_IntObject
 from pypy.objspace.std.model import registerimplementation, W_Object
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.floatobject import W_FloatObject, _hash_float
 
 
 def delegate_Bool2Complex(space, w_bool):
-    return W_ComplexObject(w_bool.boolval, 0.0)
+    return W_ComplexObject(w_bool.intval, 0.0)
 
 def delegate_Int2Complex(space, w_int):
     return W_ComplexObject(w_int.intval, 0.0)
     if w_complex1.imagval:
         return space.w_False
     return space.eq(space.newfloat(w_complex1.realval), w_long2)
+eq__Complex_Int = eq__Complex_Long
 
 def eq__Long_Complex(space, w_long1, w_complex2):
     return eq__Complex_Long(space, w_complex2, w_long1)
+eq__Int_Complex = eq__Long_Complex
 
 def ne__Complex_Long(space, w_complex1, w_long2):
     if w_complex1.imagval:
         return space.w_True
     return space.ne(space.newfloat(w_complex1.realval), w_long2)
+ne__Complex_Int = ne__Complex_Long
 
 def ne__Long_Complex(space, w_long1, w_complex2):
     return ne__Complex_Long(space, w_complex2, w_long1)
+ne__Int_Complex = ne__Long_Complex
 
 def lt__Complex_Complex(space, w_complex1, w_complex2):
     raise OperationError(space.w_TypeError, space.wrap('cannot compare complex numbers using <, <=, >, >='))

pypy/objspace/std/floatobject.py

 
 # bool-to-float delegation
 def delegate_Bool2Float(space, w_bool):
-    return W_FloatObject(float(w_bool.boolval))
+    return W_FloatObject(float(w_bool.intval))
 
 # int-to-float delegation
 def delegate_Int2Float(space, w_intobj):
 
 from pypy.objspace.std import floattype
 register_all(vars(), floattype)
-
-# pow delegation for negative 2nd arg
-def pow_neg__Long_Long_None(space, w_int1, w_int2, thirdarg):
-    w_float1 = delegate_Long2Float(space, w_int1)
-    w_float2 = delegate_Long2Float(space, w_int2)
-    return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg)
-
-model.MM.pow.register(pow_neg__Long_Long_None, W_LongObject, W_LongObject,
-                      W_NoneObject, order=1)
-
-def pow_neg__Int_Int_None(space, w_int1, w_int2, thirdarg):
-    w_float1 = delegate_Int2Float(space, w_int1)
-    w_float2 = delegate_Int2Float(space, w_int2)
-    return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg)
-
-model.MM.pow.register(pow_neg__Int_Int_None, W_IntObject, W_IntObject,
-                      W_NoneObject, order=2)

pypy/objspace/std/floattype.py

     try:
         return rfloat.string_to_float(string)
     except ParseStringError as e:
-        from pypy.objspace.std.inttype import wrap_parsestringerror
+        from pypy.objspace.std.intobject import wrap_parsestringerror
         raise wrap_parsestringerror(space, e, w_source)
 
 

pypy/objspace/std/frame.py

 
 import operator
 
-from rpython.rlib.unroll import unrolling_iterable
-from pypy.interpreter import pyopcode
+from rpython.rlib.rarithmetic import ovfcheck
+from rpython.tool.sourcetools import func_renamer
+
 from pypy.interpreter.pyframe import PyFrame
-from pypy.interpreter.error import OperationError
-from pypy.objspace.std import intobject
-from pypy.objspace.std.multimethod import FailedToImplement
+from pypy.interpreter.error import oefmt
+from pypy.objspace.std.intobject import W_IntObject
 from pypy.objspace.std.listobject import W_ListObject
 
 
 class BaseFrame(PyFrame):
     """These opcodes are always overridden."""
 
-    def LIST_APPEND(f, oparg, next_instr):
-        w = f.popvalue()
-        v = f.peekvalue(oparg - 1)
+    def LIST_APPEND(self, oparg, next_instr):
+        w = self.popvalue()
+        v = self.peekvalue(oparg - 1)
         if type(v) is W_ListObject:
             v.append(w)
         else:
             raise AssertionError
 
 
-def int_BINARY_ADD(f, oparg, next_instr):
-    w_2 = f.popvalue()
-    w_1 = f.popvalue()
-    if (type(w_1) is intobject.W_IntObject and
-        type(w_2) is intobject.W_IntObject):
-        try:
-            w_result = intobject.add__Int_Int(f.space, w_1, w_2)
-        except FailedToImplement:
-            w_result = f.space.add(w_1, w_2)
+def _intshortcut(spaceopname):
+    if spaceopname.startswith('inplace_'):
+        opname = spaceopname[len('inplace_'):]
+        funcprefix = 'int_'
     else:
-        w_result = f.space.add(w_1, w_2)
-    f.pushvalue(w_result)
+        opname = spaceopname
+        funcprefix = 'int_BINARY_'
+    op = getattr(operator, opname)
+    int_op = getattr(W_IntObject, 'descr_' + opname)
 
+    @func_renamer(funcprefix + spaceopname.upper())
+    def opimpl(self, oparg, next_instr):
+        space = self.space
+        space_op = getattr(space, spaceopname)
 
-def list_BINARY_SUBSCR(f, oparg, next_instr):
-    w_2 = f.popvalue()
-    w_1 = f.popvalue()
-    if type(w_1) is W_ListObject and type(w_2) is intobject.W_IntObject:
+        w_2 = self.popvalue()
+        w_1 = self.popvalue()
+        if type(w_1) is W_IntObject and type(w_2) is W_IntObject:
+            try:
+                z = ovfcheck(op(w_1.intval, w_2.intval))
+            except OverflowError:
+                w_result = int_op(w_1, space, w_2)
+            else:
+                w_result = space.newint(z)
+        else:
+            w_result = space_op(w_1, w_2)
+        self.pushvalue(w_result)
+
+    return opimpl
+
+
+int_BINARY_ADD = _intshortcut('add')
+int_INPLACE_ADD = _intshortcut('inplace_add')
+int_BINARY_SUBTRACT = _intshortcut('sub')
+int_INPLACE_SUBTRACT = _intshortcut('inplace_sub')
+
+
+def list_BINARY_SUBSCR(self, oparg, next_instr):
+    space = self.space
+    w_2 = self.popvalue()
+    w_1 = self.popvalue()
+    if type(w_1) is W_ListObject and type(w_2) is W_IntObject:
         try:
             w_result = w_1.getitem(w_2.intval)
         except IndexError:
-            raise OperationError(f.space.w_IndexError,
-                f.space.wrap("list index out of range"))
+            raise oefmt(space.w_IndexError, "list index out of range")
     else:
-        w_result = f.space.getitem(w_1, w_2)
-    f.pushvalue(w_result)
+        w_result = space.getitem(w_1, w_2)
+    self.pushvalue(w_result)
 
 
 def build_frame(space):
     """Consider the objspace config and return a patched frame object."""
     class StdObjSpaceFrame(BaseFrame):
         pass
-    if space.config.objspace.std.optimized_int_add:
+    if space.config.objspace.std.intshortcut:
         StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD
+        StdObjSpaceFrame.INPLACE_ADD = int_INPLACE_ADD
+        StdObjSpaceFrame.BINARY_SUBTRACT = int_BINARY_SUBTRACT
+        StdObjSpaceFrame.INPLACE_SUBTRACT = int_INPLACE_SUBTRACT
     if space.config.objspace.std.optimized_list_getitem:
         StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR
     from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD

pypy/objspace/std/intobject.py

 for overflows, something CPython does not do anymore.
 """
 
+import operator
+import sys
+
 from rpython.rlib import jit
-from rpython.rlib.rarithmetic import LONG_BIT, is_valid_int, ovfcheck, r_uint
+from rpython.rlib.objectmodel import instantiate, import_from_mixin, specialize
+from rpython.rlib.rarithmetic import (
+    LONG_BIT, is_valid_int, ovfcheck, r_longlong, r_uint, string_to_int)
 from rpython.rlib.rbigint import rbigint
+from rpython.rlib.rstring import (
+    InvalidBaseError, ParseStringError, ParseStringOverflowError)
+from rpython.tool.sourcetools import func_renamer, func_with_new_name
 
-from pypy.interpreter.error import OperationError
+from pypy.interpreter import typedef
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.buffer import Buffer
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
 from pypy.objspace.std import newformat
-from pypy.objspace.std.inttype import W_AbstractIntObject
-from pypy.objspace.std.model import W_Object, registerimplementation
-from pypy.objspace.std.multimethod import FailedToImplementArgs
-from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.model import (
+    BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_INT)
+from pypy.objspace.std.stdtypedef import StdTypeDef
+
+
+SENTINEL = object()
+
+
+class W_AbstractIntObject(W_Root):
+
+    __slots__ = ()
+
+    def is_w(self, space, w_other):
+        from pypy.objspace.std.boolobject import W_BoolObject
+        if (not isinstance(w_other, W_AbstractIntObject) or
+            isinstance(w_other, W_BoolObject)):
+            return False
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return self is w_other
+        return space.int_w(self) == space.int_w(w_other)
+
+    def immutable_unique_id(self, space):
+        if self.user_overridden_class:
+            return None
+        b = space.bigint_w(self)
+        b = b.lshift(3).or_(rbigint.fromint(IDTAG_INT))
+        return space.newlong_from_rbigint(b)
+
+    def int(self, space):
+        """x.__int__() <==> int(x)"""
+        raise NotImplementedError
+
+    def descr_format(self, space, w_format_spec):
+        raise NotImplementedError
+
+    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=SENTINEL):
+        if doc is SENTINEL:
+            doc = 'x.__%s__() <==> %s(x)' % (opname, opname)
+        @func_renamer('descr_' + opname)
+        def descr_unaryop(self, space):
+            raise NotImplementedError
+        descr_unaryop.__doc__ = doc
+        return descr_unaryop
+
+    descr_repr = _abstract_unaryop('repr')
+    descr_str = _abstract_unaryop('str')
+
+    descr_coerce = _abstract_unaryop('coerce')
+    descr_conjugate = _abstract_unaryop(
+        'conjugate', "Returns self, the complex conjugate of any int.")
+    descr_bit_length = _abstract_unaryop('bit_length', """\
+        int.bit_length() -> int
+
+        Number of bits necessary to represent self in binary.
+        >>> bin(37)
+        '0b100101'
+        >>> (37).bit_length()
+        6""")
+    descr_hash = _abstract_unaryop('hash')
+    descr_oct = _abstract_unaryop('oct')
+    descr_hex = _abstract_unaryop('hex')
+    descr_getnewargs = _abstract_unaryop('getnewargs', None)
+
+    descr_long = _abstract_unaryop('long')
+    descr_index = _abstract_unaryop(
+        'index', "x[y:z] <==> x[y.__index__():z.__index__()]")
+    descr_trunc = _abstract_unaryop('trunc',
+                                    "Truncating an Integral returns itself.")
+    descr_float = _abstract_unaryop('float')
+
+    descr_pos = _abstract_unaryop('pos', "x.__pos__() <==> +x")
+    descr_neg = _abstract_unaryop('neg', "x.__neg__() <==> -x")
+    descr_abs = _abstract_unaryop('abs')
+    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_truediv, descr_rtruediv = _abstract_binop('truediv')
+    descr_mod, descr_rmod = _abstract_binop('mod')
+    descr_divmod, descr_rdivmod = _abstract_binop('divmod')
+
+
+def _floordiv(space, x, y):
+    try:
+        z = ovfcheck(x // y)
+    except ZeroDivisionError:
+        raise oefmt(space.w_ZeroDivisionError, "integer division by zero")
+    return wrapint(space, z)
+_div = func_with_new_name(_floordiv, '_div')
+
+
+def _truediv(space, x, y):
+    a = float(x)
+    b = float(y)
+    if b == 0.0:
+        raise oefmt(space.w_ZeroDivisionError, "division by zero")
+    return space.wrap(a / b)
+
+
+def _mod(space, x, y):
+    try:
+        z = ovfcheck(x % y)
+    except ZeroDivisionError:
+        raise oefmt(space.w_ZeroDivisionError, "integer modulo by zero")
+    return wrapint(space, z)
+
+
+def _divmod(space, x, y):
+    try:
+        z = ovfcheck(x // y)
+    except ZeroDivisionError:
+        raise oefmt(space.w_ZeroDivisionError, "integer divmod by zero")
+    # no overflow possible
+    m = x % y
+    w = space.wrap
+    return space.newtuple([w(z), w(m)])
+
+
+def _divmod_ovf2small(space, x, y):
+    from pypy.objspace.std.smalllongobject import W_SmallLongObject
+    a = r_longlong(x)
+    b = r_longlong(y)
+    return space.newtuple([W_SmallLongObject(a // b),
+                           W_SmallLongObject(a % b)])
+
+
+def _lshift(space, a, b):
+    if r_uint(b) < LONG_BIT: # 0 <= b < LONG_BIT
+        c = ovfcheck(a << b)
+        return wrapint(space, c)
+    if b < 0:
+        raise oefmt(space.w_ValueError, "negative shift count")
+    # b >= LONG_BIT
+    if a == 0:
+        return wrapint(space, a)
+    raise OverflowError
+
+
+def _lshift_ovf2small(space, a, b):
+    from pypy.objspace.std.smalllongobject import W_SmallLongObject
+    w_a = W_SmallLongObject.fromint(a)
+    w_b = W_SmallLongObject.fromint(b)
+    return w_a.descr_lshift(space, w_b)
+
+
+def _rshift(space, a, b):
+    if r_uint(b) >= LONG_BIT: # not (0 <= b < LONG_BIT)
+        if b < 0:
+            raise oefmt(space.w_ValueError, "negative shift count")
+        # b >= LONG_BIT
+        if a == 0:
+            return wrapint(space, a)
+        a = -1 if a < 0 else 0
+    else:
+        a = a >> b
+    return wrapint(space, a)
+
+
+@jit.look_inside_iff(lambda space, iv, iw, iz:
+                     jit.isconstant(iw) and jit.isconstant(iz))
+def _pow(space, iv, iw, iz):
+    """Helper for pow"""
+    if iw < 0:
+        if iz != 0:
+            raise oefmt(space.w_TypeError,
+                        "pow() 2nd argument cannot be negative when 3rd "
+                        "argument specified")
+        # bounce it, since it always returns float
+        raise ValueError
+    temp = iv
+    ix = 1
+    while iw > 0:
+        if iw & 1:
+            ix = ovfcheck(ix * temp)
+        iw >>= 1   # Shift exponent down by 1 bit
+        if iw == 0:
+            break
+        temp = ovfcheck(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 ix
+
+
+def _pow_ovf2long(space, iv, iw, w_modulus):
+    if space.is_none(w_modulus) and _recover_with_smalllong(space):
+        from pypy.objspace.std.smalllongobject import _pow as _pow_small
+        try:
+            # XXX: shouldn't have to pass r_longlong(0) here (see
+            # 4fa4c6b93a84)
+            return _pow_small(space, r_longlong(iv), iw, r_longlong(0))
+        except (OverflowError, ValueError):
+            pass
+    from pypy.objspace.std.longobject import W_LongObject
+    w_iv = W_LongObject.fromint(space, iv)
+    w_iw = W_LongObject.fromint(space, iw)
+    return w_iv.descr_pow(space, w_iw, w_modulus)
+
+
+def _make_ovf2long(opname, ovf2small=None):
+    op = getattr(operator, opname, None)
+    assert op or ovf2small
+
+    def ovf2long(space, x, y):
+        """Handle overflowing to smalllong or long"""
+        if _recover_with_smalllong(space):
+            if ovf2small:
+                return ovf2small(space, x, y)
+            # Assume a generic operation without an explicit ovf2small
+            # handler
+            from pypy.objspace.std.smalllongobject import W_SmallLongObject
+            a = r_longlong(x)
+            b = r_longlong(y)
+            return W_SmallLongObject(op(a, b))
+
+        from pypy.objspace.std.longobject import W_LongObject
+        w_x = W_LongObject.fromint(space, x)
+        w_y = W_LongObject.fromint(space, y)
+        return getattr(w_x, 'descr_' + opname)(space, w_y)
+
+    return ovf2long
 
 
 class W_IntObject(W_AbstractIntObject):
+
     __slots__ = 'intval'
     _immutable_fields_ = ['intval']
 
-    from pypy.objspace.std.inttype import int_typedef as typedef
-
     def __init__(self, intval):
         assert is_valid_int(intval)
         self.intval = intval
         """representation for debugging purposes"""
         return "%s(%d)" % (self.__class__.__name__, self.intval)
 
-    def unwrap(self, space):
+    def int_w(self, space):
         return int(self.intval)
-    int_w = unwrap
+    unwrap = int_w
 
     def uint_w(self, space):
         intval = self.intval
         if intval < 0:
-            raise OperationError(
-                space.w_ValueError,
-                space.wrap("cannot convert negative integer to unsigned"))
-        else:
-            return r_uint(intval)
+            raise oefmt(space.w_ValueError,
+                        "cannot convert negative integer to unsigned")
+        return r_uint(intval)
 
     def bigint_w(self, space):
         return rbigint.fromint(self.intval)
         return float(self.intval)
 
     def int(self, space):
-        if (type(self) is not W_IntObject and
-            space.is_overloaded(self, space.w_int, '__int__')):
-            return W_Object.int(self, space)
-        if space.is_w(space.type(self), space.w_int):
+        if type(self) is W_IntObject:
             return self
+        if not space.is_overloaded(self, space.w_int, '__int__'):
+            return space.newint(self.intval)
+        return W_Root.int(self, space)
+
+    @staticmethod
+    @unwrap_spec(w_x=WrappedDefault(0))
+    def descr_new(space, w_inttype, w_x, w_base=None):
+        """T.__new__(S, ...) -> a new object with type S, a subtype of T"""
+        return _new_int(space, w_inttype, w_x, w_base)
+
+    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 _int(self, space):
+        return self.int(space)
+
+    descr_pos = func_with_new_name(_int, 'descr_pos')
+    descr_index = func_with_new_name(_int, 'descr_index')
+    descr_trunc = func_with_new_name(_int, 'descr_trunc')
+    descr_conjugate = func_with_new_name(_int, 'descr_conjugate')
+
+    descr_get_numerator = func_with_new_name(_int, 'descr_get_numerator')
+    descr_get_real = func_with_new_name(_int, 'descr_get_real')
+
+    def descr_get_denominator(self, space):
+        return wrapint(space, 1)
+
+    def descr_get_imag(self, space):
+        return wrapint(space, 0)
+
+    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):
+        # XXX: should try smalllong
+        from pypy.objspace.std.longobject import W_LongObject
+        return W_LongObject.fromint(space, self.intval)
+
+    def descr_nonzero(self, space):
+        return space.newbool(self.intval != 0)
+
+    def descr_invert(self, space):
+        return wrapint(space, ~self.intval)
+
+    def descr_neg(self, space):
         a = self.intval
-        return space.newint(a)
+        try:
+            b = ovfcheck(-a)
+        except OverflowError:
+            if _recover_with_smalllong(space):
+                from pypy.objspace.std.smalllongobject import W_SmallLongObject
+                x = r_longlong(a)
+                return W_SmallLongObject(-x)
+            return self.descr_long(space).descr_neg(space)
+        return wrapint(space, b)
 
-registerimplementation(W_IntObject)
+    def descr_abs(self, space):
+        pos = self.intval >= 0
+        return self.int(space) if pos else self.descr_neg(space)
 
-def repr__Int(space, w_int1):
-    a = w_int1.intval
-    res = str(a)
-    return space.wrap(res)
+    def descr_float(self, space):
+        a = self.intval
+        x = float(a)
+        return space.newfloat(x)
 
-str__Int = repr__Int
+    def descr_oct(self, space):
+        return space.wrap(oct(self.intval))
 
-def format__Int_ANY(space, w_int, w_format_spec):
-    return newformat.run_formatter(space, w_format_spec, "format_int_or_long",
-                                   w_int, newformat.INT_KIND)
+    def descr_hex(self, space):
+        return space.wrap(hex(self.intval))
 
-def declare_new_int_comparison(opname):
-    import operator
-    from rpython.tool.sourcetools import func_with_new_name
-    op = getattr(operator, opname)
-    def f(space, w_int1, w_int2):
-        i = w_int1.intval
-        j = w_int2.intval
-        return space.newbool(op(i, j))
-    name = "%s__Int_Int" % (opname,)
-    return func_with_new_name(f, name), name
+    def descr_getnewargs(self, space):
+        return space.newtuple([wrapint(space, self.intval)])
 
-for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']:
-    func, name = declare_new_int_comparison(op)
-    globals()[name] = func
+    def descr_bit_length(self, space):
+        val = self.intval
+        if val < 0:
+            val = -val
+        bits = 0
+        while val:
+            bits += 1
+            val >>= 1
+        return space.wrap(bits)
 
-def hash__Int(space, w_int1):
-    # 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 w_int1.int(space)
+    def descr_repr(self, space):
+        res = str(self.intval)
+        return space.wrap(res)
+    descr_str = func_with_new_name(descr_repr, 'descr_str')
 
-# coerce
-def coerce__Int_Int(space, w_int1, w_int2):
-    return space.newtuple([w_int1, w_int2])
+    def descr_format(self, space, w_format_spec):
+        return newformat.run_formatter(space, w_format_spec,
+                                       "format_int_or_long", self,
+                                       newformat.INT_KIND)
 
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_pow(self, space, w_exponent, w_modulus=None):
+        if not isinstance(w_exponent, W_IntObject):
+            return space.w_NotImplemented
 
-def add__Int_Int(space, w_int1, w_int2):
-    x = w_int1.intval
-    y = w_int2.intval
+        x = self.intval
+        y = w_exponent.intval
+
+        if space.is_none(w_modulus):
+            z = 0
+        elif isinstance(w_modulus, W_IntObject):
+            z = w_modulus.intval
+            if z == 0:
+                raise oefmt(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 _pow_ovf2long(space, x, y, w_modulus)
+
+        try:
+            result = _pow(space, x, y, z)
+        except (OverflowError, ValueError):
+            return _pow_ovf2long(space, x, y, 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_IntObject):
+            return space.w_NotImplemented
+        return w_base.descr_pow(space, self, w_modulus)
+
+    def _make_descr_cmp(opname):
+        op = getattr(operator, opname)
+        @func_renamer('descr_' + opname)
+        def descr_cmp(self, space, w_other):
+            if not isinstance(w_other, W_IntObject):
+                return space.w_NotImplemented
+            i = self.intval
+            j = w_other.intval
+            return space.newbool(op(i, j))
+        return descr_cmp
+
+    descr_lt = _make_descr_cmp('lt')
+    descr_le = _make_descr_cmp('le')
+    descr_eq = _make_descr_cmp('eq')
+    descr_ne = _make_descr_cmp('ne')
+    descr_gt = _make_descr_cmp('gt')
+    descr_ge = _make_descr_cmp('ge')
+
+    def _make_generic_descr_binop(opname, ovf=True):
+        op = getattr(operator,
+                     opname + '_' if opname in ('and', 'or') else opname)
+        descr_rname = 'descr_r' + opname
+        if ovf:
+            ovf2long = _make_ovf2long(opname)
+
+        @func_renamer('descr_' + opname)
+        def descr_binop(self, space, w_other):
+            if not isinstance(w_other, W_IntObject):
+                return space.w_NotImplemented
+
+            x = self.intval
+            y = w_other.intval
+            if ovf:
+                try:
+                    z = ovfcheck(op(x, y))
+                except OverflowError:
+                    return ovf2long(space, x, y)
+            else:
+                z = op(x, y)
+            return wrapint(space, z)
+
+        if opname in COMMUTATIVE_OPS:
+            @func_renamer(descr_rname)
+            def descr_rbinop(self, space, w_other):
+                return descr_binop(self, space, w_other)
+            return descr_binop, descr_rbinop
+
+        @func_renamer(descr_rname)
+        def descr_rbinop(self, space, w_other):
+            if not isinstance(w_other, W_IntObject):
+                return space.w_NotImplemented
+
+            x = self.intval
+            y = w_other.intval
+            if ovf:
+                try:
+                    z = ovfcheck(op(y, x))
+                except OverflowError:
+                    return ovf2long(space, y, x)
+            else:
+                z = op(y, x)
+            return wrapint(space, z)
+
+        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, ovf=True, ovf2small=None):
+        opname = func.__name__[1:]
+        if ovf:
+            ovf2long = _make_ovf2long(opname, ovf2small)
+
+        @func_renamer('descr_' + opname)
+        def descr_binop(self, space, w_other):
+            if not isinstance(w_other, W_IntObject):
+                return space.w_NotImplemented
+
+            x = self.intval
+            y = w_other.intval
+            if ovf:
+                try:
+                    return func(space, x, y)
+                except OverflowError:
+                    return ovf2long(space, x, y)
+            else:
+                return func(space, x, y)
+
+        @func_renamer('descr_r' + opname)
+        def descr_rbinop(self, space, w_other):
+            if not isinstance(w_other, W_IntObject):
+                return space.w_NotImplemented
+
+            x = self.intval
+            y = w_other.intval
+            if ovf:
+                try:
+                    return func(space, y, x)
+                except OverflowError:
+                    return ovf2long(space, y, x)
+            else:
+                return func(space, y, x)
+
+        return descr_binop, descr_rbinop
+
+    descr_lshift, descr_rlshift = _make_descr_binop(
+        _lshift, ovf2small=_lshift_ovf2small)
+    descr_rshift, descr_rrshift = _make_descr_binop(_rshift, ovf=False)
+
+    descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv)
+    descr_div, descr_rdiv = _make_descr_binop(_div)
+    descr_truediv, descr_rtruediv = _make_descr_binop(_truediv, ovf=False)
+    descr_mod, descr_rmod = _make_descr_binop(_mod)
+    descr_divmod, descr_rdivmod = _make_descr_binop(
+        _divmod, ovf2small=_divmod_ovf2small)
+
+
+def wrapint(space, x):
+    if not space.config.objspace.std.withprebuiltint:
+        return W_IntObject(x)
+    lower = space.config.objspace.std.prebuiltintfrom
+    upper = space.config.objspace.std.prebuiltintto
+    # use r_uint to perform a single comparison (this whole function is
+    # getting inlined into every caller so keeping the branching to a
+    # minimum is a good idea)
+    index = r_uint(x - lower)
+    if index >= r_uint(upper - lower):
+        w_res = instantiate(W_IntObject)
+    else:
+        w_res = W_IntObject.PREBUILT[index]
+    # obscure hack to help the CPU cache: we store 'x' even into a
+    # prebuilt integer's intval.  This makes sure that the intval field
+    # is present in the cache in the common case where it is quickly
+    # reused.  (we could use a prefetch hint if we had that)
+    w_res.intval = x
+    return w_res
+
+
+def wrap_parsestringerror(space, e, w_source):
+    if isinstance(e, InvalidBaseError):
+        w_msg = space.wrap(e.msg)
+    else:
+        w_msg = space.wrap('%s: %s' % (e.msg,
+                                       space.str_w(space.repr(w_source))))
+    return OperationError(space.w_ValueError, w_msg)
+
+
+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
+            sys.maxint == 2147483647)
+
+
+@jit.elidable
+def _string_to_int_or_long(space, w_source, string, base=10):
+    w_longval = None
+    value = 0
     try:
-        z = ovfcheck(x + y)
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer addition"))
-    return space.newint(z)
+        value = string_to_int(string, base)
+    except ParseStringError as e:
+        raise wrap_parsestringerror(space, e, w_source)
+    except ParseStringOverflowError as e:
+        w_longval = _retry_to_w_long(space, e.parser, w_source)
+    return value, w_longval
 
-def sub__Int_Int(space, w_int1, w_int2):
-    x = w_int1.intval
-    y = w_int2.intval
+
+def _retry_to_w_long(space, parser, w_source):
+    parser.rewind()
     try:
-        z = ovfcheck(x - y)
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer substraction"))
-    return space.newint(z)
+        bigint = rbigint._from_numberstring_parser(parser)
+    except ParseStringError as e:
+        raise wrap_parsestringerror(space, e, w_source)
+    return space.newlong_from_rbigint(bigint)
 
-def mul__Int_Int(space, w_int1, w_int2):
-    x = w_int1.intval
-    y = w_int2.intval
-    try:
-        z = ovfcheck(x * y)
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer multiplication"))
-    return space.newint(z)
 
-def floordiv__Int_Int(space, w_int1, w_int2):
-    x = w_int1.intval
-    y = w_int2.intval
-    try:
-        z = ovfcheck(x // y)
-    except ZeroDivisionError:
-        raise OperationError(space.w_ZeroDivisionError,
-                             space.wrap("integer division by zero"))
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer division"))
-    return space.newint(z)
-div__Int_Int = floordiv__Int_Int
+def _new_int(space, w_inttype, w_x, w_base=None):
+    w_longval = None
+    w_value = w_x     # 'x' is the keyword argument name in CPython
+    value = 0
+    if w_base is None:
+        # check for easy cases
+        if type(w_value) is W_IntObject:
+            value = w_value.intval
+        elif (space.lookup(w_value, '__int__') is not None or
+              space.lookup(w_value, '__trunc__') is not None):
+            # otherwise, use the __int__() or the __trunc__() methods
+            w_obj = w_value
+            if space.lookup(w_obj, '__int__') is None:
+                w_obj = space.trunc(w_obj)
+            w_obj = space.int(w_obj)
+            # 'int(x)' should return what x.__int__() returned, which should
+            # be an int or long or a subclass thereof.
+            if space.is_w(w_inttype, space.w_int):
+                return w_obj
+            # int_w is effectively what we want in this case,
+            # we cannot construct a subclass of int instance with an
+            # 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, w_value,
+                                                      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, w_value, string)
+        else:
+            # If object supports the buffer interface
+            try:
+                w_buffer = space.buffer(w_value)
+            except OperationError as e:
+                if not e.match(space, space.w_TypeError):
+                    raise
+                raise oefmt(space.w_TypeError,
+                            "int() argument must be a string or a number, "
+                            "not '%T'", w_value)
+            else:
+                buf = space.interp_w(Buffer, w_buffer)
+                value, w_longval = _string_to_int_or_long(space, w_value,
+                                                          buf.as_str())
+                ok = True
+    else:
+        base = space.int_w(w_base)
 
-def truediv__Int_Int(space, w_int1, w_int2):
-    x = float(w_int1.intval)
-    y = float(w_int2.intval)
-    if y == 0.0:
-        raise FailedToImplementArgs(space.w_ZeroDivisionError,
-                                    space.wrap("float division"))
-    return space.wrap(x / y)
+        if space.isinstance_w(w_value, space.w_unicode):
+            from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
+            s = unicode_to_decimal_w(space, w_value)
+        else:
+            try:
+                s = space.str_w(w_value)
+            except OperationError as e:
+                raise oefmt(space.w_TypeError,
+                            "int() can't convert non-string with explicit "
+                            "base")
 
-def mod__Int_Int(space, w_int1, w_int2):
-    x = w_int1.intval
-    y = w_int2.intval
-    try:
-        z = ovfcheck(x % y)
-    except ZeroDivisionError:
-        raise OperationError(space.w_ZeroDivisionError,
-                             space.wrap("integer modulo by zero"))
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer modulo"))
-    return space.newint(z)
+        value, w_longval = _string_to_int_or_long(space, w_value, s, base)
 
-def divmod__Int_Int(space, w_int1, w_int2):
-    x = w_int1.intval
-    y = w_int2.intval
-    try:
-        z = ovfcheck(x // y)
-    except ZeroDivisionError:
-        raise OperationError(space.w_ZeroDivisionError,
-                             space.wrap("integer divmod by zero"))
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer modulo"))
-    # no overflow possible
-    m = x % y
-    w = space.wrap
-    return space.newtuple([w(z), w(m)])
+    if w_longval is not None:
+        if not space.is_w(w_inttype, space.w_int):
+            raise oefmt(space.w_OverflowError,
+                        "long int too large to convert to int")
+        return w_longval
+    elif space.is_w(w_inttype, space.w_int):
+        # common case
+        return wrapint(space, value)
+    else:
+        w_obj = space.allocate_instance(W_IntObject, w_inttype)
+        W_IntObject.__init__(w_obj, value)
+        return w_obj
 
 
-# helper for pow()
-@jit.look_inside_iff(lambda space, iv, iw, iz:
-                     jit.isconstant(iw) and jit.isconstant(iz))
-def _impl_int_int_pow(space, iv, iw, iz):
-    if iw < 0:
-        if iz != 0:
-            raise OperationError(space.w_TypeError,
-                             space.wrap("pow() 2nd argument "
-                 "cannot be negative when 3rd argument specified"))
-        ## bounce it, since it always returns float
-        raise FailedToImplementArgs(space.w_ValueError,
-                                space.wrap("integer exponentiation"))
-    temp = iv
-    ix = 1
-    try:
-        while iw > 0:
-            if iw & 1:
-                ix = ovfcheck(ix*temp)
-            iw >>= 1   #/* Shift exponent down by 1 bit */
-            if iw==0:
-                break
-            temp = ovfcheck(temp*temp) #/* Square the value of temp */
-            if iz:
-                #/* If we did a multiplication, perform a modulo */
-                ix = ix % iz;
-                temp = temp % iz;
-        if iz:
-            ix = ix % iz
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer exponentiation"))
-    return ix
+W_IntObject.typedef = StdTypeDef("int",
+    __doc__ = """int(x=0) -> int or long
+int(x, base=10) -> int or long
 
-def pow__Int_Int_Int(space, w_int1, w_int2, w_int3):
-    x = w_int1.intval
-    y = w_int2.intval
-    z = w_int3.intval
-    if z == 0:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("pow() 3rd argument cannot be 0"))
-    return space.wrap(_impl_int_int_pow(space, x, y, z))
+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.
 
-def pow__Int_Int_None(space, w_int1, w_int2, w_int3):
-    x = w_int1.intval
-    y = w_int2.intval
-    return space.wrap(_impl_int_int_pow(space, x, y, 0))
+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(W_IntObject.descr_new),
 
-def neg__Int(space, w_int1):
-    a = w_int1.intval
-    try:
-        x = ovfcheck(-a)
-    except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer negation"))
-    return space.newint(x)
-get_negint = neg__Int
+    numerator = typedef.GetSetProperty(
+        W_IntObject.descr_get_numerator,
+        doc="the numerator of a rational number in lowest terms"),
+    denominator = typedef.GetSetProperty(
+        W_IntObject.descr_get_denominator,
+        doc="the denominator of a rational number in lowest terms"),
+    real = typedef.GetSetProperty(
+        W_IntObject.descr_get_real,
+        doc="the real part of a complex number"),
+    imag = typedef.GetSetProperty(
+        W_IntObject.descr_get_imag,
+        doc="the imaginary part of a complex number"),
 
+    __repr__ = interp2app(W_IntObject.descr_repr,
+                          doc=W_AbstractIntObject.descr_repr.__doc__),
+    __str__ = interp2app(W_IntObject.descr_str,
+                         doc=W_AbstractIntObject.descr_str.__doc__),
 
-def abs__Int(space, w_int1):
-    if w_int1.intval >= 0:
-        return w_int1.int(space)
-    else:
-        return get_negint(space, w_int1)
+    conjugate = interp2app(W_IntObject.descr_conjugate,
+                           doc=W_AbstractIntObject.descr_conjugate.__doc__),
+    bit_length = interp2app(W_IntObject.descr_bit_length,
+                            doc=W_AbstractIntObject.descr_bit_length.__doc__),
+    __format__ = interp2app(W_IntObject.descr_format,
+                            doc=W_AbstractIntObject.descr_format.__doc__),
+    __hash__ = interp2app(W_IntObject.descr_hash,
+                          doc=W_AbstractIntObject.descr_hash.__doc__),
+    __coerce__ = interp2app(W_IntObject.descr_coerce,
+                            doc=W_AbstractIntObject.descr_coerce.__doc__),
+    __oct__ = interp2app(W_IntObject.descr_oct,
+                         doc=W_AbstractIntObject.descr_oct.__doc__),
+    __hex__ = interp2app(W_IntObject.descr_hex,
+                         doc=W_AbstractIntObject.descr_hex.__doc__),
+    __getnewargs__ = interp2app(
+        W_IntObject.descr_getnewargs,
+        doc=W_AbstractIntObject.descr_getnewargs.__doc__),
 
-def nonzero__Int(space, w_int1):
-    return space.newbool(w_int1.intval != 0)
+    __int__ = interp2app(W_IntObject.int,
+                         doc=W_AbstractIntObject.int.__doc__),
+    __long__ = interp2app(W_IntObject.descr_long,
+                          doc=W_AbstractIntObject.descr_long.__doc__),
+    __index__ = interp2app(W_IntObject.descr_index,
+                           doc=W_AbstractIntObject.descr_index.__doc__),
+    __trunc__ = interp2app(W_IntObject.descr_trunc,
+                           doc=W_AbstractIntObject.descr_trunc.__doc__),
+    __float__ = interp2app(W_IntObject.descr_float,
+                           doc=W_AbstractIntObject.descr_float.__doc__),
 
-def invert__Int(space, w_int1):
-    x = w_int1.intval
-    a = ~x
-    return space.newint(a)
+    __pos__ = interp2app(W_IntObject.descr_pos,
+                         doc=W_AbstractIntObject.descr_pos.__doc__),
+    __neg__ = interp2app(W_IntObject.descr_neg,
+                         doc=W_AbstractIntObject.descr_neg.__doc__),
+    __abs__ = interp2app(W_IntObject.descr_abs,
+                         doc=W_AbstractIntObject.descr_abs.__doc__),
+    __nonzero__ = interp2app(W_IntObject.descr_nonzero,
+                             doc=W_AbstractIntObject.descr_nonzero.__doc__),
+    __invert__ = interp2app(W_IntObject.descr_invert,
+                            doc=W_AbstractIntObject.descr_invert.__doc__),
 
-def lshift__Int_Int(space, w_int1, w_int2):
-    a = w_int1.intval
-    b = w_int2.intval
-    if r_uint(b) < LONG_BIT: # 0 <= b < LONG_BIT
-        try:
-            c = ovfcheck(a << b)
-        except OverflowError:
-            raise FailedToImplementArgs(space.w_OverflowError,
-                                    space.wrap("integer left shift"))
-        return space.newint(c)
-    if b < 0:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("negative shift count"))
-    else: #b >= LONG_BIT
-        if a == 0:
-            return w_int1.int(space)
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer left shift"))
+    __lt__ = interp2app(W_IntObject.descr_lt,
+                        doc=W_AbstractIntObject.descr_lt.__doc__),
+    __le__ = interp2app(W_IntObject.descr_le,
+                        doc=W_AbstractIntObject.descr_le.__doc__),
+    __eq__ = interp2app(W_IntObject.descr_eq,
+                        doc=W_AbstractIntObject.descr_eq.__doc__),
+    __ne__ = interp2app(W_IntObject.descr_ne,
+                        doc=W_AbstractIntObject.descr_ne.__doc__),
+    __gt__ = interp2app(W_IntObject.descr_gt,
+                        doc=W_AbstractIntObject.descr_gt.__doc__),
+    __ge__ = interp2app(W_IntObject.descr_ge,
+                        doc=W_AbstractIntObject.descr_ge.__doc__),
 
-def rshift__Int_Int(space, w_int1, w_int2):
-    a = w_int1.intval
-    b = w_int2.intval
-    if r_uint(b) >= LONG_BIT: # not (0 <= b < LONG_BIT)
-        if b < 0:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap("negative shift count"))
-        else: # b >= LONG_BIT
-            if a == 0:
-                return w_int1.int(space)
-            if a < 0:
-                a = -1
-            else:
-                a = 0
-    else:
-        a = a >> b
-    return space.newint(a)
+    __add__ = interp2app(W_IntObject.descr_add,
+                         doc=W_AbstractIntObject.descr_add.__doc__),
+    __radd__ = interp2app(W_IntObject.descr_radd,
+                          doc=W_AbstractIntObject.descr_radd.__doc__),
+    __sub__ = interp2app(W_IntObject.descr_sub,
+                         doc=W_AbstractIntObject.descr_sub.__doc__),
+    __rsub__ = interp2app(W_IntObject.descr_rsub,
+                          doc=W_AbstractIntObject.descr_rsub.__doc__),
+    __mul__ = interp2app(W_IntObject.descr_mul,
+                         doc=W_AbstractIntObject.descr_mul.__doc__),
+    __rmul__ = interp2app(W_IntObject.descr_rmul,
+                          doc=W_AbstractIntObject.descr_rmul.__doc__),
 
-def and__Int_Int(space, w_int1, w_int2):
-    a = w_int1.intval
-    b = w_int2.intval
-    res = a & b
-    return space.newint(res)
+    __and__ = interp2app(W_IntObject.descr_and,
+                         doc=W_AbstractIntObject.descr_and.__doc__),
+    __rand__ = interp2app(W_IntObject.descr_rand,
+                          doc=W_AbstractIntObject.descr_rand.__doc__),
+    __or__ = interp2app(W_IntObject.descr_or,
+                        doc=W_AbstractIntObject.descr_or.__doc__),
+    __ror__ = interp2app(W_IntObject.descr_ror,
+                         doc=W_AbstractIntObject.descr_ror.__doc__),
+    __xor__ = interp2app(W_IntObject.descr_xor,
+                         doc=W_AbstractIntObject.descr_xor.__doc__),
+    __rxor__ = interp2app(W_IntObject.descr_rxor,
+                          doc=W_AbstractIntObject.descr_rxor.__doc__),
 
-def xor__Int_Int(space, w_int1, w_int2):
-    a = w_int1.intval
-    b = w_int2.intval
-    res = a ^ b
-    return space.newint(res)
+    __lshift__ = interp2app(W_IntObject.descr_lshift,
+                            doc=W_AbstractIntObject.descr_lshift.__doc__),
+    __rlshift__ = interp2app(W_IntObject.descr_rlshift,
+                             doc=W_AbstractIntObject.descr_rlshift.__doc__),
+    __rshift__ = interp2app(W_IntObject.descr_rshift,
+                            doc=W_AbstractIntObject.descr_rshift.__doc__),
+    __rrshift__ = interp2app(W_IntObject.descr_rrshift,
+                             doc=W_AbstractIntObject.descr_rrshift.__doc__),
 
-def or__Int_Int(space, w_int1, w_int2):
-    a = w_int1.intval
-    b = w_int2.intval
-    res = a | b
-    return space.newint(res)
+    __floordiv__ = interp2app(W_IntObject.descr_floordiv,
+                              doc=W_AbstractIntObject.descr_floordiv.__doc__),
+    __rfloordiv__ = interp2app(
+        W_IntObject.descr_rfloordiv,
+        doc=W_AbstractIntObject.descr_rfloordiv.__doc__),
+    __div__ = interp2app(W_IntObject.descr_div,
+                         doc=W_AbstractIntObject.descr_div.__doc__),
+    __rdiv__ = interp2app(W_IntObject.descr_rdiv,
+                          doc=W_AbstractIntObject.descr_rdiv.__doc__),
+    __truediv__ = interp2app(W_IntObject.descr_truediv,
+                             doc=W_AbstractIntObject.descr_truediv.__doc__),
+    __rtruediv__ = interp2app(W_IntObject.descr_rtruediv,
+                              doc=W_AbstractIntObject.descr_rtruediv.__doc__),
+    __mod__ = interp2app(W_IntObject.descr_mod,
+                         doc=W_AbstractIntObject.descr_mod.__doc__),
+    __rmod__ = interp2app(W_IntObject.descr_rmod,
+                          doc=W_AbstractIntObject.descr_rmod.__doc__),
+    __divmod__ = interp2app(W_IntObject.descr_divmod,
+                            doc=W_AbstractIntObject.descr_divmod.__doc__),
+    __rdivmod__ = interp2app(W_IntObject.descr_rdivmod,
+                             doc=W_AbstractIntObject.descr_rdivmod.__doc__),
 
-def pos__Int(self, space):
-    return self.int(space)
-trunc__Int = pos__Int
-
-def index__Int(space, w_int1):
-    return w_int1.int(space)
-
-def float__Int(space, w_int1):
-    a = w_int1.intval
-    x = float(a)
-    return space.newfloat(x)
-
-def oct__Int(space, w_int1):
-    return space.wrap(oct(w_int1.intval))
-
-def hex__Int(space, w_int1):
-    return space.wrap(hex(w_int1.intval))
-
-def getnewargs__Int(space, w_int1):
-    return space.newtuple([space.newint(w_int1.intval)])
-
-
-register_all(vars())
+    __pow__ = interp2app(W_IntObject.descr_pow,
+                         doc=W_AbstractIntObject.descr_pow.__doc__),
+    __rpow__ = interp2app(W_IntObject.descr_rpow,
+                          doc=W_AbstractIntObject.descr_rpow.__doc__),
+)

pypy/objspace/std/inttype.py

-from pypy.interpreter import typedef
-from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault,\
-     interpindirect2app
-from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.buffer import Buffer
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
-from pypy.objspace.std.model import W_Object
-from rpython.rlib.rarithmetic import r_uint, string_to_int
-from rpython.rlib.objectmodel import instantiate
-from rpython.rlib.rbigint import rbigint
-from rpython.rlib.rstring import (
-    InvalidBaseError, ParseStringError, ParseStringOverflowError)
-from rpython.rlib import jit
-
-# ____________________________________________________________
-
-def descr_conjugate(space, w_int):
-    "Returns self, the complex conjugate of any int."
-    return space.int(w_int)
-
-def descr_bit_length(space, w_int):
-    """int.bit_length() -> int
-
-    Number of bits necessary to represent self in binary.
-    >>> bin(37)
-    '0b100101'
-    >>> (37).bit_length()
-    6
-    """
-    val = space.int_w(w_int)
-    if val < 0:
-        val = -val
-    bits = 0
-    while val:
-        bits += 1
-        val >>= 1
-    return space.wrap(bits)
-
-
-def wrapint(space, x):
-    if space.config.objspace.std.withprebuiltint:
-        from pypy.objspace.std.intobject import W_IntObject
-        lower = space.config.objspace.std.prebuiltintfrom
-        upper =  space.config.objspace.std.prebuiltintto
-        # use r_uint to perform a single comparison (this whole function
-        # is getting inlined into every caller so keeping the branching
-        # to a minimum is a good idea)
-        index = r_uint(x - lower)
-        if index >= r_uint(upper - lower):
-            w_res = instantiate(W_IntObject)
-        else:
-            w_res = W_IntObject.PREBUILT[index]
-        # obscure hack to help the CPU cache: we store 'x' even into
-        # a prebuilt integer's intval.  This makes sure that the intval
-        # field is present in the cache in the common case where it is
-        # quickly reused.  (we could use a prefetch hint if we had that)
-        w_res.intval = x
-        return w_res
-    else:
-        from pypy.objspace.std.intobject import W_IntObject
-        return W_IntObject(x)
-
-# ____________________________________________________________
-
-@jit.elidable
-def string_to_int_or_long(space, w_source, string, base=10):
-    w_longval = None
-    value = 0
-    try:
-        value = string_to_int(string, base)
-    except ParseStringError as e:
-        raise wrap_parsestringerror(space, e, w_source)
-    except ParseStringOverflowError, e:
-        w_longval = retry_to_w_long(space, e.parser, w_source)
-    return value, w_longval
-
-def retry_to_w_long(space, parser, w_source):
-    parser.rewind()
-    try:
-        bigint = rbigint._from_numberstring_parser(parser)
-    except ParseStringError as e:
-        raise wrap_parsestringerror(space, e, w_source)
-    return space.newlong_from_rbigint(bigint)
-
-def wrap_parsestringerror(space, e, w_source):
-    if isinstance(e, InvalidBaseError):
-        w_msg = space.wrap(e.msg)
-    else:
-        w_msg = space.wrap('%s: %s' % (e.msg,
-                                       space.str_w(space.repr(w_source))))
-    return OperationError(space.w_ValueError, w_msg)
-
-@unwrap_spec(w_x = WrappedDefault(0))
-def descr__new__(space, w_inttype, w_x, w_base=None):
-    from pypy.objspace.std.intobject import W_IntObject
-    w_longval = None
-    w_value = w_x     # 'x' is the keyword argument name in CPython
-    value = 0
-    if w_base is None:
-        # check for easy cases
-        if type(w_value) is W_IntObject:
-            value = w_value.intval
-        elif space.lookup(w_value, '__int__') is not None or \
-                space.lookup(w_value, '__trunc__') is not None:
-            # otherwise, use the __int__() or the __trunc__() methods
-            w_obj = w_value
-            if space.lookup(w_obj, '__int__') is None:
-                w_obj = space.trunc(w_obj)
-            w_obj = space.int(w_obj)
-            # 'int(x)' should return what x.__int__() returned, which should
-            # be an int or long or a subclass thereof.
-            if space.is_w(w_inttype, space.w_int):
-                return w_obj
-            # int_w is effectively what we want in this case,
-            # we cannot construct a subclass of int instance with an
-            # 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, w_value,
-                                                     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, w_value, string)
-        else:
-            # If object supports the buffer interface
-            try:
-                w_buffer = space.buffer(w_value)
-            except OperationError, e:
-                if not e.match(space, space.w_TypeError):
-                    raise
-                raise oefmt(space.w_TypeError,
-                            "int() argument must be a string or a number, not "
-                            "'%T'", w_value)
-            else:
-                buf = space.interp_w(Buffer, w_buffer)
-                value, w_longval = string_to_int_or_long(space, w_value,
-                                                         buf.as_str())
-    else:
-        base = space.int_w(w_base)
-
-        if space.isinstance_w(w_value, space.w_unicode):
-            from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
-            s = unicode_to_decimal_w(space, w_value)
-        else:
-            try:
-                s = space.str_w(w_value)
-            except OperationError, e:
-                raise OperationError(space.w_TypeError,
-                                     space.wrap("int() can't convert non-string "
-                                                "with explicit base"))
-
-        value, w_longval = string_to_int_or_long(space, w_value, s, base)
-
-    if w_longval is not None:
-        if not space.is_w(w_inttype, space.w_int):
-            raise OperationError(space.w_OverflowError,
-                                 space.wrap(
-                "long int too large to convert to int"))
-        return w_longval
-    elif space.is_w(w_inttype, space.w_int):
-        # common case
-        return wrapint(space, value)
-    else:
-        w_obj = space.allocate_instance(W_IntObject, w_inttype)
-        W_IntObject.__init__(w_obj, value)
-        return w_obj
-
-def descr_get_numerator(space, w_obj):
-    return space.int(w_obj)
-
-def descr_get_denominator(space, w_obj):
-    return space.wrap(1)
-
-def descr_get_real(space, w_obj):
-    return space.int(w_obj)
-
-def descr_get_imag(space, w_obj):
-    return space.wrap(0)
-
-# ____________________________________________________________
-
-class W_AbstractIntObject(W_Object):
-    __slots__ = ()
-
-    def is_w(self, space, w_other):
-        if not isinstance(w_other, W_AbstractIntObject):
-            return False
-        if self.user_overridden_class or w_other.user_overridden_class:
-            return self is w_other
-        return space.int_w(self) == space.int_w(w_other)
-
-    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))
-        return space.newlong_from_rbigint(b)
-
-    def int(self, space):
-        raise NotImplementedError
-
-int_typedef = StdTypeDef("int",
-    __doc__ = '''int(x[, base]) -> integer
-
-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.''',
-    __new__ = interp2app(descr__new__),
-    conjugate = interp2app(descr_conjugate),
-    bit_length = interp2app(descr_bit_length),
-    numerator = typedef.GetSetProperty(descr_get_numerator),
-    denominator = typedef.GetSetProperty(descr_get_denominator),
-    real = typedef.GetSetProperty(descr_get_real),
-    imag = typedef.GetSetProperty(descr_get_imag),
-    __int__ = interpindirect2app(W_AbstractIntObject.int),
-)
-int_typedef.registermethods(globals())

pypy/objspace/std/longobject.py

 """The builtin long implementation"""
 
-import sys
+import functools
 
+from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rbigint import rbigint
+from rpython.rlib.rstring import ParseStringError
+from rpython.tool.sourcetools import func_renamer, func_with_new_name
 
-from pypy.interpreter.error import OperationError
-from pypy.objspace.std import model, newformat
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.longtype import W_AbstractLongObject, long_typedef
-from pypy.objspace.std.model import W_Object, registerimplementation
-from pypy.objspace.std.multimethod import FailedToImplementArgs
-from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.objspace.std.register_all import register_all
+from pypy.interpreter import typedef
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.buffer import Buffer
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.gateway import (
+    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
+
+
+def delegate_other(func):
+    @functools.wraps(func)
+    def delegated(self, space, w_other):
+        if isinstance(w_other, W_AbstractIntObject):
+            w_other = w_other.descr_long(space)
+        elif not isinstance(w_other, W_AbstractLongObject):
+            return space.w_NotImplemented
+        return func(self, space, w_other)
+    return delegated
+
+
+class W_AbstractLongObject(W_Root):
+
+    __slots__ = ()
+
+    def is_w(self, space, w_other):
+        if not isinstance(w_other, W_AbstractLongObject):
+            return False
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return self is w_other
+        return space.bigint_w(self).eq(space.bigint_w(w_other))
+
+    def immutable_unique_id(self, space):
+        if self.user_overridden_class:
+            return None
+        b = space.bigint_w(self)
+        b = b.lshift(3).or_(rbigint.fromint(IDTAG_LONG))
+        return space.newlong_from_rbigint(b)
+
+    def unwrap(self, space):
+        return self.longval()
+
+    def int(self, space):
+        raise NotImplementedError
+
+    def asbigint(self):
+        raise NotImplementedError
+
+    def descr_getnewargs(self, space):
+        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())
+        except OverflowError:
+            raise oefmt(space.w_OverflowError, "too many digits in integer")
+
+    def _truediv(self, space, w_other):
+        try:
+            f = self.asbigint().truediv(w_other.asbigint())
+        except ZeroDivisionError:
+            raise oefmt(space.w_ZeroDivisionError,
+                        "long division or modulo by zero")
+        except OverflowError:
+            raise oefmt(space.w_OverflowError,
+                        "long/long too large for a float")
+        return space.newfloat(f)
+
+    @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 == '%':