This is my first post to this list, apologies in advance if this is the wrong 
place or it's a known topic that my search failed to find.

As a Python user since 2.6, I make stupid mistakes with exhausted generators 
more often than I'd like to admit:

numbers = (i for i in range(5))
assert 5 not in numbers
sorted(numbers)
# []

Then the empty list creates hard-to-track bugs. I'm familiar with the iterator 
protocol and why the behavior above happens, but couldn't it be prevented? A 
naive example of the behavior I wish it had:

class SafeGenerator:
    def __init__(self, generator):
        self.generator = generator
        self.is_exhausted = False

    def __iter__(self):
        if self.is_exhausted:
            raise ValueError("can't iterate over an already exhausted 
generator")
        return self

    def __next__(self):
        try:
            return next(self.generator)
        except StopIteration:
            self.is_exhausted = True
            raise

safe_generator = SafeGenerator(i for i in range(5))
assert 5 not in safe_generator
sorted(safe_generator)
# ValueError: can't iterate over an already exhausted generator

Note that the error is raised on `__iter__`, not `__next__`, so idioms like 
`zip(generator, generator)` would still work. I can't imagine any sane code 
that would break under this change, but even if there is, what's the downside 
of at least emitting a warning when calling `__iter__` on an exhausted 
generator?
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/MSSCJ4SMMSCX2FJ2OAHVNWWWXVNU6MO7/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to