| #!/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() |