classification
Title: decimal.py: minor issues && usability
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.2, Python 3.1, Python 2.7, Python 2.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: mark.dickinson Nosy List: facundobatista, mark.dickinson, rhettinger, skrah
Priority: normal Keywords:

Created on 2009-08-28 10:28 by skrah, last changed 2009-09-08 19:24 by mark.dickinson. This issue is now closed.

Messages (7)
msg92034 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2009-08-28 10:28
Hi,

a couple of minor issues:

1:
>>> c = getcontext()
>>> c.traps[InvalidOperation] = False
>>> Decimal("NaN").__int__()
Decimal('NaN')

I think the return value should be None.


2:
>>> c = getcontext()
>>> c.traps[InvalidOperation] = False
>>> Decimal("NaN").__long__()
Traceback (most recent call last):
...
RuntimeError: maximum recursion depth exceeded in cmp


3:
>>> setcontext(8)
>>> getcontext()
8

This is just a usability issue, perhaps a type check could be performed.
msg92039 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-08-28 14:26
Thanks for the reports.

Issue 1. If this is going to be changed, I'd rather see 
int(Decimal('nan')) raise ValueError (just as int(float('nan')) does) 
than return None.

Conversions from Decimal to native integers lie outside the scope of the 
standard, so there's not much help there.  However, precisely *because* 
they lie outside the standard, it seems wrong to be raising a Decimal 
exception (Decimal.InvalidContext) here.  It's also inconsistent with 
the treatment of infinities:  int(Decimal('infinity')) currently gives 
an OverflowError.

Given the lack of guidance from the decimal standard, the next place to 
turn is probably IEEE 754.  IEEE 754-2008, section 5.8 ("Details of 
conversions from floating-point to integer formats") says: 

"""When a NaN or infinite operand cannot be represented in the 
destination format and this cannot otherwise be indicated, the invalid 
operation exception shall be signaled."""

As far as I can tell, when the invalid-operation trap is disabled, the 
return value is undefined in this case (see 7.2(i) in IEEE 754-2008).

But in Python this error condition *can* 'otherwise be indicated', by 
raising a suitable Python exception.  So I propose changing the decimal 
module in 2.7 and 3.2 so that int(Decimal('nan')) and 
long(Decimal('nan')) raise ValueError.

Raymond, Facundo:  any thoughts on this?


Issue 2. A clear bug; will fix.  Thanks.


Issue 3. I can't see how this could cause any real problems, since you'd 
get an error as soon as you tried to use a bogus context.  Further, an 
explicit typecheck goes against Python's duck-typing philosophy:  a 
suitably crazy and misguided person ought to be able to create their own 
'quacks like a context' class, not necessarily inheriting from 
Decimal.Context, and pass this into setcontext in place of a real 
context.  I'm -0 on changing this.
msg92262 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2009-09-04 18:41
Issue 1: +1 to raise ValueError

Issue 3: -0 to change actual behaviour

Thanks!
msg92368 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2009-09-07 15:27
[...]
> But in Python this error condition *can* 'otherwise be indicated', by 
> raising a suitable Python exception.  So I propose changing the decimal 
> module in 2.7 and 3.2 so that int(Decimal('nan')) and 
> long(Decimal('nan')) raise ValueError.

Excellent analysis, I would be very much in favour of this.

> Issue 3. I can't see how this could cause any real problems, since you'd 
> get an error as soon as you tried to use a bogus context.  Further, an 
> explicit typecheck goes against Python's duck-typing philosophy:  a 
> suitably crazy and misguided person ought to be able to create their own 
> 'quacks like a context' class, not necessarily inheriting from 
> Decimal.Context, and pass this into setcontext in place of a real 
> context.  I'm -0 on changing this.

Agreed, it's not really important.
msg92380 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-09-07 18:09
Fixed __long__ bug and changed behaviour of int(Decimal('nan')) in r74708 
(trunk), r74709 (py3k).  I still need to fix the __long__ bug in the 
release branches.
msg92381 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-09-07 18:12
On second thoughts, I'm going to call this a bug and backport to 2.6 and 
3.1.
msg92426 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-09-08 19:24
Fixed in r74719 (release26-maint), r74720 (release31-maint).
History
Date User Action Args
2009-09-08 19:24:42mark.dickinsonsetstatus: open -> closed
versions: + Python 2.6, Python 3.1, Python 2.7, Python 3.2
messages: + msg92426

resolution: fixed
stage: resolved
2009-09-07 18:12:30mark.dickinsonsetmessages: + msg92381
2009-09-07 18:09:54mark.dickinsonsetmessages: + msg92380
2009-09-07 15:27:56skrahsetmessages: + msg92368
2009-09-04 18:41:36facundobatistasetmessages: + msg92262
2009-08-28 14:26:59mark.dickinsonsetpriority: normal

nosy: + rhettinger, facundobatista
messages: + msg92039

type: behavior
2009-08-28 12:33:48mark.dickinsonsetassignee: mark.dickinson

nosy: + mark.dickinson
2009-08-28 10:28:26skrahcreate