You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
float() can return not exact float instance #71170
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:
assignee='https://github.com/serhiy-storchaka'closed_at=<Date2016-06-06.10:01:54.560>created_at=<Date2016-05-09.13:46:33.061>labels= ['interpreter-core', 'type-bug']
title='float() can return not exact float instance'updated_at=<Date2016-06-06.10:01:54.558>user='https://github.com/serhiy-storchaka'
And int() can return an instance of int subclass, but this behavior is deprecated:
>>> classBadInt:
... def__int__(self):
... returnTrue
...
>>> int(BadInt())
__main__:1: DeprecationWarning: __int__ returned non-int (type bool). The ability to return an instance of a strict subclass of int is deprecated, and may be removed in a future version of Python.
True
May be we should either deprecate __float__ returning non-float (as for int), or convert the result to exact float (as for complex).
The constructor of float subclass always returns an instance of correct type.
I was initially a bit confused by the wording of the warning: presumably, we're not going to change Python to make returning an instance of a strict float subclass from __float__ illegal (I don't really see how that would be possible); we're just going to check the return type at the internal call sites to __float__ and raise if we get something other than an exact float. That is, I'd still expect this code to work on future versions of Python:
The warning message is copied from __int__. As I understand, the conclusion of the Python-Dev discussion is that __int__, __float__, __complex__, etc should return exact int, float, complex, not subclasses. I have another patch that adds a warning for __complex__, and I am working on patches for other special methods. If my understanding is wrong, we should remove the deprecation warning for __int__.
As I understand, the conclusion of the Python-Dev discussion is that __int__, __float__, __complex__, etc should return exact int, float, complex, not subclasses.
Agreed; that matches my understanding. I'm only observing that it would be difficult (and likely undesirable) to actually enforce that __int__ itself always returns an exact int: I'm not sure where that check would/could take place, and I'd expect that a direct user-level call to my_object.__int__ probably wouldn't be subject to such a check. What we can do is check that the result of the nb_int call is always an int in the places we use it.
Or we could even go further, and write custom slot_nb_float and slot_nb_int functions in Objects/typeobject.c that incorporates those checks. What I don't think we can do is check that a direct call to __int__ or __float__ always returns something of the exact type.
Activity
serhiy-storchaka commentedon May 9, 2016
The float constructor can return an instance of float subclass.
Comparing with other types, complex() always returns complex:
And int() can return an instance of int subclass, but this behavior is deprecated:
May be we should either deprecate __float__ returning non-float (as for int), or convert the result to exact float (as for complex).
The constructor of float subclass always returns an instance of correct type.
serhiy-storchaka commentedon May 10, 2016
Proposed patch makes float() always returning exact float.
mdickinson commentedon May 11, 2016
+1 for the idea, and the patch LGTM.
I was initially a bit confused by the wording of the warning: presumably, we're not going to change Python to make returning an instance of a strict float subclass from __float__ illegal (I don't really see how that would be possible); we're just going to check the return type at the internal call sites to __float__ and raise if we get something other than an exact float. That is, I'd still expect this code to work on future versions of Python:
But these would both become an error in Python 3.7 (say):
>>> float(a) 0.0 >>> math.sqrt(a) 0.0Does that match your thinking?
We should probably add issues for checking and fixing other places that __float__ is used internally (like the math module).
serhiy-storchaka commentedon May 11, 2016
The warning message is copied from __int__. As I understand, the conclusion of the Python-Dev discussion is that __int__, __float__, __complex__, etc should return exact int, float, complex, not subclasses. I have another patch that adds a warning for __complex__, and I am working on patches for other special methods. If my understanding is wrong, we should remove the deprecation warning for __int__.
mdickinson commentedon May 11, 2016
Agreed; that matches my understanding. I'm only observing that it would be difficult (and likely undesirable) to actually enforce that
__int__itself always returns an exact int: I'm not sure where that check would/could take place, and I'd expect that a direct user-level call tomy_object.__int__probably wouldn't be subject to such a check. What we can do is check that the result of thenb_intcall is always an int in the places we use it.Or we could even go further, and write custom slot_nb_float and slot_nb_int functions in Objects/typeobject.c that incorporates those checks. What I don't think we can do is check that a direct call to
__int__or__float__always returns something of the exact type.serhiy-storchaka commentedon May 11, 2016
Here is updated patch. Differences:
Could you propose better warning message?
mdickinson commentedon May 11, 2016
Can you please attach the new patch?
serhiy-storchaka commentedon May 11, 2016
Oh, sorry, how could I miss it?
serhiy-storchaka commentedon Jun 3, 2016
Ping.
mdickinson commentedon Jun 3, 2016
float_exact2.patch LGTM
python-dev commentedon Jun 3, 2016
New changeset 050e5f803999 by Serhiy Storchaka in branch 'default':
Issue bpo-26983: float() now always return an instance of exact float.
https://hg.python.org/cpython/rev/050e5f803999
serhiy-storchaka commentedon Jun 3, 2016
Thank you for your review Mark.
SilentGhost commentedon Jun 6, 2016
test_format resulted in semi-failure due to this change. The attached patch fixes the issue.
python-dev commentedon Jun 6, 2016
New changeset 6216fb8afa53 by Serhiy Storchaka in branch 'default':
Issue bpo-26983: Fixed test_format failure.
https://hg.python.org/cpython/rev/6216fb8afa53
serhiy-storchaka commentedon Jun 6, 2016
My failure. Thank you for your report and patch SilentGhost.