[issue34730] aclose() doesn't stop raise StopAsyncIteration / GeneratorExit to __anext__()

2018-09-18 Thread Devin Fee


New submission from Devin Fee :

I expected an async-generator's aclose() method to cancel it's __anext__(). 
Instead, the task isn't cancelled, and (it seems) manually cleanup is necessary.


@pytest.mark.asyncio
async def test_aclose_cancels():
done = False
event = asyncio.Event()
agen = None

async def make_agen():
try:
await event.wait()
raise NotImplementedError()
yield  # pylint: disable=W0101, unreachable
finally:
nonlocal done
done = True

async def run():
nonlocal agen
agen = make_agen()
await agen.__anext__()

task = asyncio.ensure_future(run())
await asyncio.sleep(.01)

await agen.aclose()
await asyncio.sleep(.01)

assert done
assert task.done() and task.exception()


Looking at the tests for CPython, the implementation seems to expect it, but 
I'm unclear if PEP-525 actually intends for this to be the case: 
https://github.com/python/cpython/blob/e42b705188271da108de42b55d9344642170aa2b/Lib/test/test_asyncgen.py#L657

Alternatively, maybe I shouldn't be calling aclose, and instead I should be 
cancelling the task:

@pytest.mark.asyncio
async def test_cancel_finalizes():
done = False
event = asyncio.Event()
agen = None

async def make_agen():
try:
await event.wait()
raise NotImplementedError()
yield  # pylint: disable=W0101, unreachable
finally:
nonlocal done
done = True

async def run():
nonlocal agen
agen = make_agen()
await agen.__anext__()

task = asyncio.ensure_future(run())
await asyncio.sleep(.01)
task.cancel()
await asyncio.sleep(.01)

assert done
assert task.done()

So the "bug" here is one of PEP-525 clarification.

--
components: asyncio
messages: 325699
nosy: asvetlov, dfee, yselivanov
priority: normal
severity: normal
status: open
title: aclose() doesn't stop raise StopAsyncIteration / GeneratorExit to 
__anext__()
versions: Python 3.7

___
Python tracker 
<https://bugs.python.org/issue34730>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue34730] aclose() doesn't stop raise StopAsyncIteration / GeneratorExit to __anext__()

2018-09-18 Thread Devin Fee


Devin Fee  added the comment:

I've worked around this problem by doing something like this:

async def close_cancelling(agen):
while True:
try:
task = asyncio.ensure_future(agen.__anext__())
await task
yield task.result()
except (GeneratorExit, StopAsyncIteration):
await agen.aclose()
task.cancel()
break


async def run():
try:
async for v in close_cancelling(agen):
received.append(v)
except asyncio.CancelledError:
# handle finalization
pass

Though, I'm still convinced that `aclose()` should call raise 
`StopAsyncIteration` on `agen.ag_await`

--

___
Python tracker 
<https://bugs.python.org/issue34730>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue34730] aclose() doesn't stop raise StopAsyncIteration / GeneratorExit to __anext__()

2018-09-19 Thread Devin Fee


Change by Devin Fee :


--
versions: +Python 3.6

___
Python tracker 
<https://bugs.python.org/issue34730>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com