[Python-ideas] Introduce collections.Reiterable

Nick Coghlan ncoghlan at gmail.com
Thu Sep 19 15:02:57 CEST 2013


On 19 September 2013 22:18, Steven D'Aprano <steve at pearwood.info> wrote:
> The intention of the protocol is that once an iterator’s next() method
> raises StopIteration, it will continue to do so on subsequent calls.
> Implementations that do not obey this property are deemed broken. (This
> constraint was added in Python 2.3; in Python 2.2, various iterators are
> broken according to this rule.)
>
> http://docs.python.org/2/library/stdtypes.html#iterator-types
>
>
> but clearly there is a use-case for re-iterable "things", such as dict
> views, which can be re-iterated over. We just don't call them iterators.
> So maybe there should be a way to distinguish between "oops this
> iterator is broken" and "yes, this object can be iterated over
> repeatedly, it's all good".
>
> At the moment, dict views aren't directly iterable (you can't call
> next() on them). But in principle they could have been designed as
> re-iterable iterators.

That's not what iterable means. The iterable/iterator distinction is
well defined and reflected in the collections ABCs:

* iterables are objects that return iterators from __iter__.
* iterators are the subset of iterables that return "self" from
__iter__, and expose a next (2.x) or __next__ (3.x) method

That "iterators return self from __iter__" is important, since almost
everywhere Python iterates over something, it call "_itr = iter(obj)"
first.

So, my question is a genuine one. While, *in theory*, an object can
define a stateful __iter__ method that (e.g.) only works the first
time it is called, or returns a separate object that still stores it's
"current position" information on the original container, I simply
can't think of a non-pathological case where "isinstance(obj,
Iterable) and not isinstance(obj, Iterator)" would give the wrong
answer.

In theory, yes, an object could obviously pass that test and still not
be Reiterable, but I'm interested in what's true in *practice*.

Cheers,
Nick.

P.S. Generator-iterators are a further subset of iterators that expose
send and throw and are integrated with the interpreter eval loop in
various ways that other objects can't yet match. Although I think Mark
Shannon has some ideas about refactoring that API to let other objects
plug into it.


-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list