On Fri, Dec 8, 2017 at 7:20 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
On 12/08/2017 04:33 AM, Erik Bray wrote:
More importantly not as many objects that coerce to int actually implement __index__. They probably *should* but there seems to be some confusion about how that's to be used.
__int__ is for coercion (float, fraction, etc)
__index__ is for true integers
Note that if __index__ is defined, __int__ should also be defined, and return the same value.
https://docs.python.org/3/reference/datamodel.html#object.__index__
This doesn't appear to be enforced, though I think maybe it should be. I'll also note that because of the changes I pointed out in my original post, it's now necessary for me to explicitly cast as int() objects that previously "just worked" when passed as arguments in some functions in itertools, collections, and other modules with C implementations. However, this is bad because if some broken code is passing floats to these arguments, they will be quietly cast to int and succeed, when really I should only be accepting objects that have __index__. There's no index() alternative to int(). I think changing all these functions to do the appropriate PyIndex_Check is a correct and valid fix, but I think it also stretches beyond the original purpose of __index__. I think that __index__ is relatively unknown, and perhaps there should be better documentation as to when and how it should be used over the better-known __int__.