python / cpython

The Python programming language
https://www.python.org
Other
63.37k stars 30.33k forks source link

range_iterator does not use __index__ #81027

Closed df79943f-4aee-4531-a00d-c6b12816eb70 closed 5 years ago

df79943f-4aee-4531-a00d-c6b12816eb70 commented 5 years ago
BPO 36846
Nosy @serhiy-storchaka, @mr-nfamous, @remilapeyre
Superseder
  • bpo-17576: PyNumber_Index() is not int-subclass friendly (or operator.index() docs lie)
  • 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: ```python assignee = None closed_at = created_at = labels = ['3.8'] title = 'range_iterator does not use __index__' updated_at = user = 'https://github.com/mr-nfamous' ``` bugs.python.org fields: ```python activity = actor = 'serhiy.storchaka' assignee = 'none' closed = True closed_date = closer = 'serhiy.storchaka' components = [] creation = creator = 'bup' dependencies = [] files = [] hgrepos = [] issue_num = 36846 keywords = [] message_count = 3.0 messages = ['341845', '341860', '341864'] nosy_count = 3.0 nosy_names = ['serhiy.storchaka', 'bup', 'remi.lapeyre'] pr_nums = [] priority = 'normal' resolution = 'duplicate' stage = 'resolved' status = 'closed' superseder = '17576' type = None url = 'https://bugs.python.org/issue36846' versions = ['Python 3.8'] ```

    df79943f-4aee-4531-a00d-c6b12816eb70 commented 5 years ago

    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 PyLongCheck 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')
    23982c60-ed6c-47d1-96c2-69d417bd81b3 commented 5 years ago

    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?

    serhiy-storchaka commented 5 years ago

    This is a duplicate of bpo-17576.