[issue33117] asyncio example uses non-existing/documented method

New submission from Henrique Fingler <idnpolar@gmail.com>: In the documentation of asyncio.run_coroutine_threadsafe(coro, loop), in Section 19.5.3.6 (https://docs.python.org/3/library/asyncio-task.html#asyncio.run_coroutine_th...), the example code does the following: future = asyncio.run_coroutine_threadsafe(coro, loop) # Wait for the result with an optional timeout argument assert future.result(timeout) == 3 The problem is that the result method of a future, according to the documentation doesn't take parameters. It's in Section 19.5.3.4 (https://docs.python.org/3.8/library/asyncio-task.html#asyncio.Future.done) result() Return the result this future represents. The same function is used in Section 18.5.9.3 (https://docs.python.org/3/library/asyncio-dev.html#concurrency-and-multithre...) This error is present in all Python 3.* docs. From the asyncio source code (https://github.com/python/cpython/blob/master/Lib/asyncio/futures.py), we have this in the Future class definition: class Future: """This class is *almost* compatible with concurrent.futures.Future. Differences: - This class is not thread-safe. - result() and exception() do not take a timeout argument and raise an exception when the future isn't done yet. .... So this example needs to be reworked, I'd do it if I knew more about asyncio. My ideas involve either using a add_done_callback with a flag or just busy waiting until future.done(). ---------- assignee: docs@python components: Documentation messages: 314223 nosy: Henrique Fingler, docs@python priority: normal severity: normal status: open title: asyncio example uses non-existing/documented method versions: Python 3.5, Python 3.6, Python 3.7, Python 3.8 _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Change by Ned Deily <nad@python.org>: ---------- nosy: +asvetlov, giampaolo.rodola, yselivanov _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Change by Terry J. Reedy <tjreedy@udel.edu>: ---------- versions: -Python 3.5 _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Karthikeyan Singaravelan <tir.karthi@gmail.com> added the comment: I think `asyncio.run_coroutine_threadsafe(coro, loop)` returns a concurrent.futures.Future [1] which supports timeout and not asyncio.Future which doesn't support timeout. Please add in if I am missing anything. Since asyncio docs are being rewritten this would be a great time to contribute too if you would like to add more clarification. Docs at [1] also say the below : asyncio.run_coroutine_threadsafe(coro, loop) Submit a coroutine to the given event loop. Thread-safe. Return a concurrent.futures.Future to wait for the result from another OS thread. ``` # bpo33117.py. This needs to be called from a different thread as docs said but I am using future.result(timeout) just to make sure there is no error with respect to function argument. import asyncio loop = asyncio.get_event_loop() timeout = 4 # Create a coroutine coro = asyncio.sleep(1, result=3) # Submit the coroutine to a given loop future = asyncio.run_coroutine_threadsafe(coro, loop) # Wait for the result with an optional timeout argument assert future.result(timeout) == 3 ``` ➜ cpython git:(master) ./python.exe bpo33117.py Traceback (most recent call last): File "../bpo33117.py", line 13, in <module> assert future.result(timeout) == 3 File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/concurrent/futures/_base.py", line 438, in result raise TimeoutError() concurrent.futures._base.TimeoutError [1] https://docs.python.org/3.8/library/concurrent.futures.html#concurrent.futur... Thanks ---------- nosy: +xtreak _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Andrew Svetlov <andrew.svetlov@gmail.com> added the comment: @xtreak is right, `run_coroutine_threadsafe()` returns `concurrent.futures.Future` object. Personally, I like the fact that `fut.result()` is called with timeout parameter to reflect the fact of the different object type. ---------- resolution: -> not a bug stage: -> resolved status: open -> closed _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Change by Ned Deily <nad@python.org>: ---------- nosy: +asvetlov, giampaolo.rodola, yselivanov _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Change by Terry J. Reedy <tjreedy@udel.edu>: ---------- versions: -Python 3.5 _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Karthikeyan Singaravelan <tir.karthi@gmail.com> added the comment: I think `asyncio.run_coroutine_threadsafe(coro, loop)` returns a concurrent.futures.Future [1] which supports timeout and not asyncio.Future which doesn't support timeout. Please add in if I am missing anything. Since asyncio docs are being rewritten this would be a great time to contribute too if you would like to add more clarification. Docs at [1] also say the below : asyncio.run_coroutine_threadsafe(coro, loop) Submit a coroutine to the given event loop. Thread-safe. Return a concurrent.futures.Future to wait for the result from another OS thread. ``` # bpo33117.py. This needs to be called from a different thread as docs said but I am using future.result(timeout) just to make sure there is no error with respect to function argument. import asyncio loop = asyncio.get_event_loop() timeout = 4 # Create a coroutine coro = asyncio.sleep(1, result=3) # Submit the coroutine to a given loop future = asyncio.run_coroutine_threadsafe(coro, loop) # Wait for the result with an optional timeout argument assert future.result(timeout) == 3 ``` ➜ cpython git:(master) ./python.exe bpo33117.py Traceback (most recent call last): File "../bpo33117.py", line 13, in <module> assert future.result(timeout) == 3 File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/concurrent/futures/_base.py", line 438, in result raise TimeoutError() concurrent.futures._base.TimeoutError [1] https://docs.python.org/3.8/library/concurrent.futures.html#concurrent.futur... Thanks ---------- nosy: +xtreak _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________

Andrew Svetlov <andrew.svetlov@gmail.com> added the comment: @xtreak is right, `run_coroutine_threadsafe()` returns `concurrent.futures.Future` object. Personally, I like the fact that `fut.result()` is called with timeout parameter to reflect the fact of the different object type. ---------- resolution: -> not a bug stage: -> resolved status: open -> closed _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33117> _______________________________________
participants (5)
-
Andrew Svetlov
-
Henrique Fingler
-
Karthikeyan Singaravelan
-
Ned Deily
-
Terry J. Reedy