[pypy-commit] pypy remove-remaining-smm: Kill float's binary SMMs.
Manuel Jacob
noreply at buildbot.pypy.org
Mon Feb 24 02:52:51 CET 2014
Author: Manuel Jacob
Branch: remove-remaining-smm
Changeset: r69322:c12626ccdd0a
Date: 2014-02-24 02:07 +0100
http://bitbucket.org/pypy/pypy/changeset/c12626ccdd0a/
Log: Kill float's binary SMMs.
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
@@ -7,7 +7,6 @@
from pypy.interpreter.typedef import GetSetProperty
from pypy.objspace.std import newformat
from pypy.objspace.std.longobject import W_LongObject
-from pypy.objspace.std.multimethod import FailedToImplementArgs
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
@@ -314,6 +313,160 @@
w_float = space.wrap(sign * value)
return space.call_function(w_cls, w_float)
+ def _to_float(self, space, w_obj):
+ if isinstance(w_obj, W_FloatObject):
+ return w_obj
+ if space.isinstance_w(w_obj, space.w_int):
+ return W_FloatObject(float(w_obj.intval))
+ if space.isinstance_w(w_obj, space.w_long):
+ return W_FloatObject(w_obj.tofloat(space))
+
+ def descr_coerce(self, space, w_other):
+ w_other = self._to_float(space, w_other)
+ if w_other is None:
+ return space.w_NotImplemented
+ return space.newtuple([self, w_other])
+
+ def descr_add(self, space, w_rhs):
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return W_FloatObject(self.floatval + w_rhs.floatval)
+
+ def descr_radd(self, space, w_lhs):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return W_FloatObject(w_lhs.floatval + self.floatval)
+
+ def descr_sub(self, space, w_rhs):
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return W_FloatObject(self.floatval - w_rhs.floatval)
+
+ def descr_rsub(self, space, w_lhs):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return W_FloatObject(w_lhs.floatval - self.floatval)
+
+ def descr_mul(self, space, w_rhs):
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return W_FloatObject(self.floatval * w_rhs.floatval)
+
+ def descr_rmul(self, space, w_lhs):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return W_FloatObject(w_lhs.floatval * self.floatval)
+
+ def descr_div(self, space, w_rhs):
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ rhs = w_rhs.floatval
+ if rhs == 0.0:
+ raise OperationError(space.w_ZeroDivisionError, space.wrap("float division"))
+ return W_FloatObject(self.floatval / rhs)
+
+ def descr_rdiv(self, space, w_lhs):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ lhs = w_lhs.floatval
+ if lhs == 0.0:
+ raise OperationError(space.w_ZeroDivisionError, space.wrap("float division"))
+ return W_FloatObject(lhs / self.floatval)
+
+ def descr_floordiv(self, space, w_rhs):
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return _divmod_w(space, self, w_rhs)[0]
+
+ def descr_rfloordiv(self, space, w_lhs):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return _divmod_w(space, w_lhs, self)[0]
+
+ def descr_mod(self, space, w_rhs):
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ x = self.floatval
+ y = w_rhs.floatval
+ if y == 0.0:
+ raise OperationError(space.w_ZeroDivisionError, space.wrap("float modulo"))
+ try:
+ mod = math.fmod(x, y)
+ except ValueError:
+ mod = rfloat.NAN
+ else:
+ if mod:
+ # ensure the remainder has the same sign as the denominator
+ if (y < 0.0) != (mod < 0.0):
+ mod += y
+ else:
+ # the remainder is zero, and in the presence of signed zeroes
+ # fmod returns different results across platforms; ensure
+ # it has the same sign as the denominator; we'd like to do
+ # "mod = y * 0.0", but that may get optimized away
+ mod = copysign(0.0, y)
+
+ return W_FloatObject(mod)
+
+ def descr_rmod(self, space, w_lhs):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return w_lhs.descr_mod(space, self)
+
+ def descr_divmod(self, space, w_rhs):
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return space.newtuple(_divmod_w(space, self, w_rhs))
+
+ def descr_rdivmod(self, space, w_lhs):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return space.newtuple(_divmod_w(space, w_lhs, self))
+
+ @unwrap_spec(w_third_arg=WrappedDefault(None))
+ def descr_pow(self, space, w_rhs, w_third_arg):
+ # This raises FailedToImplement in cases like overflow where a
+ # (purely theoretical) big-precision float implementation would have
+ # a chance to give a result, and directly OperationError for errors
+ # that we want to force to be reported to the user.
+
+ w_rhs = self._to_float(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ if not space.is_w(w_third_arg, space.w_None):
+ raise OperationError(space.w_TypeError, space.wrap(
+ "pow() 3rd argument not allowed unless all arguments are integers"))
+ x = self.floatval
+ y = w_rhs.floatval
+
+ try:
+ result = _pow(space, x, y)
+ except PowDomainError:
+ raise oefmt(space.w_ValueError,
+ "negative number cannot be raised to a fractional power")
+ return W_FloatObject(result)
+
+ @unwrap_spec(w_third_arg=WrappedDefault(None))
+ def descr_rpow(self, space, w_lhs, w_third_arg):
+ w_lhs = self._to_float(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return w_lhs.descr_pow(space, self, w_third_arg)
+
def descr_conjugate(self, space):
return space.float(self)
@@ -343,6 +496,27 @@
__new__ = interp2app(W_FloatObject.descr__new__),
__getformat__ = interp2app(W_FloatObject.descr___getformat__, as_classmethod=True),
fromhex = interp2app(W_FloatObject.descr_fromhex, as_classmethod=True),
+ __coerce__ = interp2app(W_FloatObject.descr_coerce),
+
+ __add__ = interp2app(W_FloatObject.descr_add),
+ __radd__ = interp2app(W_FloatObject.descr_radd),
+ __sub__ = interp2app(W_FloatObject.descr_sub),
+ __rsub__ = interp2app(W_FloatObject.descr_rsub),
+ __mul__ = interp2app(W_FloatObject.descr_mul),
+ __rmul__ = interp2app(W_FloatObject.descr_rmul),
+ __div__ = interp2app(W_FloatObject.descr_div),
+ __rdiv__ = interp2app(W_FloatObject.descr_rdiv),
+ __truediv__ = interp2app(W_FloatObject.descr_div),
+ __rtruediv__ = interp2app(W_FloatObject.descr_rdiv),
+ __floordiv__ = interp2app(W_FloatObject.descr_floordiv),
+ __rfloordiv__ = interp2app(W_FloatObject.descr_rfloordiv),
+ __mod__ = interp2app(W_FloatObject.descr_mod),
+ __rmod__ = interp2app(W_FloatObject.descr_rmod),
+ __divmod__ = interp2app(W_FloatObject.descr_divmod),
+ __rdivmod__ = interp2app(W_FloatObject.descr_rdivmod),
+ __pow__ = interp2app(W_FloatObject.descr_pow),
+ __rpow__ = interp2app(W_FloatObject.descr_rpow),
+
conjugate = interp2app(W_FloatObject.descr_conjugate),
real = GetSetProperty(W_FloatObject.descr_get_real),
imag = GetSetProperty(W_FloatObject.descr_get_imag),
@@ -351,19 +525,6 @@
W_FloatObject.typedef.registermethods(globals())
-# bool-to-float delegation
-def delegate_Bool2Float(space, w_bool):
- return W_FloatObject(float(w_bool.intval))
-
-# int-to-float delegation
-def delegate_Int2Float(space, w_intobj):
- return W_FloatObject(float(w_intobj.intval))
-
-# long-to-float delegation
-def delegate_Long2Float(space, w_longobj):
- return W_FloatObject(w_longobj.tofloat(space))
-
-
# float__Float is supposed to do nothing, unless it has
# a derived float object, where it should return
# an exact one.
@@ -613,67 +774,11 @@
return x
-# coerce
-def coerce__Float_Float(space, w_float1, w_float2):
- return space.newtuple([w_float1, w_float2])
-
-
-def add__Float_Float(space, w_float1, w_float2):
- x = w_float1.floatval
- y = w_float2.floatval
- return W_FloatObject(x + y)
-
-def sub__Float_Float(space, w_float1, w_float2):
- x = w_float1.floatval
- y = w_float2.floatval
- return W_FloatObject(x - y)
-
-def mul__Float_Float(space, w_float1, w_float2):
- x = w_float1.floatval
- y = w_float2.floatval
- return W_FloatObject(x * y)
-
-def div__Float_Float(space, w_float1, w_float2):
- x = w_float1.floatval
- y = w_float2.floatval
- if y == 0.0:
- raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float division"))
- return W_FloatObject(x / y)
-
-truediv__Float_Float = div__Float_Float
-
-def floordiv__Float_Float(space, w_float1, w_float2):
- w_div, w_mod = _divmod_w(space, w_float1, w_float2)
- return w_div
-
-def mod__Float_Float(space, w_float1, w_float2):
- x = w_float1.floatval
- y = w_float2.floatval
- if y == 0.0:
- raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float modulo"))
- try:
- mod = math.fmod(x, y)
- except ValueError:
- mod = rfloat.NAN
- else:
- if mod:
- # ensure the remainder has the same sign as the denominator
- if (y < 0.0) != (mod < 0.0):
- mod += y
- else:
- # the remainder is zero, and in the presence of signed zeroes
- # fmod returns different results across platforms; ensure
- # it has the same sign as the denominator; we'd like to do
- # "mod = y * 0.0", but that may get optimized away
- mod = copysign(0.0, y)
-
- return W_FloatObject(mod)
-
def _divmod_w(space, w_float1, w_float2):
x = w_float1.floatval
y = w_float2.floatval
if y == 0.0:
- raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float modulo"))
+ raise OperationError(space.w_ZeroDivisionError, space.wrap("float modulo"))
try:
mod = math.fmod(x, y)
except ValueError:
@@ -709,27 +814,6 @@
return [W_FloatObject(floordiv), W_FloatObject(mod)]
-def divmod__Float_Float(space, w_float1, w_float2):
- return space.newtuple(_divmod_w(space, w_float1, w_float2))
-
-def pow__Float_Float_ANY(space, w_float1, w_float2, thirdArg):
- # This raises FailedToImplement in cases like overflow where a
- # (purely theoretical) big-precision float implementation would have
- # a chance to give a result, and directly OperationError for errors
- # that we want to force to be reported to the user.
- if not space.is_w(thirdArg, space.w_None):
- raise OperationError(space.w_TypeError, space.wrap(
- "pow() 3rd argument not allowed unless all arguments are integers"))
- x = w_float1.floatval
- y = w_float2.floatval
-
- try:
- result = _pow(space, x, y)
- except PowDomainError:
- raise oefmt(space.w_ValueError,
- "negative number cannot be raised to a fractional power")
- return W_FloatObject(result)
-
class PowDomainError(ValueError):
"""Signals a negative number raised to a fractional power"""
@@ -810,7 +894,7 @@
# We delegate to our implementation of math.pow() the error detection.
z = math.pow(x,y)
except OverflowError:
- raise FailedToImplementArgs(space.w_OverflowError,
+ raise OperationError(space.w_OverflowError,
space.wrap("float power"))
except ValueError:
raise OperationError(space.w_ValueError,
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
@@ -133,21 +133,12 @@
# when trying to dispatch multimethods.
# XXX build these lists a bit more automatically later
- self.typeorder[boolobject.W_BoolObject] += [
- (floatobject.W_FloatObject, floatobject.delegate_Bool2Float),
- ]
- self.typeorder[intobject.W_IntObject] += [
- (floatobject.W_FloatObject, floatobject.delegate_Int2Float),
- ]
if config.objspace.std.withsmalllong:
from pypy.objspace.std import smalllongobject
self.typeorder[smalllongobject.W_SmallLongObject] += [
(floatobject.W_FloatObject, smalllongobject.delegate_SmallLong2Float),
(complexobject.W_ComplexObject, smalllongobject.delegate_SmallLong2Complex),
]
- self.typeorder[longobject.W_LongObject] += [
- (floatobject.W_FloatObject, floatobject.delegate_Long2Float),
- ]
if config.objspace.std.withstrbuf:
from pypy.objspace.std import strbufobject
diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py
--- a/pypy/objspace/std/test/test_floatobject.py
+++ b/pypy/objspace/std/test/test_floatobject.py
@@ -12,27 +12,27 @@
f2 = fobj.W_FloatObject(y)
f3 = fobj.W_FloatObject(z)
self.space.raises_w(self.space.w_TypeError,
- fobj.pow__Float_Float_ANY,
- self.space, f1, f2, f3)
+ f1.descr_pow,
+ self.space, f2, f3)
def test_pow_ffn(self):
x = 10.0
y = 2.0
f1 = fobj.W_FloatObject(x)
f2 = fobj.W_FloatObject(y)
- v = fobj.pow__Float_Float_ANY(self.space, f1, f2, self.space.w_None)
+ v = f1.descr_pow(self.space, f2, self.space.w_None)
assert v.floatval == x ** y
f1 = fobj.W_FloatObject(-1.23)
f2 = fobj.W_FloatObject(-4.56)
self.space.raises_w(self.space.w_ValueError,
- fobj.pow__Float_Float_ANY,
- self.space, f1, f2,
+ f1.descr_pow,
+ self.space, f2,
self.space.w_None)
x = -10
y = 2.0
f1 = fobj.W_FloatObject(x)
f2 = fobj.W_FloatObject(y)
- v = fobj.pow__Float_Float_ANY(self.space, f1, f2, self.space.w_None)
+ v = f1.descr_pow(self.space, f2, self.space.w_None)
assert v.floatval == x**y
def test_dont_use_long_impl(self):
More information about the pypy-commit
mailing list