blob: c266d0400aba46125bb2f1a4de661fa0bd956df9 [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.
"""
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
finally:
try:
f.close()
except AttributeError:
pass
async def plain_host_coroutine(func) -> None:
x = 0
x = await func()
@coroutine
def decorated_host_generator(func) -> Generator[str, None, None]:
yield 'a'
x = 0
f = func()
try:
x = yield from f
finally:
try:
f.close()
except AttributeError:
pass
@coroutine
async def decorated_host_coroutine(func) -> None:
x = 0
x = await func()
# Main driver.
def main():
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()