I propose to deprecate __iter__ and __next__ on the async_generator_asend and
async_generator_athrow types, leaving them with __await__, send, throw and
close like coroutines as described in PEP 525.
The motivation is that synchronous iteration over them silently loses data. The
result of the await is delivered as StopIteration, so a for loop reads it as the
end of the iteration and drops the value, and yield from does the same.
Repro:
async def ag():
print("started")
x = yield 1
yield 2
for v in ag().asend(None):
print("got", v)
def g():
yield from ag().asend(None)
print(list(g()))
Current result:
started
started
[]
Proposal:
Traceback (most recent call last):
File "demo.py", line 6, in <module>
for v in ag().asend(None):
TypeError: 'async_generator_asend' object is not iterable
This would make it possible to in future implement these objects as regular coroutines significantly reducing the special casing involved in the interpreter for async generators and also better introspection for asyncio tools. Since, it is fundamentally broken, a deprecation of 2 releases seems reasonable and propose to remove these in 3.18.