
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?