-
I find the behavior described by the following doctests — where an exception thrown by a loop iterating a generator-backed stream is thrown into the generator and doesn't escape the loop — very surprising: import asyncio
from aiostream import operator
@operator
async def yielder():
try:
yield 1
yield 2
yield 3
except Exception as e:
print("Exception in yielder:", e)
def raw_behavior():
"""
>>> raw_behavior()
Exception outside iterator: boom
"""
async def iterator():
async for x in yielder.raw():
if x == 2:
raise RuntimeError("boom")
try:
asyncio.run(iterator())
except Exception as e:
print("Exception outside iterator:", e)
else:
print("Iterator apparently succeeded")
def stream_behavior():
"""
>>> stream_behavior()
Exception in yielder: boom
Iterator apparently succeeded
"""
async def iterator():
async with yielder().stream() as streamer:
async for x in streamer:
if x == 2:
raise RuntimeError("boom")
try:
asyncio.run(iterator())
except Exception as e:
print("Exception outside iterator:", e)
else:
print("Iterator apparently succeeded") I don't understand the purpose of this, and don't see it described in the documentation, but it does look deliberate ( |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi @npt First I want to point out that there are two parts in your original question
This I'll address later.
This one is simple: it doesn't escape the loop because it's not re-raised in @operator
async def yielder():
try:
yield 1
yield 2
yield 3
except Exception as e:
print("Exception in yielder:", e)
raise and you'll get the expected behavior. Now about the first point:
This behavior is indeed on purpose because we want to emulate the behavior of a context manager. Note the same In the context of Note than when several operators are piped, this creates a stack of nested contexts. If an exception is raised in the deepest level (in your example the However, the exception usually traverse the operators without being affected. It's only in rare situations that the operators catch the exception in order to do something specific with it (for instance if you were to write a I hope this answers your question :) |
Beta Was this translation helpful? Give feedback.
Hi @npt
First I want to point out that there are two parts in your original question
This I'll address later.
This one is simple: it doesn't escape the loop because it's not re-raised in
yielder
. Try this code instead:and you'll get the expected behavior.
Now about the first point:
This b…