This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Decimal module flags undetermined when a signal is trapped.
Type: behavior Stage: resolved
Components: Versions:
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: eric.araujo, facundobatista, foehn of blue, mark.dickinson, rhettinger, skrah
Priority: normal Keywords:

Created on 2010-05-04 14:53 by mark.dickinson, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (8)
msg104945 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-05-04 14:53
In an effort to keep to one issue per tracker item, I'm pulling this issue out of the comments on issue 8567.

Issue:  if a Decimal operation raises several signals, and one or more of those signals is trapped, how should that operation affect flags?

Decimal currently ends up setting some or none of those flags, depending on exactly which signal is trapped first.

Stefan points out that cdecimal and decnumber both treat all operations as atomic:  *all* flags relevant to that operation are set, and only then are any traps acted on.

The specification isn't clear on this.  At http://speleotrove.com/decimal/daexcep.html it says:

"""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)."""

There's also this (thanks, Stefan), in http://speleotrove.com/decimal/damodel.html

"""For each of the signals, the corresponding flag is set to 1 when the signal occurs. It is only reset to 0 by explicit user action."""

However, this doesn't really help: do we regard signals as being raised one-by-one during (or at the end of) an operation, or all at once?  And should a trap take effect the moment a signal is handled, or should all traps be delayed until the end of an operation?
msg105014 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2010-05-05 12:15
I agree that the spec is not unambiguous, but consider the Overflow and
Underflow passages here:

http://speleotrove.com/decimal/daexcep.html

  ==> Overflow

    ==> In all cases, Inexact and Rounded will also be raised.


"Raise" here of course means raising the flags Inexact and Rounded,
not Python exceptions. So I would think that if the overflow trap
handler is engaged, the flags Inexact and Rounded must be raised (set
to 1) in the context.
msg105017 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-05-05 12:27
Yes, that's a good point.  It would be nice for e.g. "Inexact => Rounded" invariants to be, well, invariant.

I agree that the cdecimal behaviour is the correct one.  I'm looking for wiggle room here because I don't really want to make a set of complicated and possibly performance-degrading changes to the decimal module unless it's really necessary for correctness.

Having said that, I can see at least one reasonable way of fixing this in the decimal module:

(1) Create a "delay_traps" context manager, so that:

with delay_traps():
    <do arithmetic>

disables traps for the duration of the with block, keeps track of all flags set (disregarding those set before the with block was entered), and then on leaving the with block re-raises signals corresponding to the traps set in the original context (respecting precedence, of course).

(2) Also create a "_delayed_traps" (names could do with improvement, probably) decorator that effectively wraps an entire function in 'with delay_traps()"

(3) Decorate all the primitive decimal operations with this decorator.

Thoughts?
msg105379 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-05-09 11:41
Hmm.  The 'delay_traps' context manager idea doesn't quite work here.  A problem occurs if (for example) an Overflow occurs during the with block;  in that case, Overflow should be raised at the end of the with block.  That's fine, except that we no longer know what sign it should be raised with---the flags accumulated in the temporary context that's active within the with block don't remember this information.  So something more elaborate (though probably still along the same lines) would be necessary.

The decimal module has a major defect that's making this awkward, namely that there's currently no easy way to implement custom trap handling.  A custom trap handler could simply record each exception as it occurred.  IEEE 754-2008 recommends that such trap handling exists (in section 8), though the language used is "should" (i.e., is recommended to), rather than "shall" (is required to).

One simple change that might help would be to have all Decimal exceptions derive from a common `DecimalException` superclass, making it easier to catch just decimal exceptions in a try-except block.
msg105380 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-05-09 11:45
Umm.  Please pretend I didn't write this:

> One simple change that might help would be to have all Decimal 
> exceptions derive from a common `DecimalException` superclass, making
> it easier to catch just decimal exceptions in a try-except block.

DecimalException already exists, of course.
msg105392 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010-05-09 12:50
Foehn, bugs.python.org is used for discussing and solving bugs in Python, not general discussion about programming. There are Web forums and IRC rooms where your question could get answered.

I will answer you, but please do not post other unrelated messages. Try the tutorials on docs.python.org/tutorial or diveintopython3.org
msg174026 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-10-28 10:31
Unassigning.
msg229308 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-10-14 16:01
This only affects the Python version and is probably not a problem
in practice.  Setting to pending, in case you want to keep it open.
History
Date User Action Args
2022-04-11 14:57:00adminsetgithub: 52859
2018-05-03 11:51:36cheryl.sabellasetstatus: pending -> closed
2014-10-14 16:01:50skrahsetstatus: open -> pending
resolution: wont fix
messages: + msg229308

stage: test needed -> resolved
2012-10-28 10:31:12mark.dickinsonsetassignee: mark.dickinson ->
messages: + msg174026
2010-05-09 12:50:27eric.araujosetnosy: + eric.araujo
messages: + msg105392
2010-05-09 12:48:50pitrousetmessages: - msg105388
2010-05-09 12:36:57foehn of bluesetnosy: + foehn of blue
messages: + msg105388
2010-05-09 11:45:38mark.dickinsonsetmessages: + msg105380
2010-05-09 11:41:05mark.dickinsonsetmessages: + msg105379
2010-05-05 12:27:58mark.dickinsonsetmessages: + msg105017
2010-05-05 12:15:32skrahsetmessages: + msg105014
2010-05-04 14:53:59mark.dickinsoncreate