@@ -103,20 +103,11 @@ the logger ``'asyncio'``.
103103Detect coroutine objects never scheduled
104104----------------------------------------
105105
106- When a coroutine function is called but not passed to :func: `async ` or to the
107- :class: `Task ` constructor, it is not scheduled and it is probably a bug.
108-
109- To detect such bug, :ref: `enable the debug mode of asyncio
110- <asyncio-debug-mode>`. When the coroutine object is destroyed by the garbage
111- collector, a log will be emitted with the traceback where the coroutine
112- function was called. See the :ref: `asyncio logger <asyncio-logger >`.
113-
114- The debug flag changes the behaviour of the :func: `coroutine ` decorator. The
115- debug flag value is only used when then coroutine function is defined, not when
116- it is called. Coroutine functions defined before the debug flag is set to
117- ``True `` will not be tracked. For example, it is not possible to debug
118- coroutines defined in the :mod: `asyncio ` module, because the module must be
119- imported before the flag value can be changed.
106+ When a coroutine function is called and its result is not passed to
107+ :func: `async ` or to the :meth: `BaseEventLoop.create_task ` method: the execution
108+ of the coroutine objet will never be scheduled and it is probably a bug.
109+ :ref: `Enable the debug mode of asyncio <asyncio-debug-mode >` to :ref: `log a
110+ warning <asyncio-logger>` to detect it.
120111
121112Example with the bug::
122113
@@ -130,20 +121,27 @@ Example with the bug::
130121
131122Output in debug mode::
132123
133- Coroutine 'test' defined at test.py:4 was never yielded from
124+ Coroutine test() at test.py:3 was never yielded from
125+ Coroutine object created at (most recent call last):
126+ File "test.py", line 7, in <module>
127+ test()
134128
135- The fix is to call the :func: `async ` function or create a :class: ` Task ` object
136- with this coroutine object.
129+ The fix is to call the :func: `async ` function or the
130+ :meth: ` BaseEventLoop.create_task ` method with the coroutine object.
137131
132+ .. seealso ::
133+
134+ :ref: `Pending task destroyed <asyncio-pending-task-destroyed >`.
138135
139- Detect exceptions not consumed
140- ------------------------------
136+
137+ Detect exceptions never consumed
138+ --------------------------------
141139
142140Python usually calls :func: `sys.displayhook ` on unhandled exceptions. If
143- :meth: `Future.set_exception ` is called, but the exception is not consumed,
144- :func: `sys.displayhook ` is not called. Instead, a log is emitted when the
145- future is deleted by the garbage collector, with the traceback where the
146- exception was raised. See the :ref: ` asyncio logger < asyncio-logger >` .
141+ :meth: `Future.set_exception ` is called, but the exception is never consumed,
142+ :func: `sys.displayhook ` is not called. Instead, a :ref: ` a log is emitted
143+ <asyncio-logger>` when the future is deleted by the garbage collector, with the
144+ traceback where the exception was raised .
147145
148146Example of unhandled exception::
149147
@@ -159,16 +157,27 @@ Example of unhandled exception::
159157
160158Output::
161159
162- Future/Task exception was never retrieved:
160+ Task exception was never retrieved
161+ future: <Task finished bug() done at asyncio/coroutines.py:139 exception=Exception('not consumed',)>
162+ source_traceback: Object created at (most recent call last):
163+ File "test.py", line 10, in <module>
164+ asyncio.async(bug())
165+ File "asyncio/tasks.py", line 510, in async
166+ task = loop.create_task(coro_or_future)
163167 Traceback (most recent call last):
164- File "/usr/lib/python3.4/ asyncio/tasks.py", line 279 , in _step
168+ File "asyncio/tasks.py", line 244 , in _step
165169 result = next(coro)
166- File "/usr/lib/python3.4/asyncio/tasks.py", line 80, in coro
170+ File "coroutines.py", line 78, in __next__
171+ return next(self.gen)
172+ File "asyncio/coroutines.py", line 141, in coro
167173 res = func(*args, **kw)
168- File "test.py", line 5 , in bug
174+ File "test.py", line 7 , in bug
169175 raise Exception("not consumed")
170176 Exception: not consumed
171177
178+ :ref: `Enable the debug mode of asyncio <asyncio-debug-mode >` to get the
179+ traceback where the task was created.
180+
172181There are different options to fix this issue. The first option is to chain to
173182coroutine in another coroutine and use classic try/except::
174183
@@ -195,7 +204,7 @@ function::
195204See also the :meth: `Future.exception ` method.
196205
197206
198- Chain coroutines correctly
207+ Chain correctly coroutines
199208--------------------------
200209
201210When a coroutine function calls other coroutine functions and tasks, they
@@ -246,7 +255,9 @@ Actual output::
246255
247256 (3) close file
248257 (2) write into file
249- Pending tasks at exit: {Task(<create>)<PENDING>}
258+ Pending tasks at exit: {<Task pending create() at test.py:7 wait_for=<Future pending cb=[Task._wakeup()]>>}
259+ Task was destroyed but it is pending!
260+ task: <Task pending create() done at test.py:5 wait_for=<Future pending cb=[Task._wakeup()]>>
250261
251262The loop stopped before the ``create() `` finished, ``close() `` has been called
252263before ``write() ``, whereas coroutine functions were called in this order:
@@ -272,3 +283,29 @@ Or without ``asyncio.async()``::
272283 yield from asyncio.sleep(2.0)
273284 loop.stop()
274285
286+
287+ .. _asyncio-pending-task-destroyed :
288+
289+ Pending task destroyed
290+ ----------------------
291+
292+ If a pending task is destroyed, the execution of its wrapped :ref: `coroutine
293+ <coroutine>` did not complete. It is probably a bug and so a warning is logged.
294+
295+ Example of log::
296+
297+ Task was destroyed but it is pending!
298+ source_traceback: Object created at (most recent call last):
299+ File "test.py", line 17, in <module>
300+ task = asyncio.async(coro, loop=loop)
301+ File "asyncio/tasks.py", line 510, in async
302+ task = loop.create_task(coro_or_future)
303+ task: <Task pending kill_me() done at test.py:5 wait_for=<Future pending cb=[Task._wakeup()]>>
304+
305+ :ref: `Enable the debug mode of asyncio <asyncio-debug-mode >` to get the
306+ traceback where the task was created.
307+
308+ .. seealso ::
309+
310+ :ref: `Detect coroutine objects never scheduled <asyncio-coroutine-not-scheduled >`.
311+
0 commit comments