[issue8567] decimal module doesn't respect precedence rules for exceptional conditions
report at bugs.python.org
Thu Apr 29 14:44:36 CEST 2010
Mark Dickinson <dickinsm at gmail.com> added the comment:
Regarding the flags that should be set, the relevant portion of the specification is at the top of the page mentioned above:
For each condition, the corresponding signal in the context is given, along with the defined result. The value of the trap-enabler for each signal in the context determines whether an operation is completed after the condition is detected or whether the condition is trapped and hence not necessarily completed (see IEEE 754 §7 and §8).
Reading between the lines, I think this means that it's okay for an exception resulting from a trap to leave the flag state undefined, at least for those flags that would have been raised by the operation. (But flags that were already set before the operation should remain set; while flags corresponding to the signals that would not have been raised by the operation should not be changed.)
Section 8 if IEEE 754 backs this up to some extent. Python's decimal traps effectively provide what IEEE 754 section 8.3 calls "Immediate transfer associated with a block", a form of "immediate exception handling". Note 2 in that section says:
[...] If the indicated exception is signaled in the associated block, causing execution of the handler block or transfer of control, then the state of the corresponding status flag might not be deterministic.
This doesn't *exactly* apply here, since it's really talking about a sequence of primitive operations rather than a single primitive operation, but it's close. (One might reasonably ask that primitive operations be regarded as atomic, so act as though all relevant flags are set, and only *then* are any relevant traps raised. This would not be a trivial change, however.)
In spite of this indeterminacy, it would still be nice to have clear rules about what Python's decimal module actually does, even if those rules are only for developer consumption.
The simplest (and closest to what's already implemented) would be the following:
- any particular operation (i.e. operands + function) determines uniquely some set of signals; the decimal specification gives us an ordering on those signals.
- the result of the operation should be as if we go through those signals one-by-one in order, and for each signal:
(a) if the signal is trapped, raise the corresponding exception
(b) else set the corresponding flag, and move on to the next signal.
Example to clarify these rules: the overflow example above produces the signals [Overflow, Inexact, Rounded] in that order. If 'Overflow' is trapped, the Overflow exception is raised and no flags are set. Otherwise, if 'Inexact' is trapped, the Inexact exception is raised and the 'Overflow' flag is set. Otherwise, if 'Rounded' is trapped, the Rounded exception is raised and the 'Overflow' and 'Inexact' flags will have been set. Otherwise, no exception is raised and all three flags are set.
Python tracker <report at bugs.python.org>
More information about the Python-bugs-list