Deprecate the iterator interface of async generator `asend`/`athrow` objects

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.

But yield from doesn’t drop the return value. It returns it. E.g.: ‘x = yield from …’

Yeah, but yield from cannot be used inside a coroutine so it isn’t very useful.

Not as of PEP 828.

Would async_generator_asend and async_generator_athrow gain async_generator_asend_wrapper and async_generator_athrow_wrapper like coroutine_wrapper?

Otherwise we’d get TypeError: __await__() returned non-iterator of type 'async_generator_asend'