This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: range_iterator does not use __index__
Type: Stage: resolved
Components: Versions: Python 3.8
process
Status: closed Resolution: duplicate
Dependencies: Superseder: PyNumber_Index() is not int-subclass friendly (or operator.index() docs lie)
View: 17576
Assigned To: Nosy List: bup, remi.lapeyre, serhiy.storchaka
Priority: normal Keywords:

Created on 2019-05-08 02:23 by bup, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg341845 - (view) Author: Dan Snider (bup) * Date: 2019-05-08 02:23
I wouldn't even know where to begin to try and find a palatable solution for this that wouldn't be summarily dismissed. 

Perhaps it isn't unreasonable to suggest PyNumber_Index shouldn't use the less stringent PyLong_Check as the entry to the fast path. That is what happens right now and it can prevent the __index__ method defined for an int subtype being called in certain situation such as this one. 

Here's a silly but valid demonstration of what happens when there is more than 1 way to skin a... index. Apologies if it is unreadable but I wanted it to be a 'single' repl statement and cmd was being uncooperative without it being squished like this.


if not not not not not not True:      
    class Duper(super):
        def __call__(self, attr, *args):
            func = super.__getattribute__(self, attr)
            this = super.__self__.__get__(self)
            print(f'{this!r}.{func.__name__}(%s)'%', '.join(map(repr, args)))
            return super.__self_class__.__get__(self)(func(*args))
        @classmethod
        class unbound(classmethod):
            def __set_name__(self, owner, name):
                setattr(owner, name, self.__func__(owner))
    class Hex(int):
        __slots__ = ()
        __call__ = __self__ = Duper.unbound()
        def __neg__(self): return self('__neg__')
        def __abs__(self): return self('__abs__')
        def __add__(a, b): return a('__add__', b)
        def __sub__(a, b): return a('__sub__', b)
        def __mul__(a, b): return a('__mul__', b)
        def __radd__(a, b): return a('__radd__', b)
        def __rsub__(a, b): return a('__rsub__', b)
        def __rmul__(a, b): return a('__rmul__', b)
        def __floordiv__(a, b): return a('__floordiv__', b)
        def __rfloordiv__(a, b): return a('__rfloordiv__', b)                            
        def __repr__(self): return f'({self.__self__.__pos__():#02x})'
    a, b, c, i = (Hex(i) for i in (0, 10, 2, 2))
    print(f'creating range({a}, {b}, {c})...') 
    r = range(a, b, c)
    print('', '-'*78)
    print(f'accessing the element at r[{i!r}]...')
    v = r[i]
    print('', '-'*78)
    print('iterating over the range...')
    for i in r:
        pass
    print('are we there yet?...\n')
msg341860 - (view) Author: Rémi Lapeyre (remi.lapeyre) * Date: 2019-05-08 08:43
Hi @bup, thanks for opening a new bug report. I'm not sure I get what is the issue though. Could you attach a more readable example and explain exactly when you expect __index__ to be called?
msg341864 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-05-08 10:57
This is a duplicate of issue17576.
History
Date User Action Args
2022-04-11 14:59:14adminsetgithub: 81027
2019-05-08 10:57:56serhiy.storchakasetstatus: open -> closed

superseder: PyNumber_Index() is not int-subclass friendly (or operator.index() docs lie)

nosy: + serhiy.storchaka
messages: + msg341864
resolution: duplicate
stage: resolved
2019-05-08 08:43:20remi.lapeyresetnosy: + remi.lapeyre
messages: + msg341860
2019-05-08 02:23:43bupcreate