Make typing.SupportsFloat, SupportsComplex and SupportInt be Unions with SupportsIndex

From the datamodel doc page:


    Called to implement the built-in functions complex(), int() and float(). Should return a value of the appropriate type.

My proposition is to make the typing.SupportsFloat class be a “does this support calling float() on it” rather than “does it have __float__”.
Because __float__ has no other documented purpose (see quote above) than serving as an anchor for the float builtin converter, so why not make the ABC more adapted to that builtin float converter ? As is stands, SupportsFloat has no purpose in an isinstance (or typing) context other than as SupportsFloat | SupportsIndex.
Same rationale for the two other ABC.

What I mean by “be subclasses of” is not that it has to be implemented that way, but that an object would test as being an instance of SupportsFloat whenever it tests as an instance of SupportsIndex.

The only difference then between isinstance(a, SupportsFloat) and this:

except Exception:
    return False
    return True

…would be the strings such as "+4" which would return false for the isinstance but true for the try/except. But I think it would still be worth it.

From what I understand, you should probably post this to python/typing.

Should not it be in other way to satisfy the Liskov’s substitution principle? SupportsIndex being a subclass of SupportsFloat, SupportsComplex and SupportInt?

@storchaka I think I sort of understand what you mean, so yes, it should probably not be a subclass.
In that case my proposition is to make NewSupportsFloat = OldSupportsFloat | OldSupportsIndex. And then yes, we can have NewSupportsIndex report as a subclass of… basically all the others.

Though it’s worth noting that a class implementing __float__, __int__ and __complex__ but not __index__ would be a subclass of NewSupportsIndex but not of OldSupportsIndex. I like that ABC as a feature but I’m not sure it should be called SupportsIndex.

@NeilGirdhar I don’t think so, that seems to be a forum about help and best practices while I’m talking about changes to the features of the typing module.

Is this true? Sign in to GitHub · GitHub

I think so, yes. I would candidly claim that in all examples you find where SupportsFloat is tested and SupportsIndex is not, then either I could pass a SupportsIndex subclass and it would work the same while being reported as a typing error, or the example would be accessing __float__ directly in a way that would betray the datamodel and the only documented purpose of that method.

Actually if you look into these examples most of them include SupportsIndex from version 3.8 on, and that’s because it only exists since then.