summaryrefslogtreecommitdiffstats
path: root/Lib/decimal.py
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2004-07-09 10:02:53 (GMT)
committerRaymond Hettinger <python@rcn.com>2004-07-09 10:02:53 (GMT)
commit5aa478badfabb005e6f17c98fcf007a0bc54eecc (patch)
treeea3fdbf9730756faf600180da8b9b02229ff9c68 /Lib/decimal.py
parent563e44972922b98db06f06b81b049d1941fd43d9 (diff)
downloadcpython-5aa478badfabb005e6f17c98fcf007a0bc54eecc.zip
cpython-5aa478badfabb005e6f17c98fcf007a0bc54eecc.tar.gz
cpython-5aa478badfabb005e6f17c98fcf007a0bc54eecc.tar.bz2
Module and tests:
* Map conditions to related signals. * Make contexts unhashable. * Eliminate used "default" attribute in exception definitions. * Eliminate the _filterfunc in favor of a straight list. Docs: * Eliminate documented references to conditions that are not signals. * Eliminate parenthetical notes such as "1/0 --> Inf" which are no longer true with the new defaults.
Diffstat (limited to 'Lib/decimal.py')
-rw-r--r--Lib/decimal.py65
1 files changed, 30 insertions, 35 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py
index 4e5cbbb..9f77b24 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -78,30 +78,30 @@ Traceback (most recent call last):
...
DivisionByZero: x / 0
>>> c = Context()
->>> c.trap_enablers[DivisionUndefined] = 0
->>> print c.flags[DivisionUndefined]
+>>> c.trap_enablers[InvalidOperation] = 0
+>>> print c.flags[InvalidOperation]
0
>>> c.divide(Decimal(0), Decimal(0))
Decimal("NaN")
->>> c.trap_enablers[DivisionUndefined] = 1
->>> print c.flags[DivisionUndefined]
+>>> c.trap_enablers[InvalidOperation] = 1
+>>> print c.flags[InvalidOperation]
1
->>> c.flags[DivisionUndefined] = 0
->>> print c.flags[DivisionUndefined]
+>>> c.flags[InvalidOperation] = 0
+>>> print c.flags[InvalidOperation]
0
>>> print c.divide(Decimal(0), Decimal(0))
Traceback (most recent call last):
...
...
...
-DivisionUndefined: 0 / 0
->>> print c.flags[DivisionUndefined]
+InvalidOperation: 0 / 0
+>>> print c.flags[InvalidOperation]
1
->>> c.flags[DivisionUndefined] = 0
->>> c.trap_enablers[DivisionUndefined] = False
+>>> c.flags[InvalidOperation] = 0
+>>> c.trap_enablers[InvalidOperation] = 0
>>> print c.divide(Decimal(0), Decimal(0))
NaN
->>> print c.flags[DivisionUndefined]
+>>> print c.flags[InvalidOperation]
1
>>>
"""
@@ -152,7 +152,7 @@ ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
#Errors
class DecimalException(ArithmeticError):
- """Base exception class, defines default things.
+ """Base exception class.
Used exceptions derive from this.
If an exception derives from another exception besides this (such as
@@ -160,12 +160,6 @@ class DecimalException(ArithmeticError):
called if the others are present. This isn't actually used for
anything, though.
- Attributes:
-
- default -- If the context is basic, the trap_enablers are set to
- this by default. Extended contexts start out with them set
- to 0, regardless.
-
handle -- Called when context._raise_error is called and the
trap_enabler is set. First argument is self, second is the
context. More arguments can be given, those being after
@@ -176,7 +170,6 @@ class DecimalException(ArithmeticError):
To define a new exception, it should be sufficient to have it derive
from DecimalException.
"""
- default = 1
def handle(self, context, *args):
pass
@@ -288,7 +281,7 @@ class Inexact(DecimalException):
The inexact signal may be tested (or trapped) to determine if a given
operation (or sequence of operations) was inexact.
"""
- default = 0
+ pass
class InvalidContext(InvalidOperation):
"""Invalid context. Unknown rounding, for example.
@@ -315,7 +308,7 @@ class Rounded(DecimalException):
The rounded signal may be tested (or trapped) to determine if a given
operation (or sequence of operations) caused a loss of precision.
"""
- default = 0
+ pass
class Subnormal(DecimalException):
"""Exponent < Emin before rounding.
@@ -382,19 +375,15 @@ class Underflow(Inexact, Rounded, Subnormal):
In all cases, Inexact, Rounded, and Subnormal will also be raised.
"""
+# List of public traps and flags
+Signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
+ Underflow, InvalidOperation, Subnormal]
-def _filterfunc(obj):
- """Returns true if a subclass of DecimalException"""
- try:
- return issubclass(obj, DecimalException)
- except TypeError:
- return False
-
-#Signals holds the exceptions
-Signals = filter(_filterfunc, globals().values())
-
-del _filterfunc
-
+# Map conditions (per the spec) to signals
+_condition_map = {ConversionSyntax:InvalidOperation,
+ DivisionImpossible:InvalidOperation,
+ DivisionUndefined:InvalidOperation,
+ InvalidContext:InvalidOperation}
##### Context Functions #######################################
@@ -2168,7 +2157,7 @@ class Context(object):
return nc
__copy__ = copy
- def _raise_error(self, error, explanation = None, *args):
+ def _raise_error(self, condition, explanation = None, *args):
"""Handles an error
If the flag is in _ignored_flags, returns the default response.
@@ -2176,6 +2165,7 @@ class Context(object):
trap_enabler is set, it reaises the exception. Otherwise, it returns
the default value after incrementing the flag.
"""
+ error = _condition_map.get(condition, condition)
if error in self._ignored_flags:
#Don't touch the flag
return error().handle(self, *args)
@@ -2183,7 +2173,7 @@ class Context(object):
self.flags[error] += 1
if not self.trap_enablers[error]:
#The errors define how to handle themselves.
- return error().handle(self, *args)
+ return condition().handle(self, *args)
# Errors should only be risked on copies of the context
#self._ignored_flags = []
@@ -2207,6 +2197,11 @@ class Context(object):
for flag in flags:
self._ignored_flags.remove(flag)
+ def __hash__(self):
+ """A Context cannot be hashed."""
+ # We inherit object.__hash__, so we must deny this explicitly
+ raise TypeError, "Cannot hash a Context."
+
def Etiny(self):
"""Returns Etiny (= Emin - prec + 1)"""
return int(self.Emin - self.prec + 1)