This rule raises an issue when StopIteration is explicitly raised within a generator function, that is, a function containing
yield.
In Python, generators are special functions that use the yield keyword to produce a sequence of values lazily. They implement the
iterator protocol and are used to create iterators in a concise way.
Traditionally, raising StopIteration was the standard way to signal that an iterator had no more values to produce. However, this
could lead to subtle bugs when StopIteration exceptions from nested iterators or function calls accidentally propagated up and terminated
the generator unexpectedly.
To address this issue, PEP 479 changed the behavior in Python 3.7+. Now, when
StopIteration is raised inside a generator function, Python automatically converts it to a RuntimeError. This conversion
happens at the point where the exception would leave the generator.
This means code that explicitly raises StopIteration in a generator will fail with a RuntimeError at runtime in Python
3.7 and later versions. The error message will indicate that the StopIteration exception was raised inside a generator.
The proper way to terminate a generator is to use a return statement, optionally with a value. When a generator executes a
return, Python automatically raises StopIteration behind the scenes, but does so in a way that is compatible with PEP
479.
When StopIteration is raised inside a generator in Python 3.7+, it causes a RuntimeError at runtime. This can lead
to:
Replace the raise StopIteration statement with a return statement. In generators, return is the proper way
to signal completion. If you need to return a value when the generator completes, you can use return value, though note that this value
is not yielded but becomes the exception value of the StopIteration that is automatically raised.
def my_generator():
yield 1
yield 2
raise StopIteration # Noncompliant
def my_generator():
yield 1
yield 2
return # Properly terminates the generator