[pypy-commit] pypy remove-intlong-smm: fully handle int overflowing to smalllong and much cleanup/progress
pjenvey
noreply at buildbot.pypy.org
Sat Dec 28 01:59:00 CET 2013
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: remove-intlong-smm
Changeset: r68560:e677ccdf7fe2
Date: 2013-12-27 16:56 -0800
http://bitbucket.org/pypy/pypy/changeset/e677ccdf7fe2/
Log: fully handle int overflowing to smalllong and much cleanup/progress
diff too long, truncating to 2000 out of 2240 lines
diff --git a/pypy/objspace/std/boolobject.py b/pypy/objspace/std/boolobject.py
--- a/pypy/objspace/std/boolobject.py
+++ b/pypy/objspace/std/boolobject.py
@@ -2,7 +2,7 @@
from rpython.rlib.rbigint import rbigint
from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
-from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject
+from pypy.objspace.std.intobject import W_AbstractIntObject
from pypy.objspace.std.stdtypedef import StdTypeDef
@@ -41,7 +41,6 @@
def descr_repr(self, space):
return space.wrap('True' if self.boolval else 'False')
-
descr_str = descr_repr
def descr_nonzero(self, space):
@@ -68,11 +67,11 @@
@unwrap_spec(w_obj=WrappedDefault(False))
def descr__new__(space, w_booltype, w_obj):
space.w_bool.check_user_subclass(w_booltype)
- return space.newbool(space.is_true(w_obj)) # XXX: method call?
+ return space.newbool(space.is_true(w_obj))
# ____________________________________________________________
-W_BoolObject.typedef = StdTypeDef("bool", W_IntObject.typedef,
+W_BoolObject.typedef = StdTypeDef("bool", W_AbstractIntObject.typedef,
__doc__ = """bool(x) -> bool
Returns True when the argument x is true, False otherwise.
@@ -81,6 +80,13 @@
__new__ = interp2app(descr__new__),
__repr__ = interp2app(W_BoolObject.descr_repr),
__str__ = interp2app(W_BoolObject.descr_str),
- # XXX: might as well declare interp2app directly here for nonzero/and/etc
+ __nonzero__ = interp2app(W_BoolObject.descr_nonzero),
+ # XXX: rsides
+ __and__ = interp2app(W_BoolObject.descr_and),
+ #__rand__ = interp2app(W_BoolObject.descr_rand),
+ __or__ = interp2app(W_BoolObject.descr_or),
+ #__ror__ = interp2app(W_BoolObject.descr_ror),
+ __xor__ = interp2app(W_BoolObject.descr_xor),
+ #__rxor__ = interp2app(W_BoolObject.descr_rxor),
)
W_BoolObject.typedef.acceptable_as_base_class = False
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -62,7 +62,6 @@
# long-to-float delegation
def delegate_Long2Float(space, w_longobj):
- # XXX: tofloat is not abstract (SmallLongs)
return W_FloatObject(w_longobj.tofloat(space))
@@ -563,20 +562,3 @@
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)
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
@@ -6,40 +6,251 @@
"""
import operator
+import sys
from rpython.rlib import jit
+from rpython.rlib.objectmodel import instantiate, specialize
from rpython.rlib.rarithmetic import (
- LONG_BIT, is_valid_int, ovfcheck, string_to_int, r_uint)
-from rpython.rlib.objectmodel import instantiate
+ LONG_BIT, is_valid_int, ovfcheck, r_uint, string_to_int)
from rpython.rlib.rbigint import rbigint
from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError
-from rpython.tool.sourcetools import func_with_new_name
+from rpython.tool.sourcetools import func_renamer, func_with_new_name
from pypy.interpreter import typedef
+from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.buffer import Buffer
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import (
WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
from pypy.objspace.std import newformat
-from pypy.objspace.std.model import W_Object
from pypy.objspace.std.stdtypedef import StdTypeDef
-class W_AbstractIntObject(W_Object):
+class W_AbstractIntObject(W_Root):
+
__slots__ = ()
def int(self, space):
raise NotImplementedError
+ 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_AbstractIntObject):
+ return space.w_NotImplemented
+ i = space.int_w(self)
+ j = space.int_w(w_other)
+ 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)
+ commutative = opname in ('add', 'mul', 'and', 'or', 'xor')
+
+ @func_renamer('descr_' + opname)
+ def descr_binop(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(x, y))
+ except OverflowError:
+ return ovf2long(space, opname, self, w_other)
+ else:
+ z = op(x, y)
+ return wrapint(space, z)
+
+ if commutative:
+ return descr_binop, func_with_new_name(descr_binop,
+ 'descr_r' + opname)
+
+ @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)
+
+ 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:]
+
+ @func_renamer('descr_' + opname)
+ def descr_binop(self, space, w_other):
+ if not isinstance(w_other, W_AbstractIntObject):
+ return space.w_NotImplemented
+ try:
+ return func(self, space, w_other)
+ except OverflowError:
+ return ovf2long(space, opname, self, w_other)
+
+ @func_renamer('descr_r' + opname)
+ def descr_rbinop(self, space, w_other):
+ if not isinstance(w_other, W_AbstractIntObject):
+ return space.w_NotImplemented
+ try:
+ return func(w_other, space, self)
+ except OverflowError:
+ return ovf2long(space, opname, w_other, self)
+
+ return descr_binop, descr_rbinop
+
+ def _floordiv(self, space, w_other):
+ x = space.int_w(self)
+ y = space.int_w(w_other)
+ try:
+ z = ovfcheck(x // y)
+ except ZeroDivisionError:
+ raise operationerrfmt(space.w_ZeroDivisionError,
+ "integer division by zero")
+ return wrapint(space, z)
+ descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv)
+
+ _div = func_with_new_name(_floordiv, '_div')
+ descr_div, descr_rdiv = _make_descr_binop(_div)
+
+ def _truediv(self, space, w_other):
+ x = float(space.int_w(self))
+ y = float(space.int_w(w_other))
+ if y == 0.0:
+ raise operationerrfmt(space.w_ZeroDivisionError,
+ "division by zero")
+ return space.wrap(x / y)
+ descr_truediv, descr_rtruediv = _make_descr_binop(_truediv)
+
+ def _mod(self, space, w_other):
+ x = space.int_w(self)
+ y = space.int_w(w_other)
+ try:
+ z = ovfcheck(x % y)
+ except ZeroDivisionError:
+ raise operationerrfmt(space.w_ZeroDivisionError,
+ "integer modulo by zero")
+ return wrapint(space, z)
+ descr_mod, descr_rmod = _make_descr_binop(_mod)
+
+ def _divmod(self, space, w_other):
+ x = space.int_w(self)
+ y = space.int_w(w_other)
+ try:
+ z = ovfcheck(x // y)
+ except ZeroDivisionError:
+ raise operationerrfmt(space.w_ZeroDivisionError,
+ "integer divmod by zero")
+ # no overflow possible
+ m = x % y
+ w = space.wrap
+ return space.newtuple([w(z), w(m)])
+ descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
+
+ def _lshift(self, space, w_other):
+ a = space.int_w(self)
+ b = space.int_w(w_other)
+ if r_uint(b) < LONG_BIT: # 0 <= b < LONG_BIT
+ c = ovfcheck(a << b)
+ 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
+ descr_lshift, descr_rlshift = _make_descr_binop(_lshift)
+
+ def _rshift(self, space, w_other):
+ a = space.int_w(self)
+ b = space.int_w(w_other)
+ if r_uint(b) >= LONG_BIT: # not (0 <= b < LONG_BIT)
+ if b < 0:
+ raise operationerrfmt(space.w_ValueError,
+ "negative shift count")
+ # b >= LONG_BIT
+ if a == 0:
+ return self.int(space)
+ a = -1 if a < 0 else 0
+ else:
+ a = a >> b
+ 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_format(self, space, w_format_spec):
- return newformat.run_formatter(space, w_format_spec,
- "format_int_or_long", self,
- newformat.INT_KIND)
-
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
@@ -47,283 +258,30 @@
# floats and longs.
return self.int(space)
- def descr_coerce(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
- return space.newtuple([self, w_other])
+ def descr_nonzero(self, space):
+ return space.newbool(space.int_w(self) != 0)
- def _make_descr_binop(opname):
- # XXX: func_renamer or func_with_new_name?
- from rpython.tool.sourcetools import func_renamer
- op = getattr(operator, opname)
+ def descr_invert(self, space):
+ return wrapint(space, ~space.int_w(self))
- @func_renamer('descr_' + opname)
- def descr_binop(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- x = space.int_w(self)
- y = space.int_w(w_other)
- try:
- z = ovfcheck(op(x, y))
- except OverflowError:
- w_long1 = _delegate_Int2Long(space, self)
- # XXX: this needs to be _delegate_Int2Long(space,
- # space.int(w_other)) to support bools. so maybe delegation
- # should work against space.int_w(w_other)
- w_long2 = _delegate_Int2Long(space, w_other)
- return getattr(space, opname)(w_long1, w_long2)
- return wrapint(space, z)
-
- @func_renamer('descr_r' + opname)
- def descr_rbinop(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- x = space.int_w(self)
- y = space.int_w(w_other)
- try:
- z = ovfcheck(op(y, x))
- except OverflowError:
- w_long1 = _delegate_Int2Long(space, self)
- # XXX: this needs to be _delegate_Int2Long(space,
- # space.int(w_other)) to support bools. so maybe delegation
- # should work against space.int_w(w_other)
- w_long2 = _delegate_Int2Long(space, w_other)
- return getattr(space, opname)(w_long2, w_long1)
- return wrapint(space, z)
-
- return descr_binop, descr_rbinop
-
- descr_add, descr_radd = _make_descr_binop('add')
- descr_sub, descr_rsub = _make_descr_binop('sub')
- descr_mul, descr_rmul = _make_descr_binop('mul')
-
- def _make_descr_cmp(opname):
- op = getattr(operator, opname)
- def f(self, space, w_other):
- # XXX: this doesn't belong here, regardless of how we originally set this up. blargh
- #if isinstance(w_other, W_SmallLongObject):
- # return space.newbool(op(space.int_w(self), w_other.longlong))
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- i = space.int_w(self)
- j = space.int_w(w_other)
- return space.newbool(op(i, j))
- return func_with_new_name(f, "descr_" + opname)
-
- 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 descr_floordiv(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- x = space.int_w(self)
- y = space.int_w(w_other)
- try:
- z = ovfcheck(x // y)
- except ZeroDivisionError:
- raise operationerrfmt(space.w_ZeroDivisionError,
- "integer division by zero")
- except OverflowError:
- w_long1 = _delegate_Int2Long(space, self)
- w_long2 = _delegate_Int2Long(space, w_other)
- return space.floordiv(w_long1, w_long2)
- return wrapint(space, z)
-
- descr_div = func_with_new_name(descr_floordiv, 'descr_div')
-
- def descr_truediv(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- x = float(space.int_w(self))
- y = float(space.int_w(w_other))
- if y == 0.0:
- raise operationerrfmt(space.w_ZeroDivisionError,
- "division by zero")
- return space.wrap(x / y)
-
- def descr_mod(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- x = space.int_w(self)
- y = space.int_w(w_other)
- try:
- z = ovfcheck(x % y)
- except ZeroDivisionError:
- raise operationerrfmt(space.w_ZeroDivisionError,
- "integer modulo by zero")
- except OverflowError:
- w_long1 = _delegate_Int2Long(space, self)
- w_long2 = _delegate_Int2Long(space, w_other)
- return space.mod(w_long1, w_long2)
- return wrapint(space, z)
-
- def descr_divmod(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- x = space.int_w(self)
- y = space.int_w(w_other)
- try:
- z = ovfcheck(x // y)
- except ZeroDivisionError:
- raise operationerrfmt(space.w_ZeroDivisionError,
- "integer divmod by zero")
- except OverflowError:
- w_long1 = _delegate_Int2Long(space, self)
- w_long2 = _delegate_Int2Long(space, w_other)
- return space.divmod(w_long1, w_long2)
-
- # no overflow possible
- m = x % y
- w = space.wrap
- return space.newtuple([w(z), w(m)])
-
- @unwrap_spec(w_modulus=WrappedDefault(None))
- def descr_pow(self, space, w_exponent, w_modulus=None):
- if not space.isinstance_w(w_exponent, space.w_int):
- return space.w_NotImplemented
- if space.is_none(w_modulus):
- z = 0
- elif space.isinstance_w(w_modulus, space.w_int):
- # XXX: handle long... overflow?
- z = space.int_w(w_modulus)
- if z == 0:
- raise operationerrfmt(space.w_ValueError,
- "pow() 3rd argument cannot be 0")
- else:
- return self._delegate2longpow(space, w_exponent, w_modulus)
- #return space.w_NotImplemented
-
- x = space.int_w(self)
- y = space.int_w(w_exponent)
- try:
- return space.wrap(_pow_impl(space, x, y, z))
- except ValueError:
- return self._delegate2longpow(space, w_exponent, w_modulus)
-
- def _delegate2longpow(self, space, w_exponent, w_modulus):
- # XXX: gross
- w_long1 = _delegate_Int2Long(space, self)
- w_exponent = _delegate_Int2Long(space, w_exponent)
- if not space.is_none(w_modulus):
- w_modulus = _delegate_Int2Long(space, w_modulus)
- return space.pow(w_long1, w_exponent, w_modulus)
-
- @unwrap_spec(w_modulus=WrappedDefault(None))
- def descr_rpow(self, space, w_base, w_modulus=None):
- if not space.isinstance_w(w_base, space.w_int):
- return space.w_NotImplemented
- # XXX: this seems like trouble? very likely trouble with int
- # subclasses implementing __pow__
- return space.pow(w_base, self, w_modulus)
+ 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:
- w_long1 = _delegate_Int2Long(space, self)
- return space.neg(w_long1)
+ 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):
- return self.int(space) if space.int_w(self) >= 0 else self.descr_neg(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_lshift(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- a = space.int_w(self)
- b = space.int_w(w_other)
- if r_uint(b) < LONG_BIT: # 0 <= b < LONG_BIT
- try:
- c = ovfcheck(a << b)
- except OverflowError:
- w_long1 = _delegate_Int2Long(space, self)
- w_long2 = _delegate_Int2Long(space, w_other)
- return space.lshift(w_long1, w_long2)
- 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)
- w_long1 = _delegate_Int2Long(space, self)
- w_long2 = _delegate_Int2Long(space, w_other)
- return space.lshift(w_long1, w_long2)
-
- def descr_rshift(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- a = space.int_w(self)
- b = space.int_w(w_other)
- if r_uint(b) >= LONG_BIT: # not (0 <= b < LONG_BIT)
- if b < 0:
- raise operationerrfmt(space.w_ValueError,
- "negative shift count")
- else: # b >= LONG_BIT
- if a == 0:
- return self.int(space)
- if a < 0:
- a = -1
- else:
- a = 0
- else:
- a = a >> b
- return wrapint(space, a)
-
- def descr_and(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- a = space.int_w(self)
- b = space.int_w(w_other)
- res = a & b
- return wrapint(space, res)
-
- def descr_or(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- a = space.int_w(self)
- b = space.int_w(w_other)
- res = a | b
- return wrapint(space, res)
-
- def descr_xor(self, space, w_other):
- if not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- a = space.int_w(self)
- b = space.int_w(w_other)
- res = a ^ b
- return wrapint(space, res)
-
- descr_rand = func_with_new_name(descr_and, 'descr_rand')
- descr_ror = func_with_new_name(descr_or, 'descr_ror')
- descr_rxor = func_with_new_name(descr_xor, 'descr_rxor')
-
- def descr_pos(self, space):
- return self.int(space)
-
- descr_trunc = func_with_new_name(descr_pos, 'descr_trunc')
+ 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)
@@ -342,13 +300,8 @@
def descr_getnewargs(self, space):
return space.newtuple([wrapint(space, space.int_w(self))])
- def descr_repr(self, space):
- res = str(self.int_w(space))
- return space.wrap(res)
- descr_str = func_with_new_name(descr_repr, 'descr_str')
-
def descr_conjugate(self, space):
- "Returns self, the complex conjugate of any int."
+ """Returns self, the complex conjugate of any int."""
return space.int(self)
def descr_bit_length(self, space):
@@ -369,9 +322,15 @@
val >>= 1
return space.wrap(bits)
- def descr_get_numerator(self, space):
- return space.int(self)
- descr_get_real = func_with_new_name(descr_get_numerator, 'descr_get_real')
+ 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)
@@ -379,8 +338,11 @@
def descr_get_imag(self, space):
return space.wrap(0)
+ descr_get_numerator = descr_get_real = descr_conjugate
+
class W_IntObject(W_AbstractIntObject):
+
__slots__ = 'intval'
_immutable_fields_ = ['intval']
@@ -393,7 +355,7 @@
return "%s(%d)" % (self.__class__.__name__, self.intval)
def is_w(self, space, w_other):
- if not isinstance(w_other, W_AbstractIntObject):
+ if not isinstance(w_other, W_IntObject):
return False
if self.user_overridden_class or w_other.user_overridden_class:
return self is w_other
@@ -414,11 +376,10 @@
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 operationerrfmt(space.w_ValueError,
+ "cannot convert negative integer to "
+ "unsigned")
+ return r_uint(intval)
def bigint_w(self, space):
return rbigint.fromint(self.intval)
@@ -429,15 +390,29 @@
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)
+ return W_Root.int(self, space)
if space.is_w(space.type(self), space.w_int):
return self
a = self.intval
return space.newint(a)
-def _delegate_Int2Long(space, w_intobj):
- from pypy.objspace.std.longobject import W_LongObject
- return W_LongObject.fromint(space, w_intobj.int_w(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
+ sys.maxint == 2147483647)
+
+
+ at specialize.arg(1)
+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)
+ self = self.descr_long(space)
+ w_other = w_other.descr_long(space)
+ return getattr(self, 'descr_' + opname)(space, w_other)
# helper for pow()
@@ -446,53 +421,49 @@
def _pow_impl(space, iv, iw, iz):
if iw < 0:
if iz != 0:
- msg = ("pow() 2nd argument cannot be negative when 3rd argument "
- "specified")
- raise operationerrfmt(space.w_TypeError, msg)
- ## bounce it, since it always returns float
+ raise operationerrfmt(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
- 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;
+ 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:
- ix = ix % iz
- except OverflowError:
- raise ValueError
+ # If we did a multiplication, perform a modulo
+ ix %= iz
+ temp %= iz
+ if iz:
+ ix %= iz
return ix
# ____________________________________________________________
def wrapint(space, x):
- if space.config.objspace.std.withprebuiltint:
- 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
+ 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:
- return W_IntObject(x)
+ 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
# ____________________________________________________________
@@ -502,10 +473,9 @@
value = 0
try:
value = string_to_int(string, base)
- except ParseStringError, e:
- raise OperationError(space.w_ValueError,
- space.wrap(e.msg))
- except ParseStringOverflowError, e:
+ 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)
return value, w_longval
@@ -513,9 +483,8 @@
parser.rewind()
try:
bigint = rbigint._from_numberstring_parser(parser)
- except ParseStringError, e:
- raise OperationError(space.w_ValueError,
- space.wrap(e.msg))
+ except ParseStringError as e:
+ raise OperationError(space.w_ValueError, space.wrap(e.msg))
return space.newlong_from_rbigint(bigint)
@unwrap_spec(w_x=WrappedDefault(0))
@@ -543,7 +512,8 @@
# 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)
@@ -552,7 +522,7 @@
# If object supports the buffer interface
try:
w_buffer = space.buffer(w_value)
- except OperationError, e:
+ except OperationError as e:
if not e.match(space, space.w_TypeError):
raise
raise operationerrfmt(space.w_TypeError,
@@ -571,18 +541,17 @@
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"))
+ except OperationError as e:
+ raise operationerrfmt(space.w_TypeError,
+ "int() can't convert non-string with "
+ "explicit 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):
- raise OperationError(space.w_OverflowError,
- space.wrap(
- "long int too large to convert to int"))
+ raise operationerrfmt(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
@@ -596,14 +565,14 @@
W_AbstractIntObject.typedef = StdTypeDef("int",
- __doc__ = '''int(x[, base]) -> integer
+ __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.''',
+will be returned instead.""",
__new__ = interp2app(descr__new__),
numerator = typedef.GetSetProperty(
@@ -635,12 +604,21 @@
__gt__ = interpindirect2app(W_AbstractIntObject.descr_gt),
__ge__ = interpindirect2app(W_AbstractIntObject.descr_ge),
- # XXX: rtruediv
__floordiv__ = interpindirect2app(W_AbstractIntObject.descr_floordiv),
+ __rfloordiv__ = interpindirect2app(W_AbstractIntObject.descr_rfloordiv),
__div__ = interpindirect2app(W_AbstractIntObject.descr_div),
+ __rdiv__ = interpindirect2app(W_AbstractIntObject.descr_rdiv),
__truediv__ = interpindirect2app(W_AbstractIntObject.descr_truediv),
+ __rtruediv__ = interpindirect2app(W_AbstractIntObject.descr_rtruediv),
__mod__ = interpindirect2app(W_AbstractIntObject.descr_mod),
+ __rmod__ = interpindirect2app(W_AbstractIntObject.descr_rmod),
__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),
@@ -648,14 +626,13 @@
__abs__ = interpindirect2app(W_AbstractIntObject.descr_abs),
__nonzero__ = interpindirect2app(W_AbstractIntObject.descr_nonzero),
__invert__ = interpindirect2app(W_AbstractIntObject.descr_invert),
- __lshift__ = interpindirect2app(W_AbstractIntObject.descr_lshift),
- __rshift__ = interpindirect2app(W_AbstractIntObject.descr_rshift),
__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),
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
@@ -1,41 +1,35 @@
"""The builtin long implementation"""
-import sys
+import functools
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 import typedef
+from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.buffer import Buffer
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import (
WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
-from pypy.objspace.std import model, newformat
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.model import W_Object
-from pypy.objspace.std.noneobject import W_NoneObject
+from pypy.objspace.std import newformat
+from pypy.objspace.std.intobject import W_AbstractIntObject
from pypy.objspace.std.stdtypedef import StdTypeDef
def delegate_other(func):
- @func_renamer(func.__name__)
+ @functools.wraps(func)
def delegated(self, space, w_other):
- if space.isinstance_w(w_other, space.w_int):
- w_other = _delegate_Int2Long(space, w_other)
- elif not space.isinstance_w(w_other, space.w_long):
+ if isinstance(w_other, W_AbstractIntObject):
+ w_other = w_other.descr_long(space)
+ elif not isinstance(w_other, W_AbstractLongObject):
return space.w_NotImplemented
- # XXX: if a smalllong, delegate to Long?
- assert isinstance(w_other, W_AbstractLongObject)
return func(self, space, w_other)
return delegated
-def _delegate_Int2Long(space, w_intobj):
- """int-to-long delegation"""
- return W_LongObject.fromint(space, w_intobj.int_w(space))
+class W_AbstractLongObject(W_Root):
-class W_AbstractLongObject(W_Object):
__slots__ = ()
def is_w(self, space, w_other):
@@ -53,8 +47,8 @@
b = b.lshift(3).or_(rbigint.fromint(tag))
return space.newlong_from_rbigint(b)
- def unwrap(w_self, space): #YYYYYY
- return w_self.longval()
+ def unwrap(self, space):
+ return self.longval()
def int(self, space):
raise NotImplementedError
@@ -62,15 +56,14 @@
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')
- # XXX:
- def descr_float(self, space):
- raise NotImplementedError
+ 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')
@@ -100,7 +93,9 @@
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')
@@ -119,20 +114,19 @@
return newformat.run_formatter(space, w_format_spec,
"format_int_or_long", self,
newformat.LONG_KIND)
- def descr_repr(self, space):
- return space.wrap(self.asbigint().repr())
- def descr_str(self, space):
- return space.wrap(self.asbigint().str())
+ 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
- def descr_hash(self, space):
- return space.wrap(self.asbigint().hash())
-
- def descr_oct(self, space):
- return space.wrap(self.asbigint().oct())
-
- def descr_hex(self, space):
- return space.wrap(self.asbigint().hex())
+ 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())])
@@ -145,14 +139,11 @@
try:
return space.wrap(bigint.bit_length())
except OverflowError:
- raise OperationError(space.w_OverflowError,
- space.wrap("too many digits in integer"))
+ raise operationerrfmt(space.w_OverflowError,
+ "too many digits in integer")
- # XXX: need rtruediv
- @delegate_other
- def descr_truediv(self, space, w_other):
+ def _truediv(self, space, w_other):
try:
- #f = self.num.truediv(w_other.num)
f = self.asbigint().truediv(w_other.asbigint())
except ZeroDivisionError:
raise operationerrfmt(space.w_ZeroDivisionError,
@@ -163,8 +154,15 @@
return space.newfloat(f)
@delegate_other
+ def descr_truediv(self, space, w_other):
+ return W_AbstractLongObject._truediv(self, space, w_other)
+
+ @delegate_other
+ def descr_rtruediv(self, space, w_other):
+ return W_AbstractLongObject._truediv(w_other, space, self)
+
+ @delegate_other
def descr_coerce(self, space, w_other):
- # XXX: consider stian's branch where he optimizes long + ints
return space.newtuple([self, w_other])
def descr_get_numerator(self, space):
@@ -180,10 +178,11 @@
class W_LongObject(W_AbstractLongObject):
"""This is a wrapper of rbigint."""
+
_immutable_fields_ = ['num']
- def __init__(self, l):
- self.num = l # instance of rbigint
+ def __init__(self, num):
+ self.num = num # instance of rbigint
def fromint(space, intval):
return W_LongObject(rbigint.fromint(intval))
@@ -219,18 +218,20 @@
try:
return self.num.toint()
except OverflowError:
- raise OperationError(space.w_OverflowError, space.wrap(
- "long int too large to convert to int"))
+ raise operationerrfmt(space.w_OverflowError,
+ "long int too large to convert to int")
def uint_w(self, space):
try:
return self.num.touint()
except ValueError:
- raise OperationError(space.w_ValueError, space.wrap(
- "cannot convert negative integer to unsigned int"))
+ raise operationerrfmt(space.w_ValueError,
+ "cannot convert negative integer to "
+ "unsigned int")
except OverflowError:
- raise OperationError(space.w_OverflowError, space.wrap(
- "long int too large to convert to unsigned int"))
+ raise operationerrfmt(space.w_OverflowError,
+ "long int too large to convert to unsigned "
+ "int")
def bigint_w(self, space):
return self.num
@@ -241,7 +242,7 @@
def int(self, space):
if (type(self) is not W_LongObject and
space.is_overloaded(self, space.w_long, '__int__')):
- return W_Object.int(self, space)
+ return W_Root.int(self, space)
try:
return space.newint(self.num.toint())
except OverflowError:
@@ -254,35 +255,22 @@
return '<W_LongObject(%d)>' % self.num.tolong()
def descr_long(self, space):
- # long__Long is supposed to do nothing, unless it has a derived
+ # __long__ is supposed to do nothing, unless it has a derived
# long object, where it should return an exact one.
if space.is_w(space.type(self), space.w_long):
return self
- l = self.num
- return W_LongObject(l)
- 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')
+ return W_LongObject(self.num)
+ descr_index = descr_trunc = descr_pos = descr_long
def descr_float(self, space):
return space.newfloat(self.tofloat(space))
def _make_descr_cmp(opname):
- #from pypy.objspace.std.smalllongobject import W_SmallLongObject
op = getattr(rbigint, opname)
@delegate_other
def descr_impl(self, space, w_other):
- ## XXX: these only need explicit SmallLong support whereas
- ## everything else would delegate2Long. blah blah
- #if isinstance(w_other, W_SmallLongObject):
- # result = op(self.num, w_other.asbigint())
- #else:
- # result = op(self.num, w_other.num)
- #return space.newbool(result)
-
- # XXX: if we use self.asbigint then can this live on
- # AbstractLong? eek not really, a '_cmp' (_lt) could live on
- # it that just did this (without the checks..)
+ # XXX: previous impl had all kinds of shortcuts between
+ # smalllong and int/long
return space.newbool(op(self.num, w_other.asbigint()))
return func_with_new_name(descr_impl, "descr_" + opname)
@@ -293,8 +281,7 @@
descr_gt = _make_descr_cmp('gt')
descr_ge = _make_descr_cmp('ge')
- def _make_descr_binop(opname):
- from rpython.tool.sourcetools import func_renamer
+ def _make_generic_descr_binop(opname):
methname = opname + '_' if opname in ('and', 'or') else opname
op = getattr(rbigint, methname)
@@ -306,19 +293,19 @@
@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
- descr_add, descr_radd = _make_descr_binop('add')
- descr_sub, descr_rsub = _make_descr_binop('sub')
- descr_mul, descr_rmul = _make_descr_binop('mul')
- descr_and, descr_rand = _make_descr_binop('and')
- descr_or, descr_ror = _make_descr_binop('or')
- descr_xor, descr_rxor = _make_descr_binop('xor')
+ 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')
+ descr_or, descr_ror = _make_generic_descr_binop('or')
+ descr_xor, descr_rxor = _make_generic_descr_binop('xor')
def _make_descr_unaryop(opname):
- from rpython.tool.sourcetools import func_renamer
op = getattr(rbigint, opname)
@func_renamer('descr_' + opname)
def descr_unaryop(self, space):
@@ -332,9 +319,25 @@
def descr_nonzero(self, space):
return space.newbool(self.num.tobool())
- @delegate_other
- def descr_lshift(self, space, w_other):
- # XXX need to replicate some of the logic, to get the errors right
+ def _make_descr_binop(func):
+ opname = func.__name__[1:]
+
+ @delegate_other
+ @func_renamer('descr_' + opname)
+ def descr_binop(self, space, w_other):
+ return func(self, space, w_other)
+
+ @delegate_other
+ @func_renamer('descr_r' + opname)
+ def descr_rbinop(self, space, w_other):
+ if not isinstance(w_other, W_LongObject):
+ # coerce other W_AbstractLongObjects
+ w_other = W_LongObject(w_other.asbigint())
+ return func(w_other, space, self)
+
+ return descr_binop, descr_rbinop
+
+ def _lshift(self, space, w_other):
if w_other.asbigint().sign < 0:
raise operationerrfmt(space.w_ValueError, "negative shift count")
try:
@@ -343,10 +346,9 @@
raise operationerrfmt(space.w_OverflowError,
"shift count too large")
return W_LongObject(self.num.lshift(shift))
+ descr_lshift, descr_rlshift = _make_descr_binop(_lshift)
- @delegate_other
- def descr_rshift(self, space, w_other):
- # XXX need to replicate some of the logic, to get the errors right
+ def _rshift(self, space, w_other):
if w_other.asbigint().sign < 0:
raise operationerrfmt(space.w_ValueError, "negative shift count")
try:
@@ -355,102 +357,79 @@
raise operationerrfmt(space.w_OverflowError,
"shift count too large")
return newlong(space, self.num.rshift(shift))
+ descr_rshift, descr_rrshift = _make_descr_binop(_rshift)
- @delegate_other
- def descr_floordiv(self, space, w_other):
+ def _floordiv(self, space, w_other):
try:
z = self.num.floordiv(w_other.asbigint())
except ZeroDivisionError:
raise operationerrfmt(space.w_ZeroDivisionError,
"long division or modulo by zero")
return newlong(space, z)
- descr_div = func_with_new_name(descr_floordiv, 'descr_div')
+ descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv)
- @delegate_other
- def descr_mod(self, space, w_other):
+ _div = func_with_new_name(_floordiv, '_div')
+ descr_div, descr_rdiv = _make_descr_binop(_div)
+
+ def _mod(self, space, w_other):
try:
z = self.num.mod(w_other.asbigint())
except ZeroDivisionError:
raise operationerrfmt(space.w_ZeroDivisionError,
"long division or modulo by zero")
return newlong(space, z)
+ descr_mod, descr_rmod = _make_descr_binop(_mod)
- @delegate_other
- def descr_divmod(self, space, w_other):
+ def _divmod(self, space, w_other):
try:
div, mod = self.num.divmod(w_other.asbigint())
except ZeroDivisionError:
raise operationerrfmt(space.w_ZeroDivisionError,
"long division or modulo by zero")
return space.newtuple([newlong(space, div), newlong(space, mod)])
+ descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
- #@delegate_other # XXX:
@unwrap_spec(w_modulus=WrappedDefault(None))
def descr_pow(self, space, w_exponent, w_modulus=None):
- if space.isinstance_w(w_exponent, space.w_int):
- w_exponent = _delegate_Int2Long(space, w_exponent)
- elif not space.isinstance_w(w_exponent, space.w_long):
+ if isinstance(w_exponent, W_AbstractIntObject):
+ w_exponent = w_exponent.descr_long(space)
+ elif not isinstance(w_exponent, W_AbstractLongObject):
return space.w_NotImplemented
- assert isinstance(w_exponent, W_AbstractLongObject)
- #if space.is_none(w_modulus):
- # from pypy.objspace.std.floatobject import delegate_Long2Float
- # self = delegate_Long2Float(space, self)
- # w_exponent = delegate_Long2Float(space, w_exponent)
- # return space.pow(self, w_exponent, w_modulus)
- #elif space.isinstance_w(w_modulus, space.w_int):
if space.is_none(w_modulus):
- # XXX need to replicate some of the logic, to get the errors right
if w_exponent.asbigint().sign < 0:
- from pypy.objspace.std.floatobject import delegate_Long2Float
- w_exponent = delegate_Long2Float(space, w_exponent)
- # XXX: hack around multimethod annoyances for now (when
- # w_modulus=None)
- return space.pow(self.descr_float(space), w_exponent, space.w_None if w_modulus is None else w_modulus)
- return W_LongObject(self.num.pow(w_exponent.asbigint(), None))
- elif space.isinstance_w(w_modulus, space.w_int):
- w_modulus = _delegate_Int2Long(space, w_modulus)
- #elif space.is_none(w_modulus):
- # # XXX need to replicate some of the logic, to get the errors right
- # if w_exponent.num.sign < 0:
- # return space.pow(self.descr_float(space), w_exponent, w_modulus)
- # return W_LongObject(self.num.pow(w_exponent.num, None))
- elif not space.isinstance_w(w_modulus, space.w_long):
+ 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
- assert isinstance(w_modulus, W_AbstractLongObject)
if w_exponent.asbigint().sign < 0:
- raise OperationError(
- space.w_TypeError,
- space.wrap(
- "pow() 2nd argument "
- "cannot be negative when 3rd argument specified"))
+ raise operationerrfmt(space.w_TypeError,
+ "pow() 2nd argument cannot be negative when "
+ "3rd argument specified")
try:
- return W_LongObject(self.num.pow(w_exponent.asbigint(),
- w_modulus.asbigint()))
+ result = self.num.pow(w_exponent.asbigint(), w_modulus.asbigint())
except ValueError:
- raise OperationError(space.w_ValueError,
- space.wrap("pow 3rd argument cannot be 0"))
+ 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_exponent, w_modulus=None):
- if space.isinstance_w(w_exponent, space.w_int):
- w_exponent = _delegate_Int2Long(space, w_exponent)
- elif not space.isinstance_w(w_exponent, space.w_long):
+ 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
- ### XXX: these may needs all the checks above has. annoying
- #if not space.isinstance_w(w_exponent, space.w_long):
- # return space.w_NotImplemented
- # XXX:
- return space.pow(w_exponent, self, w_modulus)
-
- def descr_getnewargs(self, space):
- return space.newtuple([W_LongObject(self.num)])
+ return w_base.descr_pow(space, self, w_modulus)
def newlong(space, bigint):
- """Turn the bigint into a W_LongObject. If withsmalllong is enabled,
- check if the bigint would fit in a smalllong, and return a
+ """Turn the bigint into a W_LongObject. If withsmalllong is
+ enabled, check if the bigint would fit in a smalllong, and return a
W_SmallLongObject instead if it does.
"""
if space.config.objspace.std.withsmalllong:
@@ -464,67 +443,6 @@
return W_LongObject(bigint)
-# register implementations of ops that recover int op overflows
-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)
-
-# XXX:
-# binary ops
-for opname in ['add', 'sub', 'mul', 'div', 'floordiv', 'truediv', 'mod',
- 'divmod', 'lshift']:
- exec compile("""
-def %(opname)s_ovr__Int_Int(space, w_int1, w_int2):
- if recover_with_smalllong(space) and %(opname)r != 'truediv':
- from pypy.objspace.std.smalllongobject import %(opname)s_ovr
- return %(opname)s_ovr(space, w_int1, w_int2)
- w_long1 = _delegate_Int2Long(space, w_int1)
- w_long2 = _delegate_Int2Long(space, w_int2)
- #return %(opname)s__Long_Long(space, w_long1, w_long2)
- return w_long1.descr_%(opname)s(space, w_long2)
-""" % {'opname': opname}, '', 'exec')
-
- getattr(model.MM, opname).register(globals()['%s_ovr__Int_Int' % opname],
- W_IntObject, W_IntObject, order=1)
-
-# unary ops
-for opname in ['neg', 'abs']:
- exec """
-def %(opname)s_ovr__Int(space, w_int1):
- if recover_with_smalllong(space):
- from pypy.objspace.std.smalllongobject import %(opname)s_ovr
- return %(opname)s_ovr(space, w_int1)
- w_long1 = _delegate_Int2Long(space, w_int1)
- #return %(opname)s__Long(space, w_long1)
- return w_long1.descr_%(opname)s(space)
-""" % {'opname': opname}
-
- getattr(model.MM, opname).register(globals()['%s_ovr__Int' % opname],
- W_IntObject, order=1)
-
-# pow
-def pow_ovr__Int_Int_None(space, w_int1, w_int2, w_none3):
- if recover_with_smalllong(space):
- from pypy.objspace.std.smalllongobject import pow_ovr
- return pow_ovr(space, w_int1, w_int2)
- w_long1 = _delegate_Int2Long(space, w_int1)
- w_long2 = _delegate_Int2Long(space, w_int2)
- #return pow__Long_Long_None(space, w_long1, w_long2, w_none3)
- return w_long1.descr_pow(space, w_long2, w_none3)
-
-def pow_ovr__Int_Int_Long(space, w_int1, w_int2, w_long3):
- w_long1 = _delegate_Int2Long(space, w_int1)
- w_long2 = _delegate_Int2Long(space, w_int2)
- #return pow__Long_Long_Long(space, w_long1, w_long2, w_long3)
- return w_long1.descr_pow(space, w_long2, w_long3)
-
-model.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject,
- W_NoneObject, order=1)
-model.MM.pow.register(pow_ovr__Int_Int_Long, W_IntObject, W_IntObject,
- W_LongObject, order=1)
-
-
@unwrap_spec(w_x=WrappedDefault(0))
def descr__new__(space, w_longtype, w_x, w_base=None):
if space.config.objspace.std.withsmalllong:
@@ -580,8 +498,9 @@
try:
s = space.str_w(w_value)
except OperationError:
- msg = "long() can't convert non-string with explicit base"
- raise operationerrfmt(space.w_TypeError, msg)
+ raise operationerrfmt(space.w_TypeError,
+ "long() can't convert non-string with "
+ "explicit base")
return string_to_w_long(space, w_longtype, s, base)
@@ -633,7 +552,6 @@
conjugate = interp2app(W_AbstractLongObject.descr_conjugate),
bit_length = interp2app(W_AbstractLongObject.descr_bit_length),
- # XXX: likely need indirect everything for SmallLong
__int__ = interpindirect2app(W_AbstractLongObject.int),
__long__ = interpindirect2app(W_AbstractLongObject.descr_long),
__index__ = interpindirect2app(W_AbstractLongObject.descr_index),
@@ -678,14 +596,20 @@
__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),
- # XXX: all these need r sides
__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),
__mod__ = interpindirect2app(W_AbstractLongObject.descr_mod),
+ __rmod__ = interpindirect2app(W_AbstractLongObject.descr_rmod),
__divmod__ = interpindirect2app(W_AbstractLongObject.descr_divmod),
+ __rdivmod__ = interpindirect2app(W_AbstractLongObject.descr_rdivmod),
__pow__ = interpindirect2app(W_AbstractLongObject.descr_pow),
__rpow__ = interpindirect2app(W_AbstractLongObject.descr_rpow),
diff --git a/pypy/objspace/std/marshal_impl.py b/pypy/objspace/std/marshal_impl.py
--- a/pypy/objspace/std/marshal_impl.py
+++ b/pypy/objspace/std/marshal_impl.py
@@ -28,6 +28,7 @@
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.typeobject import W_TypeObject
from pypy.objspace.std.longobject import W_LongObject, newlong
+from pypy.objspace.std.smalllongobject import W_SmallLongObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.unicodeobject import W_UnicodeObject
@@ -211,7 +212,7 @@
m.start(TYPE_LONG)
SHIFT = 15
MASK = (1 << SHIFT) - 1
- num = w_long.num
+ num = w_long.asbigint()
sign = num.sign
num = num.abs()
total_length = (num.bit_length() + (SHIFT - 1)) / SHIFT
@@ -221,6 +222,7 @@
next = num.abs_rshift_and_mask(bigshiftcount, MASK)
m.put_short(next)
bigshiftcount += SHIFT
+marshal_w__SmallLong = marshal_w__Long
def unmarshal_Long(space, u, tc):
from rpython.rlib.rbigint import rbigint
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
@@ -39,7 +39,6 @@
from pypy.objspace.std.bytearraytype import bytearray_typedef
from pypy.objspace.std.typeobject import type_typedef
from pypy.objspace.std.slicetype import slice_typedef
- #from pypy.objspace.std.longtype import long_typedef
from pypy.objspace.std.unicodetype import unicode_typedef
from pypy.objspace.std.nonetype import none_typedef
self.pythontypes = [value for key, value in result.__dict__.items()
@@ -86,8 +85,10 @@
# the set of implementation types
self.typeorder = {
objectobject.W_ObjectObject: [],
+ # XXX: Bool/Int/Long are pythontypes but still included here
+ # for delegation to Float/Complex
boolobject.W_BoolObject: [],
- intobject.W_IntObject: [], # XXX: (And self.typeorder[intobject] below)
+ intobject.W_IntObject: [],
floatobject.W_FloatObject: [],
stringobject.W_StringObject: [],
bytearrayobject.W_BytearrayObject: [],
@@ -108,7 +109,6 @@
if option.startswith("with") and option in option_to_typename:
for classname in option_to_typename[option]:
modname = classname[:classname.index('.')]
- if modname == 'smalllongobject': continue # XXX:
classname = classname[classname.index('.')+1:]
d = {}
exec "from pypy.objspace.std.%s import %s" % (
@@ -136,26 +136,16 @@
# XXX build these lists a bit more automatically later
self.typeorder[boolobject.W_BoolObject] += [
-# (intobject.W_IntObject, boolobject.delegate_Bool2IntObject),
(floatobject.W_FloatObject, floatobject.delegate_Bool2Float),
-# (longobject.W_LongObject, longobject.delegate_Bool2Long),
(complexobject.W_ComplexObject, complexobject.delegate_Bool2Complex),
]
self.typeorder[intobject.W_IntObject] += [
(floatobject.W_FloatObject, floatobject.delegate_Int2Float),
-# (longobject.W_LongObject, longobject.delegate_Int2Long),
(complexobject.W_ComplexObject, complexobject.delegate_Int2Complex),
]
- if False and config.objspace.std.withsmalllong:
+ if config.objspace.std.withsmalllong:
from pypy.objspace.std import smalllongobject
- self.typeorder[boolobject.W_BoolObject] += [
- (smalllongobject.W_SmallLongObject, smalllongobject.delegate_Bool2SmallLong),
- ]
- self.typeorder[intobject.W_IntObject] += [
- (smalllongobject.W_SmallLongObject, smalllongobject.delegate_Int2SmallLong),
- ]
self.typeorder[smalllongobject.W_SmallLongObject] += [
- (longobject.W_LongObject, smalllongobject.delegate_SmallLong2Long),
(floatobject.W_FloatObject, smalllongobject.delegate_SmallLong2Float),
(complexobject.W_ComplexObject, smalllongobject.delegate_SmallLong2Complex),
]
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
@@ -7,15 +7,14 @@
from rpython.rlib.rarithmetic import LONGLONG_BIT, intmask, r_longlong, r_uint
from rpython.rlib.rbigint import rbigint
-from rpython.tool.sourcetools import func_with_new_name
+from rpython.tool.sourcetools import func_renamer, func_with_new_name
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import operationerrfmt
from pypy.interpreter.gateway import WrappedDefault, unwrap_spec
-from pypy.objspace.std.multimethod import FailedToImplementArgs
+from pypy.objspace.std.intobject import W_AbstractIntObject
from pypy.objspace.std.longobject import W_AbstractLongObject, W_LongObject
-from pypy.objspace.std.intobject import _delegate_Int2Long
-LONGLONG_MIN = r_longlong((-1) << (LONGLONG_BIT-1))
+LONGLONG_MIN = r_longlong(-1 << (LONGLONG_BIT - 1))
class W_SmallLongObject(W_AbstractLongObject):
@@ -48,21 +47,20 @@
b = intmask(a)
if b == a:
return b
- else:
- raise OperationError(space.w_OverflowError, space.wrap(
- "long int too large to convert to int"))
+ raise operationerrfmt(space.w_OverflowError,
+ "long int too large to convert to int")
def uint_w(self, space):
a = self.longlong
if a < 0:
- raise OperationError(space.w_ValueError, space.wrap(
- "cannot convert negative integer to unsigned int"))
+ raise operationerrfmt(space.w_ValueError,
+ "cannot convert negative integer to "
+ "unsigned int")
b = r_uint(a)
if r_longlong(b) == a:
return b
- else:
- raise OperationError(space.w_OverflowError, space.wrap(
- "long int too large to convert to unsigned int"))
+ raise operationerrfmt(space.w_OverflowError,
+ "long int too large to convert to unsigned int")
def bigint_w(self, space):
return self.asbigint()
@@ -73,37 +71,32 @@
def int(self, space):
a = self.longlong
b = intmask(a)
- if b == a:
- return space.newint(b)
- else:
- return self
+ return space.newint(b) if b == a else self
def descr_long(self, space):
- # XXX: do subclasses never apply here?
- return self
- 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')
-
- def descr_index(self, space):
- return self
+ if space.is_w(space.type(self), space.w_long):
+ return self
+ return W_SmallLongObject(self.longlong)
+ descr_index = descr_trunc = descr_pos = descr_long
def descr_float(self, space):
return space.newfloat(float(self.longlong))
def _make_descr_cmp(opname):
op = getattr(operator, opname)
- def descr_impl(self, space, w_other):
- if space.isinstance_w(w_other, space.w_int):
+ bigint_op = getattr(rbigint, opname)
+ @func_renamer('descr_' + opname)
+ def descr_cmp(self, space, w_other):
+ if isinstance(w_other, W_AbstractIntObject):
result = op(self.longlong, w_other.int_w(space))
- elif not space.isinstance_w(w_other, space.w_long):
+ elif not isinstance(w_other, W_AbstractLongObject):
return space.w_NotImplemented
elif isinstance(w_other, W_SmallLongObject):
result = op(self.longlong, w_other.longlong)
else:
- result = getattr(self.asbigint(), opname)(w_other.num)
+ result = bigint_op(self.asbigint(), w_other.asbigint())
return space.newbool(result)
- return func_with_new_name(descr_impl, "descr_" + opname)
+ return descr_cmp
descr_lt = _make_descr_cmp('lt')
descr_le = _make_descr_cmp('le')
@@ -113,50 +106,51 @@
descr_ge = _make_descr_cmp('ge')
def _make_descr_binop(func):
- # XXX: so if w_other is Long, what do we do? sigh
- # how to handle delegation with descr_add on longobject?
opname = func.__name__[1:]
- methname = opname + '_' if opname in ('and', 'or') else opname
+ descr_name = 'descr_' + opname
+ descr_rname = 'descr_r' + opname
- def descr_impl(self, space, w_other):
- if space.isinstance_w(w_other, space.w_int):
+ @func_renamer(descr_name)
+ def descr_binop(self, space, w_other):
+ if isinstance(w_other, W_AbstractIntObject):
w_other = delegate_Int2SmallLong(space, w_other)
- elif not space.isinstance_w(w_other, space.w_long):
+ 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(space, methname)(self, w_other)
+ return getattr(self, descr_name)(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(space, methname)(self, w_other)
+ return getattr(self, descr_name)(space, w_other)
- def descr_rimpl(self, space, w_other):
- if space.isinstance_w(w_other, space.w_int):
+ @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 space.isinstance_w(w_other, space.w_long):
+ 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(space, methname)(w_other, self)
+ return getattr(self, descr_rname)(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(space, methname)(w_other, self)
+ return getattr(self, descr_rname)(space, w_other)
- return descr_impl, descr_rimpl
+ return descr_binop, descr_rbinop
def _add(self, space, w_other):
x = self.longlong
y = w_other.longlong
z = x + y
- if ((z^x)&(z^y)) < 0:
+ if ((z ^ x) & (z ^ y)) < 0:
raise OverflowError
return W_SmallLongObject(z)
descr_add, descr_radd = _make_descr_binop(_add)
@@ -165,7 +159,7 @@
x = self.longlong
y = w_other.longlong
z = x - y
- if ((z^x)&(z^~y)) < 0:
+ if ((z ^ x) & (z ^ ~y)) < 0:
raise OverflowError
return W_SmallLongObject(z)
descr_sub, descr_rsub = _make_descr_binop(_sub)
@@ -185,11 +179,8 @@
raise OverflowError
z = 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"))
+ raise operationerrfmt(space.w_ZeroDivisionError,
+ "integer division by zero")
return W_SmallLongObject(z)
descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv)
@@ -204,11 +195,8 @@
raise OverflowError
z = 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"))
+ raise operationerrfmt(space.w_ZeroDivisionError,
+ "integer modulo by zero")
return W_SmallLongObject(z)
descr_mod, descr_rmod = _make_descr_binop(_mod)
@@ -220,136 +208,96 @@
raise OverflowError
z = 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"))
+ raise operationerrfmt(space.w_ZeroDivisionError,
+ "integer divmod by zero")
# no overflow possible
m = x % y
return space.newtuple([W_SmallLongObject(z), W_SmallLongObject(m)])
descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
- # XXX:
@unwrap_spec(w_modulus=WrappedDefault(None))
- #def descr_pow__SmallLong_Int_SmallLong(self, space, w_exponent,
def descr_pow(self, space, w_exponent, w_modulus=None):
- if space.isinstance_w(w_exponent, space.w_long):
+ if isinstance(w_exponent, W_AbstractLongObject):
self = delegate_SmallLong2Long(space, self)
- return space.pow(self, w_exponent, w_modulus)
- elif not space.isinstance_w(w_exponent, space.w_int):
+ return self.descr_pow(space, w_exponent, w_modulus)
+ elif not isinstance(w_exponent, W_AbstractIntObject):
return space.w_NotImplemented
-
- # XXX: this expects w_exponent as an int o_O
- """
- if space.isinstance_w(w_exponent, space.w_int):
- w_exponent = delegate_Int2SmallLong(space, w_exponent)
- elif not space.isinstance_w(w_exponent, space.w_long):
- return space.w_NotImplemented
- elif not isinstance(w_exponent, W_SmallLongObject):
- self = delegate_SmallLong2Long(space, self)
- return space.pow(self, w_exponent, w_modulus)
- """
if space.is_none(w_modulus):
- #return _impl_pow(space, self.longlong, w_exponent)
try:
- return _impl_pow(space, self.longlong, w_exponent)
+ return _pow_impl(space, self.longlong, w_exponent)
except ValueError:
- self = delegate_SmallLong2Float(space, self)
+ self = self.descr_float(space)
+ return space.pow(self, w_exponent, space.w_None)
except OverflowError:
self = delegate_SmallLong2Long(space, self)
- return space.pow(self, w_exponent, w_modulus)
- elif space.isinstance_w(w_modulus, space.w_int):
+ return self.descr_pow(space, w_exponent, w_modulus)
+ elif isinstance(w_modulus, W_AbstractIntObject):
w_modulus = delegate_Int2SmallLong(space, w_modulus)
- elif not space.isinstance_w(w_modulus, space.w_long):
+ elif not isinstance(w_modulus, W_AbstractLongObject):
return space.w_NotImplemented
elif not isinstance(w_modulus, W_SmallLongObject):
self = delegate_SmallLong2Long(space, self)
- #return space.pow(self, w_modulus, w_modulus)
- return space.pow(self, w_exponent, w_modulus)
+ return self.descr_pow(space, w_exponent, w_modulus)
z = w_modulus.longlong
if z == 0:
- raise OperationError(space.w_ValueError,
- space.wrap("pow() 3rd argument cannot be 0"))
+ raise operationerrfmt(space.w_ValueError,
+ "pow() 3rd argument cannot be 0")
try:
- return _impl_pow(space, self.longlong, w_exponent, z)
+ return _pow_impl(space, self.longlong, w_exponent, z)
except ValueError:
- self = delegate_SmallLong2Float(space, self)
+ self = self.descr_float(space)
+ return space.pow(self, w_exponent, w_modulus)
except OverflowError:
self = delegate_SmallLong2Long(space, self)
- return space.pow(self, w_exponent, w_modulus)
+ return self.descr_pow(space, w_exponent, w_modulus)
- # XXX:
@unwrap_spec(w_modulus=WrappedDefault(None))
- def descr_rpow(self, space, w_exponent, w_modulus=None):
- # XXX: blargh
- if space.isinstance_w(w_exponent, space.w_int):
- w_exponent = _delegate_Int2Long(space, w_exponent)
- elif not space.isinstance_w(w_exponent, space.w_long):
+ 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 space.pow(w_exponent, self, w_modulus)
+ return w_base.descr_pow(space, self, w_modulus)
- #def descr_lshift__SmallLong_Int(space, w_small1, w_int2):
- def descr_lshift(self, space, w_other):
- if space.isinstance_w(w_other, space.w_long):
- self = delegate_SmallLong2Long(space, self)
- w_other = delegate_SmallLong2Long(space, w_other)
- return space.lshift(self, w_other)
- elif not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
+ def _lshift(self, space, w_other):
a = self.longlong
- b = w_other.intval
+ # May overflow
+ b = space.int_w(w_other)
if r_uint(b) < LONGLONG_BIT: # 0 <= b < LONGLONG_BIT
- try:
- c = a << b
- if a != (c >> b):
- raise OverflowError
- except OverflowError:
- #raise FailedToImplementArgs(space.w_OverflowError,
- # space.wrap("integer left shift"))
- self = delegate_SmallLong2Long(space, self)
- w_other = _delegate_Int2Long(space, w_other)
- return space.lshift(self, w_other)
+ c = a << b
+ if a != (c >> b):
+ raise OverflowError
return W_SmallLongObject(c)
if b < 0:
- raise OperationError(space.w_ValueError,
- space.wrap("negative shift count"))
- else: #b >= LONGLONG_BIT
+ raise operationerrfmt(space.w_ValueError, "negative shift count")
+ # b >= LONGLONG_BIT
+ if a == 0:
+ return self
+ raise OverflowError
+ descr_lshift, descr_rlshift = _make_descr_binop(_lshift)
+
+ def _rshift(self, space, w_other):
+ a = self.longlong
+ # May overflow
+ b = space.int_w(w_other)
+ if r_uint(b) >= LONGLONG_BIT: # not (0 <= b < LONGLONG_BIT)
+ if b < 0:
+ raise operationerrfmt(space.w_ValueError,
+ "negative shift count")
+ # b >= LONGLONG_BIT
if a == 0:
return self
- #raise FailedToImplementArgs(space.w_OverflowError,
- # space.wrap("integer left shift"))
- self = delegate_SmallLong2Long(space, self)
- w_other = _delegate_Int2Long(space, w_other)
- return space.lshift(self, w_other)
-
- def descr_rshift(self, space, w_other):
- if space.isinstance_w(w_other, space.w_long):
- self = delegate_SmallLong2Long(space, self)
- w_other = delegate_SmallLong2Long(space, w_other)
- return space.rshift(self, w_other)
- elif not space.isinstance_w(w_other, space.w_int):
- return space.w_NotImplemented
-
- a = self.longlong
- b = w_other.intval
More information about the pypy-commit
mailing list