Clients don’t need permission to make other assumptions about iterators after they raised StopIteration. If you want to iterate over iterators like this, there are no Python Police to stop you (although your peers may laugh at you behind your back):
it = iter(some_iterable)
for i in range(100):
for obj in it:
process(obj)
For most iterators, the last 99 attempts to iterate over it
will be empty loops, but you never know when an exhausted iterator will suddenly recover and stop being exhausted. Right?
The risk is actually the other way. Here is a legitimate idiom that will fail if the iterator suddenly unexhausts itself:
words = iter(words)
# Process words before "STOP" in one way, and words afterwards
# in another way.
for word in words:
if word == "STOP":
break
process_before_stop(word)
do_some_more_stuff()
# Now process words after "STOP"
for word in words:
process_after_stop(words)
We should be able to assume that if the first loop exhausts the iterator (i.e. that the sentinel “STOP” either doesn’t exist, or is the very last word), that the iterator will remain exhausted forever, and that the second loop will do nothing.
If iterators can be reset, then we don’t know if do_some_more_stuff()
may have reset the iterator and broken our expectations about the iterator being exhausted.
And that is why, technically, file iterators are broken.
But then file I/O is a very grubby case. Errors can be transient; files can be modified by other processes even in the middle of a read. Reading a file is not idepotent: there is no guarantee that two reads of the same file from the same position will give the same data, even if you are reading from read-only media. Computing would be so much cleaner and simpler if there was no I/O
Describing an iterator as “broken” is a provocative thing to say. But this is Python, and if you want to shoot yourself in the foot, you can. Broken things can be useful. If you want to give your iterators a reset mechanism, you can, but then don’t be surprised if that breaks people’s expectations about iteration.