New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
int() and math.trunc don't accept objects that only define __index__ #77220
Comments
(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:
Supporting int() requires also setting
Supporting math.trunc() requires also setting
(This anomaly was noticed by Eric Appelt while updating the int() docs to cover the fallback to trying __trunc__ when __int__ isn't defined: #6022 (comment)) |
Marking this as a documentation enhancement request for now, but I think we should also consider changing the type creation behaviour in 3.8 to implicitly add __int__ and __trunc__ definitions when __index__ is defined, but they aren't. That way, no behaviour will change for classes that explicitly define __int__ or __trunc__, but classes that only define __index__ without defining the other methods will behave more intuitively. |
@ncoghlan is this what's being done in PyTypeReady? |
@rémi Aye, filling out derived slots is one of the things PyType_Ready does. This would need a discussion on python-dev before going ahead and doing it though, as the closest equivalent we have to this right now is the "negative" derivation, where overriding __eq__ without overriding __hash__ implicitly marks the derived class as unhashable (look for "type->tp_hash = PyObject_HashNotImplemented;"). |
See also bpo-33039. |
Is not this a duplicate of bpo-20092? |
Yes it is. Thanks for finding that @serhiy. Since nobody objected to the change on the mailing list and people seem to agree in bpo-20092:
I will post my patch tonight. |
Rémi, Are you still working on the patch for this? Thanks! |
Hi Cheryl, thanks for the ping. I wasn't sure my patch was correct but reading typeobject.c:add_operators(), it is actually more straight-forward than I thought. Serhiy Storchaka: This is indeed a duplicate of bpo-20092. I believe the solution proposed by Nick Coghlan is better than the one of Amitava Bhattacharyya, "adding a call to One thing to note regarding the proposed patch: the following stops to work and raises a RecursionError since __index__ == __int__: class MyInt(int):
def __index__(self):
return int(self) + 1 I changed test_int_subclass_with_index() as |
Then let to continue the discussion on the older issue which has larger discussion. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: