[Python-ideas] Deterministic iterator cleanup

Yury Selivanov yselivanov.ml at gmail.com
Wed Oct 19 16:33:46 EDT 2016


On 2016-10-19 3:33 PM, Nathaniel Smith wrote:

>>>>>> lst = [1,2,3,4]
>>>>>> >>>>>it = iter(lst)
>>>>>> >>>>>for i in it:
>>> >>...   if i == 2: break
>>> >>
>>>>>> >>>>>for i in it:
>>> >>...   print(i)
>>> >>3
>>> >>4
>>>>>> >>>>>
>>> >>
>>> >>With the proposed behaviour, if I understand it, "it" would be closed
>>> >>after the first loop, so resuming "it" for the second loop wouldn't
>>> >>work. Am I right in that? I know there's a proposed itertools function
>>> >>to bring back the old behaviour, but it's still a compatibility break.
>>> >>And code like this, that partially consumes an iterator, is not
>>> >>uncommon.
>> >
>> >Right -- did you reach the "transition plan" section? (I know it's
>> >wayyy down there.) The proposal is to hide this behind a __future__ at
>> >first + a mechanism during the transition period to catch code that
>> >depends on the old behavior and issue deprecation warnings. But it is
>> >a compatibility break, yes.
> I should also say, regarding your specific example, I guess it's an
> open question whether we would want list_iterator.__iterclose__ to
> actually do anything. It could flip the iterator to a state where it
> always raises StopIteration, or RuntimeError, or it could just be a
> no-op that allows iteration to continue normally afterwards.

Making 'for' loop to behave differently for built-in containers (i.e. 
make __iterclose__ a no-op for them) will only make this whole thing 
even more confusing.

It has to be consistent: if you partially iterate over *anything* 
without wrapping it with `preserve()`, it should always close the iterator.

Yury


More information about the Python-ideas mailing list