bpo-26701: Add documentation for trunc by appeltel · Pull Request #6022 · python/cpython (original) (raw)
@ncoghlan So I did some experimentation to try to ensure that I had the order of fallbacks correct, and after further investigation it seems that you can't call int()
on an object that has only defined __index__
. I can use it as an index, even call hex()
on it, but not int()
:
>>> class Foo:
... def __index__(self): return 4
...
>>> f = Foo()
>>> [x for x in range(7)][f]
4
>>> int(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Foo'
>>> int(hex(f), 16)
4
This appears to be odd behavior in that something that is obviously designed to be interpreted as an int for the purposes of indexing and slicing can't be coerced into an int, and it seems backwards relative to the aim of PEP-357.
The source code for PyObject * PyNumber_Long(PyObject *o)
also clearly does not check the nb_index
slot, only nb_int
. I found that I can clumsily add this capability by making an (PyLongObject *)_PyLong_FromNbIndex(PyObject *)
function largely copied from (PyLongObject *)_PyLong_FromNbInt(PyObject *)
but changing the slot, so I guess it was never there.
Maybe I am misreading the code, could you verify?