New submission from Nick Coghlan: In issue 24342, the invocation of coroutine wrappers specified via sys.set_coroutine_wrapper was fixed to catch and report the case of infinite recursion, where the wrapper attempts to instantiate a nested coroutine (which would call the wrapper, which would attempt to instantiate the coroutine, etc, etc)
The docs for sys.set_coroutine_wrapper include an example of this failure case: https://docs.python.org/3/library/sys.html#sys.set_coroutine_wrapper However, if you're not reading carefully, it looks like an example of how to *use* sys.set_coroutine_wrapper, rather than an example of a case that won't work. It would be better to include an example that either doesn't wrap the coroutine at all, or else uses one of the non-native coroutine emulations to avoid the infinite recursion problem: ``` import asyncio, sys def wrapper(coro): @asyncio.coroutine def wrap(coro): print("Coroutine started") result = yield from coro print("Coroutine finished") return result return wrap(coro) sys.set_coroutine_wrapper(wrapper) async def foo(): print("Coroutine running") return "Coroutine result" import asyncio asyncio.get_event_loop().run_until_complete(foo()) ``` Also related: I discovered in writing this that "sys.set_coroutine_wrapper(None)" doesn't actually turn off coroutine wrapping. Instead, you still get this exception when attempting to recursively define an unwrapped one: RuntimeError: coroutine wrapper <NULL> attempted to recursively wrap <code object wrap at 0x7eff31fbde40, file "<stdin>", line 2>) That error was produced as follows: ``` import sys, contextlib @contextlib.contextmanager def disable_coroutine_wrapping(): wrapper = sys.get_coroutine_wrapper() sys.set_coroutine_wrapper(None) try: yield finally: sys.set_coroutine_wrapper(wrapper) def wrapper(coro): async def wrap(coro): print("Coroutine started") result = await coro print("Coroutine finished") return result with disable_coroutine_wrapping(): return wrap(coro) sys.set_coroutine_wrapper(wrapper) async def foo(): print("Coroutine running") return "Coroutine result" import asyncio asyncio.get_event_loop().run_until_complete(foo()) ``` ---------- assignee: docs@python components: Documentation messages: 295231 nosy: docs@python, giampaolo.rodola, haypo, ncoghlan, yselivanov priority: normal severity: normal stage: needs patch status: open title: Misleading example in sys.set_coroutine_wrapper docs type: enhancement versions: Python 3.6, Python 3.7 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue30578> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com