[Python-Dev] Semantics of __int__(), __index__()

Steven D'Aprano steve at pearwood.info
Wed Apr 3 17:49:31 CEST 2013

On 03/04/13 23:47, Hrvoje Niksic wrote:
> On 04/03/2013 01:17 PM, Nick Coghlan wrote:
>>  > > >
>>  > > I like Nick's answer to that: int *should* always return something of
>>  > > exact type int.  Otherwise you're always left wondering whether you
>>  > > have to do "int(int(x))", or perhaps even "int(int(int(x)))", to be
>>  > > absolutely sure of getting an int.
>>  >
>>  > Agreed.
>> Perhaps we should start emitting a DeprecationWarning for int subclasses
>> returned from __int__ and __index__ in 3.4?
> Why would one want to be absolutely sure of getting an int?
> It seems like a good feature that an __int__ implementation can choose to return an int subclass with additional (and optional) information. After all, int subclass instances should be usable everywhere where ints are, including in C code.

I agree with Hrvoje here, and I have code that's probably going to be impacted by any change in behaviour.

In OO terms, an instance of an int subclass *is* an int, and we shouldn't care whether __int__ returns a subclass or a builtin. I think that before any change is made, even mere DeprecationWarning, there needs to be a very strong reason justifying restricting __int__ to return a built-in int.

To put it another way, I think it is perfectly reasonable for __int__ to enforce the constraint ``isinstance(result, int)`` but *not* to enforce the constraint ``type(result) is int``. We rarely, if ever, write explicit type checks like the second. Why should __int__ etc. implicitly do so?

This issue doesn't just apply to ints. For example:

py> class MyStr(str):
...     def __str__(self):
...             return self
py> s = MyStr('spam')
py> type(str(s))
<class '__main__.MyStr'>

This seems perfectly reasonable to me: __str__ is expected to return a string, and it does. If I absolutely must have a built-in str, I can do this:

py> type(''.join(s))
<class 'str'>

But I can't really think of any cases where I am going to insist on a built-in str, instead of accepting anything that passes either the weaker isinstance check. Even if there are such cases, surely they are going to be rare and unusual.

(I note that in OO terms, we don't really have good terminology for "an instance of a class, excluding instances of any subclasses". That's because in OO terms we shouldn't care whether the type of the instance is the superclass or subclass, at least not in general.)

-1 on forcing __int__, __str__, __float__ etc. to return instances of the built-in types.


More information about the Python-Dev mailing list