The exception actually occurs when you call next() on a generator which cannot return any more values, or is finished, in which case `StopIteration` is usually raised.
>>> next(iter([]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> next(iter((lambda: (yield 5) if False else None)()))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIterationHere's a quick description from somewhere on the interwebs: An error is an issue in a program that prevents the program from completing its task. In comparison, an exception is a condition that interrupts the normal flow of the program.
Then there is StopIteration, which does not fit well into either of the two above. It's a wart I've learned to treat as a beauty mark.
You could signal errors via eg returning None or False or throwing an exception. But not throwing an exception could also be an error. (Eg if your for-loop never ends, that might be an error. And that would be synonymous with StopIteration never being thrown.)
[0] Eg for a program like 'cat' it would normally be considered an error, when the file being read doesn't exist. But perhaps in my particular usage, that's expected to occur quite often, and is a normal part of my operation. You can translate this example to Python: FileNotFound might be an error, or a normal condition.