bpo-20092: Make __int__ defaults to __index__ by remilapeyre · Pull Request #13106 · python/cpython
Rémi Lapeyre added 2 commits
serhiy-storchaka
changed the title
bpo-33039: Make __int__ defaults to __index__
bpo-20092: Make __int__ defaults to __index__
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of handling this on the level of the Python __dict__, wouldn't it be better to handle this in nb_int? That is, set nb_int to nb_index. That way, it's also guaranteed to work for extension types defining only nb_index.
@jdemeyer, I was not absolutly clear with how the methods that have a slot interact with __dict__, I tried to read the code source and to look were __dict__ or the slot were preferred over each other and I'm still not sure about the details. I couldn't find where __getattr__ would look in the slots.
I will push a commit to update the slots instead of __dict__ tonight.
I was not absolutly clear with how the methods that have a slot interact with
__dict__
It's complicated, I would have to look up the details myself.
But basically, the slots are used to put entries in the __dict__ (instances of wrapper_descriptor) and the presence of a special method (but not a wrapper_descriptor) in the __dict__ adds an entry (for example slot_nb_index) in the slot. It's especially this two-way interaction that makes things more complicated.
Thanks @jdemeyer, I think the last change should be good to make nb_int defaults to nb_index
What I meant is that should only do
type->tp_as_number->nb_int = type->tp_as_number->nb_index;
and then the wrapper descriptor __int__ should be added automatically.
This doesn't seem to work, with this:
/* If __index__ is defined but not __int__, make it default to __index__.
Don't touch __float__ and __complex__ as there could be some loss of
precision.
*/
if (type->tp_as_number != NULL && type->tp_as_number->nb_int == NULL) {
type->tp_as_number->nb_int = type->tp_as_number->nb_index;
}
I get:
✗ ./python.exe -m test.test_index
...E....................................................
======================================================================
ERROR: test_int_defaults_to_index (__main__.BaseTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/remi/src/cpython/Lib/test/test_index.py", line 97, in test_int_defaults_to_index
self.assertEqual(int(Test()), 4)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Test'
#13108 has been merged so the issue is now resolved.