blob: d4612dd8179988d515aecb1ad848ea003a4b6d07 [file] [log] [blame]
#!/usr/bin/env python3
"""Test various combinations of generators/coroutines.
This was used to cross-check the errors in the test case
testFullCoroutineMatrix in test-data/unit/check-async-await.test.
"""
from __future__ import annotations
import sys
from types import coroutine
from typing import Any, Awaitable, Generator, Iterator
# The various things you might try to use in `await` or `yield from`.
def plain_generator() -> Generator[str, None, int]:
yield "a"
return 1
async def plain_coroutine() -> int:
return 1
@coroutine
def decorated_generator() -> Generator[str, None, int]:
yield "a"
return 1
@coroutine
async def decorated_coroutine() -> int:
return 1
class It(Iterator[str]):
stop = False
def __iter__(self) -> It:
return self
def __next__(self) -> str:
if self.stop:
raise StopIteration("end")
else:
self.stop = True
return "a"
def other_iterator() -> It:
return It()
class Aw(Awaitable[int]):
def __await__(self) -> Generator[str, Any, int]:
yield "a"
return 1
def other_coroutine() -> Aw:
return Aw()
# The various contexts in which `await` or `yield from` might occur.
def plain_host_generator(func) -> Generator[str, None, None]:
yield "a"
x = 0
f = func()
try:
x = yield from f # noqa: F841
finally:
try:
f.close()
except AttributeError:
pass
async def plain_host_coroutine(func) -> None:
x = 0
x = await func() # noqa: F841
@coroutine
def decorated_host_generator(func) -> Generator[str, None, None]:
yield "a"
x = 0
f = func()
try:
x = yield from f # noqa: F841
finally:
try:
f.close()
except AttributeError:
pass
@coroutine
async def decorated_host_coroutine(func) -> None:
x = 0
x = await func() # noqa: F841
# Main driver.
def main() -> None:
verbose = "-v" in sys.argv
for host in [
plain_host_generator,
plain_host_coroutine,
decorated_host_generator,
decorated_host_coroutine,
]:
print()
print("==== Host:", host.__name__)
for func in [
plain_generator,
plain_coroutine,
decorated_generator,
decorated_coroutine,
other_iterator,
other_coroutine,
]:
print(" ---- Func:", func.__name__)
try:
f = host(func)
for i in range(10):
try:
x = f.send(None)
if verbose:
print(" yield:", x)
except StopIteration as e:
if verbose:
print(" stop:", e.value)
break
else:
if verbose:
print(" ???? still going")
except Exception as e:
print(" error:", repr(e))
# Run main().
if __name__ == "__main__":
main()