[docs] [issue30578] Misleading example in sys.set_coroutine_wrapper docs
Nick Coghlan
report at bugs.python.org
Mon Jun 5 22:44:33 EDT 2017
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 at python
components: Documentation
messages: 295231
nosy: docs at 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 <report at bugs.python.org>
<http://bugs.python.org/issue30578>
_______________________________________
More information about the docs
mailing list