Author: stian Branch: py3-bigint-to-int Changeset: r96071:4e3d4c68bcde Date: 2019-02-18 16:49 +0100 http://bitbucket.org/pypy/pypy/changeset/4e3d4c68bcde/
Log: Reduce this to int_mod and int_and ops for now. 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 @@ -234,23 +234,22 @@ descr_gt = _make_descr_cmp('gt') descr_ge = _make_descr_cmp('ge') - def descr_sub(self, space, w_other): - if isinstance(w_other, W_IntObject): - res = self.num.int_sub(w_other.int_w(space)) - elif not isinstance(w_other, W_AbstractLongObject): - return space.w_NotImplemented - res = self.num.sub(w_other.asbigint()) - try: - return W_IntObject(res.toint()) - except OverflowError: - return W_LongObject(res) - @delegate_other - def descr_rsub(self, space, w_other): - res = w_other.asbigint().sub(self.num) - try: - return W_IntObject(res.toint()) - except OverflowError: - return W_LongObject(res) + def _make_generic_descr_binop_noncommutative(opname): + methname = opname + '_' if opname in ('and', 'or') else opname + descr_rname = 'descr_r' + opname + op = getattr(rbigint, methname) + + @func_renamer('descr_' + opname) + @delegate_other + def descr_binop(self, space, w_other): + return W_LongObject(op(self.num, w_other.asbigint())) + + @func_renamer(descr_rname) + @delegate_other + def descr_rbinop(self, space, w_other): + return W_LongObject(op(w_other.asbigint(), self.num)) + + return descr_binop, descr_rbinop def _make_generic_descr_binop(opname): if opname not in COMMUTATIVE_OPS: @@ -264,49 +263,82 @@ @func_renamer('descr_' + opname) def descr_binop(self, space, w_other): if isinstance(w_other, W_IntObject): - res = intop(self.num, w_other.int_w(space)) + return W_LongObject(intop(self.num, w_other.int_w(space))) elif not isinstance(w_other, W_AbstractLongObject): return space.w_NotImplemented - else: - res = op(self.num, w_other.asbigint()) - try: - return W_IntObject(res.toint()) - except OverflowError: - return W_LongObject(res) + + return W_LongObject(op(self.num, w_other.asbigint())) + + @func_renamer(descr_rname) + def descr_rbinop(self, space, w_other): + if isinstance(w_other, W_IntObject): + return W_LongObject(intop(self.num, w_other.int_w(space))) + elif not isinstance(w_other, W_AbstractLongObject): + return space.w_NotImplemented + + return W_LongObject(op(w_other.asbigint(), self.num)) + + return descr_binop, descr_rbinop + + def _make_generic_descr_binop_maybeint(opname): + if opname not in COMMUTATIVE_OPS: + raise Exception("Not supported") + + methname = opname + '_' if opname in ('and', 'or') else opname + descr_rname = 'descr_r' + opname + op = getattr(rbigint, methname) + intop = getattr(rbigint, "int_" + methname) + + @func_renamer('descr_' + opname) + def descr_binop(self, space, w_other): + if isinstance(w_other, W_IntObject): + res = intop(self.num, w_other.int_w(space)) + try: + return W_IntObject(res.toint()) + except OverflowError: + return W_LongObject(res) + elif not isinstance(w_other, W_AbstractLongObject): + return space.w_NotImplemented + + return W_LongObject(op(self.num, w_other.asbigint())) @func_renamer(descr_rname) def descr_rbinop(self, space, w_other): if isinstance(w_other, W_IntObject): res = intop(self.num, w_other.int_w(space)) + try: + return W_IntObject(res.toint()) + except OverflowError: + return W_LongObject(res) elif not isinstance(w_other, W_AbstractLongObject): return space.w_NotImplemented - else: - res = op(w_other.asbigint(), self.num) - try: - return W_IntObject(res.toint()) - except OverflowError: - return W_LongObject(res) - + + return W_LongObject(op(w_other.asbigint(), self.num)) + return descr_binop, descr_rbinop - descr_add, descr_radd = _make_generic_descr_binop('add') - + descr_sub, descr_rsub = _make_generic_descr_binop_noncommutative('sub') descr_mul, descr_rmul = _make_generic_descr_binop('mul') - descr_and, descr_rand = _make_generic_descr_binop('and') + descr_and, descr_rand = _make_generic_descr_binop_maybeint('and') descr_or, descr_ror = _make_generic_descr_binop('or') descr_xor, descr_rxor = _make_generic_descr_binop('xor') - def _make_descr_binop(func, int_func): + def _make_descr_binop(func, int_func=None): opname = func.__name__[1:] - @func_renamer('descr_' + opname) - def descr_binop(self, space, w_other): - if isinstance(w_other, W_IntObject): - return int_func(self, space, w_other.int_w(space)) - elif not isinstance(w_other, W_AbstractLongObject): - return space.w_NotImplemented - return func(self, space, w_other) - + if int_func: + @func_renamer('descr_' + opname) + def descr_binop(self, space, w_other): + if isinstance(w_other, W_IntObject): + return int_func(self, space, w_other.int_w(space)) + elif not isinstance(w_other, W_AbstractLongObject): + return space.w_NotImplemented + return func(self, space, w_other) + else: + @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): @@ -324,20 +356,12 @@ shift = w_other.asbigint().toint() except OverflowError: # b too big raise oefmt(space.w_OverflowError, "shift count too large") - res = self.num.lshift(shift) - try: - return W_IntObject(res.toint()) - except OverflowError: - return W_LongObject(res) - - def _int_lshift(self, space, other): - if other < 0: + return W_LongObject(self.num.lshift(shift)) + + def _int_lshift(self, space, w_other): + if w_other < 0: raise oefmt(space.w_ValueError, "negative shift count") - res = self.num.lshift(other) - try: - return W_IntObject(res.toint()) - except OverflowError: - return W_LongObject(res) + return W_LongObject(self.num.lshift(w_other)) descr_lshift, descr_rlshift = _make_descr_binop(_lshift, _int_lshift) @@ -348,20 +372,13 @@ shift = w_other.asbigint().toint() except OverflowError: # b too big # XXX maybe just return 0L instead? raise oefmt(space.w_OverflowError, "shift count too large") - res = self.num.rshift(shift) - try: - return space.newint(res.toint()) - except OverflowError: - return newlong(space, res) + return newlong(space, self.num.rshift(shift)) - def _int_rshift(self, space, other): - if other < 0: + def _int_rshift(self, space, w_other): + if w_other < 0: raise oefmt(space.w_ValueError, "negative shift count") - res = self.num.rshift(other) - try: - return space.newint(res.toint()) - except OverflowError: - return newlong(space, res) + + return newlong(space, self.num.rshift(w_other)) descr_rshift, descr_rrshift = _make_descr_binop(_rshift, _int_rshift) def _floordiv(self, space, w_other): @@ -370,20 +387,16 @@ except ZeroDivisionError: raise oefmt(space.w_ZeroDivisionError, "long division or modulo by zero") - + return newlong(space, z) + + def _floordiv(self, space, w_other): try: - return space.newint(z.toint()) - except OverflowError: - return newlong(space, z) - - def _int_floordiv(self, space, other): - try: - z = self.num.int_floordiv(other) + z = self.num.floordiv(w_other.asbigint()) except ZeroDivisionError: raise oefmt(space.w_ZeroDivisionError, "integer division or modulo by zero") return newlong(space, z) - descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv, _int_floordiv) + descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv) def _mod(self, space, w_other): try: @@ -391,21 +404,17 @@ except ZeroDivisionError: raise oefmt(space.w_ZeroDivisionError, "integer division or modulo by zero") + return newlong(space, z) + + def _int_mod(self, space, w_other): try: - return space.newint(z.toint()) - except OverflowError: - return newlong(space, z) - - def _int_mod(self, space, other): - try: - z = self.num.int_mod(other) + z = self.num.int_mod(w_other) except ZeroDivisionError: raise oefmt(space.w_ZeroDivisionError, "long division or modulo by zero") - - # Int mod should always fit into an int. + #return newlong(space, z) + # Should always fit. return space.newint(z.toint()) - #return newlong(space, z) descr_mod, descr_rmod = _make_descr_binop(_mod, _int_mod) def _divmod(self, space, w_other): @@ -415,16 +424,7 @@ raise oefmt(space.w_ZeroDivisionError, "integer division or modulo by zero") return space.newtuple([newlong(space, div), newlong(space, mod)]) - - def _int_divmod(self, space, other): - try: - div, mod = self.num.int_divmod(other) - except ZeroDivisionError: - raise oefmt(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, _int_divmod) + descr_divmod, descr_rdivmod = _make_descr_binop(_divmod) def _hash_long(space, v): diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py --- a/pypy/objspace/std/test/test_longobject.py +++ b/pypy/objspace/std/test/test_longobject.py @@ -42,29 +42,24 @@ def test_long_to_int(self): a = lobj.W_LongObject.fromlong(8) b = lobj.W_LongObject.fromlong(1) + c = iobj.W_IntObject(1) + + modres = a.descr_mod(self.space, b) + assert type(modres) is lobj.W_LongObject - floordivres = a._floordiv(self.space, b) - assert type(floordivres) is iobj.W_IntObject + intmodres = a.descr_mod(self.space, c) + assert type(intmodres) is iobj.W_IntObject - modres = a._mod(self.space, b) - assert type(modres) is iobj.W_IntObject + andres = a.descr_and(self.space, b) + assert type(andres) is lobj.W_LongObject - # Covers all of descr_binop? - addres = a.descr_add(self.space, b) - assert type(addres) is iobj.W_IntObject + intandres = a.descr_and(self.space, c) + assert type(intandres) is iobj.W_IntObject - # Covers all of descr_rbinop? - raddres = a.descr_radd(self.space, b) - assert type(raddres) is iobj.W_IntObject + # Maybe in next round. + #intdivlongres = a.descr_rfloordiv(self.space, c) + #assert type(intdivlongres) is iobj.W_IntObject - subres = a.descr_sub(self.space, b) - assert type(subres) is iobj.W_IntObject - - lshiftres = a._lshift(self.space, b) - assert type(lshiftres) is iobj.W_IntObject - - rshiftres = a._rshift(self.space, b) - assert type(rshiftres) is iobj.W_IntObject class AppTestLong: def w__long(self, obj): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit