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: Reversing large ranges results in a minor type inconsistency
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.8, Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Donald Hobson, christian.heimes, p-ganssle, rhettinger
Priority: normal Keywords:

Created on 2019-04-21 16:28 by Donald Hobson, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg340614 - (view) Author: Donald Hobson (Donald Hobson) Date: 2019-04-21 16:28
Almost all of python makes the abstraction that ints are a single type of thing, the fact that some ints are too big to store in 8 bytes of memory is abstracted away. This abstraction fails when you try to reverse large ranges. 

>>> reversed(range(1<<63))
<longrange_iterator object at 0x7f0925d26660>
>>> reversed(range(1<<63-1))
<range_iterator object at 0x7f0925d26600>
>>> type(reversed(range(1<<63-1)))
<class 'range_iterator'>
>>> type(reversed(range(1<<63)))
<class 'longrange_iterator'>
>>> type(reversed(range(1<<63-2)))==type(reversed(range(1<<63-1)))
True
>>> type(reversed(range(1<<63-1)))==type(reversed(range(1<<63)))
False
msg340618 - (view) Author: Paul Ganssle (p-ganssle) * (Python committer) Date: 2019-04-21 19:18
I have edited the title to be a bit more and give more context. Donald, if you feel I have misrepresented your issue, please feel free to tweak it further.
msg340619 - (view) Author: Paul Ganssle (p-ganssle) * (Python committer) Date: 2019-04-21 19:25
I believe the relevant code is here:

https://github.com/python/cpython/blob/bb86bf4c4eaa30b1f5192dab9f389ce0bb61114d/Objects/rangeobject.c#L1038

It looks like it's a performance enhancement and that for ranges where the beginning and end can fit in a C long, a faster iterator that uses C types under the hood is returned, and for ranges where the boundaries *can't* be represented by a C long, it defaults to the slower `longrange_iterator`, that uses Python integers.

It *may* be possible to disguise this from the end user, but I'm not sure if doing so is warranted. I have always treated the specific type returned by `iter()` to be an implementation detail, other than the fact that it is an iterator.
msg340638 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2019-04-22 04:58
This all seems proper to me.  In each case, an iterator is returned -- that is the documented behavior.  The specific type of iterator is allowed to vary in ways that are convenient for the implementation.

Specifically, reversed() will call __reversed__() which must return an iterator but its type is allowed to vary.  That is really convenient for handling extreme ranges separately from the fast, common case of smaller ranges.
History
Date User Action Args
2022-04-11 14:59:14adminsetgithub: 80874
2019-04-22 04:58:42rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg340638

resolution: not a bug
stage: resolved
2019-04-21 19:25:42p-gansslesetmessages: + msg340619
2019-04-21 19:18:05p-gansslesetnosy: + p-ganssle

messages: + msg340618
title: Minor inconsistancy with types. -> Reversing large ranges results in a minor type inconsistency
2019-04-21 17:15:37SilentGhostsetnosy: + christian.heimes

versions: + Python 3.7, Python 3.8, - Python 3.5
2019-04-21 16:28:47Donald Hobsoncreate