[Python-checkins] r58138 - in python/branches/decimal-branch/Lib: decimal.py test/decimaltestdata/extra.decTest
facundo.batista
python-checkins at python.org
Thu Sep 13 16:53:40 CEST 2007
Author: facundo.batista
Date: Thu Sep 13 16:53:39 2007
New Revision: 58138
Modified:
python/branches/decimal-branch/Lib/decimal.py
python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest
Log:
Now raises TypeError instead returning NotImplemented when the function
is not __xxx__. Changed _convert_other() to be able to return a better
message and at the same time be more concise.
Modified: python/branches/decimal-branch/Lib/decimal.py
==============================================================================
--- python/branches/decimal-branch/Lib/decimal.py (original)
+++ python/branches/decimal-branch/Lib/decimal.py Thu Sep 13 16:53:39 2007
@@ -752,9 +752,7 @@
NaN => one is NaN
Like __cmp__, but returns Decimal instances.
"""
- other = _convert_other(other)
- if other is NotImplemented:
- return other
+ other = _convert_other(other, raiseit=True)
# Compare(NaN, NaN) = NaN
if (self._is_special or other and other._is_special):
@@ -1359,9 +1357,7 @@
if context is None:
context = getcontext()
- other = _convert_other(other)
- if other is NotImplemented:
- raise TypeError("Unable to convert %s to Decimal" % other)
+ other = _convert_other(other, raiseit=True)
ans = self._check_nans(other, context)
if ans:
@@ -1638,42 +1634,25 @@
and a single final rounding is performed.
"""
+ other = _convert_other(other, raiseit=True)
+ third = _convert_other(third, raiseit=True)
+
if context is None:
context = getcontext()
- other = _convert_other(other)
- if other is NotImplemented:
- return other
+ # do self*other in fresh context with no traps and no rounding
+ mul_context = Context(traps=[], flags=[],
+ _rounding_decision=NEVER_ROUND)
+ product = self.__mul__(other, mul_context)
- third = _convert_other(third)
- if third is NotImplemented:
- return third
-
- # deal correctly with NaNs:
- self_is_nan = self._isnan()
- other_is_nan = other._isnan()
- third_is_nan = third._isnan()
- if self_is_nan or other_is_nan or third_is_nan:
- if self_is_nan == 2:
- return context._raise_error(InvalidOperation, 'sNaN',
- 1, self)
- if other_is_nan == 2:
- return context._raise_error(InvalidOperation, 'sNaN',
- 1, other)
- if third_is_nan == 2:
- return context._raise_error(InvalidOperation, 'sNaN',
- 1, third)
- if self_is_nan:
- return self
- if other_is_nan:
- return other
- return third
+ if mul_context.flags[InvalidOperation]:
+ # reraise in current context
+ return context._raise_error(InvalidOperation,
+ 'invalid multiplication in fma',
+ 1, product)
- context = context._shallow_copy()
- rounding_decision = context._set_rounding_decision(NEVER_ROUND)
- product = self.__mul__(other, context)
- context._set_rounding_decision(rounding_decision)
- return product.__add__(third, context)
+ ans = product.__add__(third, context)
+ return ans
def _power_modulo(self, other, modulo, context=None):
"""Three argument version of __pow__"""
@@ -1681,17 +1660,8 @@
# if can't convert other and modulo to Decimal, raise
# TypeError; there's no point returning NotImplemented (no
# equivalent of __rpow__ for three argument pow)
- other = _convert_other(other)
- if other is NotImplemented:
- raise TypeError("The second argument to pow should be " +
- "an integer or an instance of Decimal. Got " +
- str(other))
-
- modulo = _convert_other(modulo)
- if modulo is NotImplemented:
- raise TypeError("The third argument to pow should be " +
- "an integer or an instance of Decimal. Got " +
- str(modulo))
+ other = _convert_other(other, raiseit=True)
+ modulo = _convert_other(modulo, raiseit=True)
if context is None:
context = getcontext()
@@ -2447,9 +2417,7 @@
Like max(self, other) except if one is not a number, returns
NaN (and signals if one is sNaN). Also rounds.
"""
- other = _convert_other(other)
- if other is NotImplemented:
- return other
+ other = _convert_other(other, raiseit=True)
if self._is_special or other._is_special:
# If one operand is a quiet NaN and the other is number, then the
@@ -2492,9 +2460,7 @@
Like min(self, other) except if one is not a number, returns
NaN (and signals if one is sNaN). Also rounds.
"""
- other = _convert_other(other)
- if other is NotImplemented:
- return other
+ other = _convert_other(other, raiseit=True)
if self._is_special or other._is_special:
# If one operand is a quiet NaN and the other is number, then the
@@ -3112,9 +3078,7 @@
def max_mag(self, other, context=None):
"""Compares the values numerically with their sign ignored."""
- other = _convert_other(other)
- if other is NotImplemented:
- return other
+ other = _convert_other(other, raiseit=True)
if self._is_special or other._is_special:
# If one operand is a quiet NaN and the other is number, then the
@@ -3145,9 +3109,7 @@
def min_mag(self, other, context=None):
"""Compares the values numerically with their sign ignored."""
- other = _convert_other(other)
- if other is NotImplemented:
- return other
+ other = _convert_other(other, raiseit=True)
if self._is_special or other._is_special:
# If one operand is a quiet NaN and the other is number, then the
@@ -3229,11 +3191,7 @@
numerically equal, then the result is a copy of self with the
sign set to be the same as the sign of other.
"""
- other = _convert_other(other)
- if other is NotImplemented:
- raise TypeError("The second argument to next_toward should be " +
- "an integer or an instance of Decimal. Got " +
- str(other))
+ other = _convert_other(other, raiseit=True)
if context is None:
context = getcontext()
@@ -5154,7 +5112,7 @@
##### Helper Functions ####################################################
-def _convert_other(other):
+def _convert_other(other, raiseit=False):
"""Convert other to Decimal.
Verifies that it's ok to use in an implicit construction.
@@ -5163,6 +5121,8 @@
return other
if isinstance(other, (int, long)):
return Decimal(other)
+ if raiseit:
+ raise TypeError("Unable to convert %s to Decimal" % other)
return NotImplemented
_infinity_map = {
Modified: python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest
==============================================================================
--- python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest (original)
+++ python/branches/decimal-branch/Lib/test/decimaltestdata/extra.decTest Thu Sep 13 16:53:39 2007
@@ -147,6 +147,13 @@
extr1201 scaleb 5678 0 -> 5.68E+3 Inexact Rounded
extr1202 scaleb -9105 -1 -> -910 Inexact Rounded
+-- Invalid operation from 0 * infinity in fma
+-- takes precedence over a third-argument sNaN
+extr1300 fma 0 Inf sNaN123 -> NaN Invalid_operation
+extr1301 fma Inf 0 sNaN456 -> NaN Invalid_operation
+extr1302 fma 0E123 -Inf sNaN789 -> NaN Invalid_operation
+extr1302 fma -Inf 0E-456 sNaN148 -> NaN Invalid_operation
+
------------------------------------------------------------------------
-- The following tests (pwmx0 through pwmx440) are for the --
-- three-argument version of power: --
More information about the Python-checkins
mailing list