Problem
Cannot catch a StopIteration raised from within a iterator.
Example
from typing import (
Generator,
Iterable,
List
)
import sys
import pathlib
from itertools import islice
import numpy as np
def take(n: int, iterable: Iterable) -> List:
taken = list(islice(iterable, 0, n))
if len(taken) > 0:
return taken
else:
print("Raising StopIteration")
raise StopIteration("Nothing to take") # <----- Raise StopIteration
def file_line_stream(path: str) -> Generator[str, None, None]:
if not pathlib.Path(path).is_file():
raise FileNotFoundError(f"file {path} does not exist or non file")
try:
_file = pathlib.Path(path)
with _file.open() as f:
for line in f:
yield line.rstrip()
except (IOError, FileNotFoundError) as e:
raise RuntimeError("Read file failure") from e
def get_sentences(path_to_file, num_sentences):
counter = 0
stream = file_line_stream(path_to_file)
try:
while True:
_lines = take(num_sentences, stream)
print(f"Count {counter}: yielding [{_lines[0]}]\n")
yield np.array(_lines)
counter += 1
finally:
stream.close()
def test():
path_to_input = "test_has_two_lines.txt"
generator = get_sentences(path_to_file=path_to_input, num_sentences=100)
for i in range(10):
# ----------------------------------------------------------------------
# Want to catch the StopIteration raised from within the generator.
# ----------------------------------------------------------------------
try:
next(generator)
except StopIteration as e:
print("Caught at StopIteration except")
generator.close()
except Exception as e: # <--- Raised StopIteration will get caught here
print("Caught at catch-all except: %s", sys.exc_info()[0])
generator.close()
raise e
if __name__ == '__main__':
test()
Result
Count 0: yielding [previous monthly <unk> of the major market index futures and standard & poor 's <unk> index options have produced spectacular volatility]
Raising StopIteration
Caught at catch-all except: %s <class 'RuntimeError'>
Traceback (most recent call last):
File "test_050_word2vec.py", line 39, in get_sentences
_lines = take(num_sentences, stream)
File "test_050_word2vec.py", line 19, in take
raise StopIteration("Nothing to take") # <----- Raise StopIteration
StopIteration: Nothing to take
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test_050_word2vec.py", line 67, in <module>
test()
File "test_050_word2vec.py", line 63, in test
raise e
File "test_050_word2vec.py", line 55, in test
next(generator)
RuntimeError: generator raised StopIteration <----- Converted into RuntimeError