[pypy-svn] r71824 - in pypy/trunk/pypy/rpython/lltypesystem/module: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Mar 5 19:26:58 CET 2010
Author: arigo
Date: Fri Mar 5 19:26:57 2010
New Revision: 71824
Modified:
pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py
pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py
Log:
Test and fix. On Mac OS/X, this triggers a use case
where the C function ldexp() fails to set errno=ERANGE
in case it overflows, but where we still really want
the OverflowError from RPython.
Modified: pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py (original)
+++ pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py Fri Mar 5 19:26:57 2010
@@ -7,6 +7,7 @@
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib import rposix
from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rlib.rarithmetic import isinf
math_frexp = rffi.llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE,
sandboxsafe=True)
@@ -26,16 +27,24 @@
def ll_math_frexp(x):
exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
- mantissa = math_frexp(x, exp_p)
- exponent = rffi.cast(lltype.Signed, exp_p[0])
- lltype.free(exp_p, flavor='raw')
+ try:
+ _error_reset()
+ mantissa = math_frexp(x, exp_p)
+ _check_error(mantissa)
+ exponent = rffi.cast(lltype.Signed, exp_p[0])
+ finally:
+ lltype.free(exp_p, flavor='raw')
return (mantissa, exponent)
def ll_math_modf(x):
intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw')
- fracpart = math_modf(x, intpart_p)
- intpart = intpart_p[0]
- lltype.free(intpart_p, flavor='raw')
+ try:
+ _error_reset()
+ fracpart = math_modf(x, intpart_p)
+ _check_error(fracpart)
+ intpart = intpart_p[0]
+ finally:
+ lltype.free(intpart_p, flavor='raw')
return (fracpart, intpart)
def ll_math_ldexp(x, exp):
@@ -50,6 +59,8 @@
ERANGE = errno.ERANGE
def _check_error(x):
errno = rposix.get_errno()
+ if isinf(x):
+ errno = ERANGE
if errno:
if errno == ERANGE:
if not x:
Modified: pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original)
+++ pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py Fri Mar 5 19:26:57 2010
@@ -45,3 +45,26 @@
# underflows give 0.0 with no exception raised
assert f(1.0, -10000) == 0.0 # sanity-check the host Python
assert self.interpret(f, [1.0, -10000]) == 0.0
+
+ def test_overflow_1(self):
+ # this (probably, depending on platform) tests the case
+ # where the C function pow() sets ERANGE.
+ def f(x, y):
+ try:
+ return math.pow(x, y)
+ except OverflowError:
+ return -42.0
+
+ assert self.interpret(f, [10.0, 40000.0]) == -42.0
+
+ def test_overflow_2(self):
+ # this (not on Linux but on Mac OS/X at least) tests the case
+ # where the C function ldexp() does not set ERANGE, but
+ # returns +infinity.
+ def f(x, y):
+ try:
+ return math.ldexp(x, y)
+ except OverflowError:
+ return -42.0
+
+ assert self.interpret(f, [10.0, 40000]) == -42.0
More information about the Pypy-commit
mailing list