-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
Inconsistent round behavior between float and int #72123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Theo error handling for round is different for float and int. Python 3.5.1 (default, Apr 18 2016, 11:46:32)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> round(1.0, None)
1
>>> round(1, None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object cannot be interpreted as an integer |
The different data types make different choices: >>> from decimal import Decimal
>>> from fractions import Fraction
>>> (1).__round__(None)
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
(1).__round__(None)
TypeError: 'NoneType' object cannot be interpreted as an integer
>>> (1.0).__round__(None)
1
>>> Decimal(1).__round__(None)
Traceback (most recent call last):
File "<pyshell#41>", line 1, in <module>
Decimal(1).__round__(None)
TypeError: optional arg must be an integer
>>> Fraction(1, 1).__round__(None)
1
>>> from _pydecimal import Decimal
>>> Decimal(1).__round__(None)
1 For Fraction and _pydecimal, the behavior comes from using None as a placeholder (which is common and normal in pure python code). For float there is explicit code to test for the None case. For int, the None test was omitted (perhaps a mistake) and the error is raised by PyNumber_Index. Looking through tests, only Lib/test/test_float.py tests for None being allowable. Elsewhere, it seems to be an implementation detail. The old Python 2 version of the round() function never let None be passed in (because it used PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round"). That logic seems to get lost in the Python 3 version when __round__ was introduced. To resolve the differences, I think the round() function should explicitly check for None and replace it with zero before calling the underling __round__ functions where we would allow variable according the needs of the implementation. |
That would be a change in behaviour: >>> round(1.3, 0)
1.0
>>> round(1.3)
1
>>> round(1.3, None)
1 |
Ah, sorry; now that I've looked at the patch, I see I misunderstood. You're not replacing None with zero; you're replacing it with NULL. Patch LGTM. |
The test could be strengthened to add a check that the types of |
For the record, the float behaviour was changed (for Python 3.5) in http://bugs.python.org/issue19933. There didn't seem to be any particularly strong motivation for that change, but it's done now. |
New changeset c3c4d8e4ca1a by Raymond Hettinger in branch '3.5': |
New changeset 7108f2a708c9 by Raymond Hettinger in branch '3.5': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: