[issue17576] PyNumber_Index() is not int-subclass friendly (or operator.index() docos lie)
Mark Dickinson
report at bugs.python.org
Thu May 28 04:41:58 EDT 2020
Mark Dickinson <dickinsm at gmail.com> added the comment:
[Serhiy]
> * Undeprecate accepting __index__ and __int__ returning instances of int sublasses. There is no difference from the side of using int and index(), but it can simplify user implementations of __index__ and __int__.
I'm not sure about this. Thinking about the bigger picture, we have a similar deprecation in place for __float__ returning an instance of a float subclass. That one I'd like to keep (and probably make an error for 3.10).
A problem I've run into in Real Code (TM) is needing to convert something float-like to a float, using the same mechanisms that (for example) something like `math.sqrt` uses.
One option is to call "float", but that requires explicitly excluding str, bytes and bytearray, which feels ugly and not very future-proof.
So the code ends up calling __float__. But because __float__ can return an instance of a float subclass, it then still needs some way to convert the return value to an actual float. And that's surprisingly tricky.
So I really *do* want to see the ability of __float__ to return a non-float eventually removed.
Similarly for __int__, there's no easy Python-side way to mimic the effect of calling __int__, followed by converting to an exact int. We have to:
1. Do an explicit check for non-numbers (str, bytes, bytearray)
2. Call int
Or:
1. Call __int__
2. Convert an instance of a possible subclass of int to something of exact type int. I don't know how to do this cleanly in general in Python, and end up resorting to evil tricks like adding `0`.
Deprecating allowing __int__ to return a non-int helps here, because it lets me simply call __int__.
I care much more about the __float__ case than the __int__ case, because the "right way" to duck-type integers is to use __index__ rather than __int__, and for __index__ we have operator.index as a solution.
But it would seem odd to have the rule in place for __float__ but not for __int__ and __index__.
The other way to solve my problem would be to provide an operator module function (operator.as_float?) that does a duck-typed conversion of an arbitrary Python object to a float.
----------
nosy: +mark.dickinson
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue17576>
_______________________________________
More information about the Python-bugs-list
mailing list