classification
Title: Exceptions raised by Fraction() different from those raised by int()
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: mark.dickinson Nosy List: asvetlov, casevh, ezio.melotti, kachayev, loewis, mark.dickinson, rhettinger, skrah
Priority: normal Keywords: patch

Created on 2012-11-14 06:30 by casevh, last changed 2012-11-15 22:20 by kachayev. This issue is now closed.

Files
File name Uploaded Description Edit
issue16469.diff kachayev, 2012-11-15 16:42 review
full_issues16469.diff kachayev, 2012-11-15 18:23 review
full_issues16469_fixed.diff kachayev, 2012-11-15 18:47 review
Messages (12)
msg175536 - (view) Author: Case Van Horsen (casevh) Date: 2012-11-14 06:30
When attempting to convert a float("nan"), float("inf"), or float("-inf"), fractions.Fraction() raises different exceptions than int()

>>> int(float("nan"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot convert float NaN to integer
>>> fractions.Fraction(float("nan"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/lib/python3.2/fractions.py", line 114, in __new__
    value = Fraction.from_float(numerator)
  File "/opt/local/lib/python3.2/fractions.py", line 186, in from_float
    raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
TypeError: Cannot convert nan to Fraction.
>>> int(float("inf"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: cannot convert float infinity to integer
>>> fractions.Fraction(float("inf"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/lib/python3.2/fractions.py", line 114, in __new__
    value = Fraction.from_float(numerator)
  File "/opt/local/lib/python3.2/fractions.py", line 186, in from_float
    raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
TypeError: Cannot convert inf to Fraction.
>>> int(float("-inf"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: cannot convert float infinity to integer
>>> fractions.Fraction(float("-inf"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/lib/python3.2/fractions.py", line 114, in __new__
    value = Fraction.from_float(numerator)
  File "/opt/local/lib/python3.2/fractions.py", line 186, in from_float
    raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
TypeError: Cannot convert -inf to Fraction.

Should the exceptions be changed to ValueError and OverflowError?
msg175548 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-11-14 08:23
Certainly TypeError seems inappropriate here, and using ValueError for conversions from NaN sounds good to me.

I'm not a big fan of the OverflowError for converting infinities to an integer:  nothing's actually overflowed here.  I think that should have been ValueError, too.  So either of ValueError or OverflowError works for me there.

I'd suggest fixing this for >= 3.4 only.
msg175550 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-11-14 08:43
The from_decimal method should be changed as well.
msg175570 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2012-11-14 15:09
The description of OverflowError is that is is "raised when the result of an arithmetic operation is too large to be represented", so it doesn't actually need to overflow. Still, I see that ∞ actually isn't too large to be represented (and the documentation points out that integer operations will raise MemoryError instead of OverflowError). So yes, ValueError seems more appropriate.

+1 for fixing this in 3.4, only.
msg175579 - (view) Author: Case Van Horsen (casevh) Date: 2012-11-14 17:40
Do we also want to change int(infinity) to return ValueError? I think consistent behavior between int() and Fraction() is valuable.
msg175605 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-11-15 09:30
> I think consistent behavior between int() and Fraction() is valuable.

Agreed.  If no-one objects I'll fix the Decimal -> Fraction and float -> Fraction conversions to match what Decimal -> int and float -> int currently do (ValueError and OverflowError).

Then we can open a new issue to discuss having infinities give ValueError versus OverflowError for all four cases of {float, Decimal} -> {int, Fraction}.
msg175625 - (view) Author: Alexey Kachayev (kachayev) * Date: 2012-11-15 16:42
Patch is attached for {float, Decimal} -> {int, Fraction} consistency (with ValueError and OverflowError). Test cases are changed as well. 

I can also change OverflowError to ValueError for all cases, but I'm not sure should I open for this separated issue or continue to work with this one.
msg175631 - (view) Author: Alexey Kachayev (kachayev) * Date: 2012-11-15 18:23
I also attached "full_issue" patch: change OverflowError to ValueError for all cases.
msg175639 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-11-15 20:40
The first patch looks great (modulo a stray extra line in test_int). Thank you!

Let's just apply that for now; I'll open a new issue for the suggested OverflowError / ValueError switch.  (Getting rid of the TypeError seems a clear win to me;  switching the OverflowError to ValueError may be more controversial.)
msg175640 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-11-15 21:01
Fixed in http://hg.python.org/cpython/rev/a2b54b6d9759.  Thanks for the report and patch.
msg175644 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-11-15 21:18
See issue #16483 for the ValueError / OverflowError switch.  To be honest, while I would have preferred ValueError to OverflowError for int(float('inf')) if we were doing this from scratch, I'm not convinced that it's actually worth switching.
msg175655 - (view) Author: Alexey Kachayev (kachayev) * Date: 2012-11-15 22:20
Ok, I think that ValueError is more appropriate and I have already attached adopted patch for issue 16483.
History
Date User Action Args
2012-11-15 22:20:47kachayevsetmessages: + msg175655
2012-11-15 21:18:32mark.dickinsonsetmessages: + msg175644
2012-11-15 21:01:50mark.dickinsonsetstatus: open -> closed
resolution: fixed
messages: + msg175640
2012-11-15 20:40:42mark.dickinsonsetmessages: + msg175639
2012-11-15 18:47:35kachayevsetfiles: + full_issues16469_fixed.diff
2012-11-15 18:23:37kachayevsetfiles: + full_issues16469.diff

messages: + msg175631
2012-11-15 18:10:56mark.dickinsonsetstage: needs patch -> patch review
2012-11-15 16:42:11kachayevsetfiles: + issue16469.diff

nosy: + kachayev
messages: + msg175625

keywords: + patch
2012-11-15 09:30:55mark.dickinsonsetmessages: + msg175605
2012-11-14 17:40:03casevhsetmessages: + msg175579
2012-11-14 15:09:39loewissetnosy: + loewis
messages: + msg175570
2012-11-14 10:44:25asvetlovsetnosy: + asvetlov
2012-11-14 09:15:57mark.dickinsonsetassignee: mark.dickinson
2012-11-14 08:43:51mark.dickinsonsetmessages: + msg175550
2012-11-14 08:23:50mark.dickinsonsettitle: Exceptions raised by Fraction() from those raised by int() -> Exceptions raised by Fraction() different from those raised by int()
2012-11-14 08:23:17mark.dickinsonsetstage: needs patch
messages: + msg175548
versions: + Python 3.4, - Python 3.3
2012-11-14 07:12:02ezio.melottisetnosy: + rhettinger, mark.dickinson, ezio.melotti, skrah
type: behavior
2012-11-14 06:30:20casevhcreate