これは Python バージョン 3.6 までのデフォルトの動作ですが、これは言語の誤りと見なされ、代わりに例外が発生するように Python 3.7 で変更される予定です。
PEP 479が言うように:
ジェネレーター と の相互作用StopIteration
は現在のところやや驚くべきものであり、あいまいなバグを隠している可能性があります。予期しない例外により、動作が微妙に変更されることはありませんが、ノイズが多く、デバッグが容易なトレースバックが発生する必要があります。現在、StopIteration
ジェネレーター関数内で誤って発生した場合、ジェネレーターを駆動するループ構造による反復の終了として解釈されます。
Python 3.5 以降では、デフォルトの動作を 3.7 で予定されている動作に変更できます。このコード:
# gs_exc.py
from __future__ import generator_stop
def error():
return next(i for i in range(3) if i==10)
all(error() for i in range(2))
… 次の例外が発生します。
Traceback (most recent call last):
File "gs_exc.py", line 8, in <genexpr>
all(error() for i in range(2))
File "gs_exc.py", line 6, in error
return next(i for i in range(3) if i==10)
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "gs_exc.py", line 8, in <module>
all(error() for i in range(2))
RuntimeError: generator raised StopIteration
インポートのないPython 3.5 および 3.6__future__
では、警告が発生します。例えば:
# gs_warn.py
def error():
return next(i for i in range(3) if i==10)
all(error() for i in range(2))
$ python3.5 -Wd gs_warn.py
gs_warn.py:6: PendingDeprecationWarning: generator '<genexpr>' raised StopIteration
all(error() for i in range(2))
$ python3.6 -Wd gs_warn.py
gs_warn.py:6: DeprecationWarning: generator '<genexpr>' raised StopIteration
all(error() for i in range(2))