Author ncoghlan
Recipients Eric Appelt, mark.dickinson, ncoghlan
Date 2018-03-10.08:57:09
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1520672231.04.0.467229070634.issue33039@psf.upfronthosting.co.za>
In-reply-to
Content
(Note: I haven't categorised this yet, as I'm not sure how it *should* be categorised)

Back when the __index__/nb_index slot was added, the focus was on allowing 3rd party integer types to be used in places where potentially lossy conversion with __int__/nb_int *wasn't* permitted.

However, this has led to an anomaly where the lossless conversion method *isn't* tried implicitly for the potentially lossy int() and math.trunc() calls, but is tried automatically in other contexts:

```
>>> import math
>>> class MyInt:
...     def __index__(self):
...         return 42
... 
>>> int(MyInt())
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 'MyInt'
>>> math.trunc(MyInt())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type MyInt doesn't define __trunc__ method
>>> hex(MyInt())
'0x2a'
>>> len("a" * MyInt())
42

```

Supporting int() requires also setting `__int__`:

```
>>> MyInt.__int__ = MyInt.__index__
>>> int(MyInt())
42
```

Supporting math.trunc() requires also setting `__trunc__`:

```
>>> MyInt.__trunc__ = MyInt.__index__
>>> math.trunc(MyInt())
42
```

(This anomaly was noticed by Eric Appelt while updating the int() docs to cover the fallback to trying __trunc__ when __int__ isn't defined: https://github.com/python/cpython/pull/6022#issuecomment-371695913)
History
Date User Action Args
2018-03-10 08:57:11ncoghlansetrecipients: + ncoghlan, mark.dickinson, Eric Appelt
2018-03-10 08:57:11ncoghlansetmessageid: <1520672231.04.0.467229070634.issue33039@psf.upfronthosting.co.za>
2018-03-10 08:57:10ncoghlanlinkissue33039 messages
2018-03-10 08:57:09ncoghlancreate