
This issue trackerhas been migrated toGitHub, and is currentlyread-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.
Created on2016-05-09 13:46 byserhiy.storchaka, last changed2022-04-11 14:58 byadmin. This issue is nowclosed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| float_exact.patch | serhiy.storchaka,2016-05-10 19:08 | review | ||
| float_exact2.patch | serhiy.storchaka,2016-05-11 14:54 | review | ||
| issue26983.diff | SilentGhost,2016-06-06 08:08 | review | ||
| Messages (15) | |||
|---|---|---|---|
| msg265191 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-05-09 13:46 | |
The float constructor can return an instance of float subclass.>>> class FloatSubclass(float):... pass... >>> class BadFloat:... def __float__(self):... return FloatSubclass(1.2)... >>> type(float(BadFloat()))<class '__main__.FloatSubclass'>Comparing with other types, complex() always returns complex:>>> class ComplexSubclass(complex):... pass... >>> class BadComplex:... def __complex__(self):... return ComplexSubclass(1.2, 3.4)... >>> type(complex(BadComplex()))<class 'complex'>And int() can return an instance of int subclass, but this behavior is deprecated:>>> class BadInt:... def __int__(self):... return True... >>> 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.TrueMay 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.>>> class FloatSubclass2(float):... pass... >>> type(FloatSubclass2(BadFloat()))<class '__main__.FloatSubclass2'> | |||
| msg265267 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-05-10 19:08 | |
Proposed patch makes float() always returning exact float. | |||
| msg265295 -(view) | Author: Mark Dickinson (mark.dickinson)*![]() | Date: 2016-05-11 08:05 | |
+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:>>> class MyFloat(float): pass... >>> class A:... def __float__(self): return MyFloat()... >>> a = A()>>> a.__float__()0.0But 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). | |||
| msg265297 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-05-11 08:59 | |
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__. | |||
| msg265298 -(view) | Author: Mark Dickinson (mark.dickinson)*![]() | Date: 2016-05-11 09:45 | |
> 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 inObjects/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. | |||
| msg265299 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-05-11 10:20 | |
Here is updated patch. Differences:* Deprecation warning is now emitted in functions accepting floats (like math.sqrt).* Improved error messages. Now reported wrong type name and a type of wrong __float__ method.* float() now returns the same object for exact float argument.Could you propose better warning message? | |||
| msg265316 -(view) | Author: Mark Dickinson (mark.dickinson)*![]() | Date: 2016-05-11 14:05 | |
Can you please attach the new patch? | |||
| msg265318 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-05-11 14:54 | |
Oh, sorry, how could I miss it? | |||
| msg267096 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-06-03 12:27 | |
Ping. | |||
| msg267101 -(view) | Author: Mark Dickinson (mark.dickinson)*![]() | Date: 2016-06-03 14:11 | |
float_exact2.patch LGTM | |||
| msg267129 -(view) | Author: Roundup Robot (python-dev)![]() | Date: 2016-06-03 18:43 | |
New changeset050e5f803999 by Serhiy Storchaka in branch 'default':Issue#26983: float() now always return an instance of exact float.https://hg.python.org/cpython/rev/050e5f803999 | |||
| msg267130 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-06-03 18:44 | |
Thank you for your review Mark. | |||
| msg267521 -(view) | Author: SilentGhost (SilentGhost)*![]() | Date: 2016-06-06 08:08 | |
test_format resulted in semi-failure due to this change. The attached patch fixes the issue. | |||
| msg267523 -(view) | Author: Roundup Robot (python-dev)![]() | Date: 2016-06-06 10:00 | |
New changeset6216fb8afa53 by Serhiy Storchaka in branch 'default':Issue#26983: Fixed test_format failure.https://hg.python.org/cpython/rev/6216fb8afa53 | |||
| msg267524 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-06-06 10:01 | |
My failure. Thank you for your report and patch SilentGhost. | |||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:58:30 | admin | set | github: 71170 |
| 2016-06-06 10:01:54 | serhiy.storchaka | set | status: open -> closed resolution: fixed messages: +msg267524 |
| 2016-06-06 10:00:28 | python-dev | set | messages: +msg267523 |
| 2016-06-06 08:08:04 | SilentGhost | set | status: closed -> open files: +issue26983.diff assignee:serhiy.storchaka nosy: +SilentGhost messages: +msg267521 resolution: fixed -> (no value) stage: resolved -> commit review |
| 2016-06-03 18:54:26 | serhiy.storchaka | set | status: open -> closed resolution: fixed stage: patch review -> resolved |
| 2016-06-03 18:44:27 | serhiy.storchaka | set | messages: +msg267130 |
| 2016-06-03 18:43:29 | python-dev | set | nosy: +python-dev messages: +msg267129 |
| 2016-06-03 14:11:05 | mark.dickinson | set | messages: +msg267101 |
| 2016-06-03 12:27:52 | serhiy.storchaka | set | messages: +msg267096 |
| 2016-05-11 14:54:48 | serhiy.storchaka | set | files: +float_exact2.patch messages: +msg265318 |
| 2016-05-11 14:05:17 | mark.dickinson | set | messages: +msg265316 |
| 2016-05-11 10:21:29 | serhiy.storchaka | set | dependencies: +Add tests for parsing float and object arguments |
| 2016-05-11 10:20:50 | serhiy.storchaka | set | messages: +msg265299 |
| 2016-05-11 09:45:22 | mark.dickinson | set | messages: +msg265298 |
| 2016-05-11 08:59:35 | serhiy.storchaka | set | messages: +msg265297 |
| 2016-05-11 08:05:24 | mark.dickinson | set | messages: +msg265295 |
| 2016-05-10 19:08:27 | serhiy.storchaka | set | files: +float_exact.patch keywords: +patch messages: +msg265267 stage: patch review |
| 2016-05-09 13:46:33 | serhiy.storchaka | create | |