8000 bpo-32610: Fix asyncio.all_tasks() to return only pending tasks. (GH-… · python/cpython@416c1eb · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 416c1eb

Browse files
authored
bpo-32610: Fix asyncio.all_tasks() to return only pending tasks. (GH-7174)
1 parent fdccfe0 commit 416c1eb

File tree

7 files changed

+51
-9
lines changed

7 files changed

+51
-9
lines changed

Doc/library/asyncio-task.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,8 @@ Task
443443
Return a set of all tasks for an event loop.
444444

445445
By default all tasks for the current event loop are returned.
446+
If *loop* is ``None``, :func:`get_event_loop` function
447+
is used to get the current loop.
446448

447449
.. classmethod:: current_task(loop=None)
448450

@@ -567,8 +569,9 @@ Task functions
567569

568570
Return a set of :class:`Task` objects created for the loop.
569571

570-
If *loop* is ``None`` :func:`get_event_loop` is used for getting
571-
current loop.
572+
If *loop* is ``None``, :func:`get_running_loop` is used for getting
573+
current loop (contrary to the deprecated :meth:`Task.all_tasks` method
574+
that uses :func:`get_event_loop`.)
572575

573576
.. versionadded:: 3.7
574577

Lib/asyncio/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
from .tasks import *
1919
from .transports import *
2020

21+
# Exposed for _asynciomodule.c to implement now deprecated
22+
# Task.all_tasks() method. This function will be removed in 3.9.
23+
from .tasks import _all_tasks_compat # NoQA
24+
2125
__all__ = (base_events.__all__ +
2226
coroutines.__all__ +
2327
events.__all__ +

Lib/asyncio/runners.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ async def main():
5151

5252

5353
def _cancel_all_tasks(loop):
54-
to_cancel = [task for task in tasks.all_tasks(loop)
55-
if not task.done()]
54+
to_cancel = tasks.all_tasks(loop)
5655
if not to_cancel:
5756
return
5857

Lib/asyncio/tasks.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ def current_task(loop=None):
3333

3434
def all_tasks(loop=None):
3535
"""Return a set of all tasks for the loop."""
36+
if loop is None:
37+
loop = events.get_running_loop()
38+
return {t for t in _all_tasks
39+
if futures._get_loop(t) is loop and not t.done()}
40+
41+
42+
def _all_tasks_compat(loop=None):
43+
# Different from "all_task()" by returning *all* Tasks, including
44+
# the completed ones. Used to implement deprecated "Tasks.all_task()"
45+
# method.
3646
if loop is None:
3747
loop = events.get_event_loop()
3848
return {t for t in _all_tasks if futures._get_loop(t) is loop}
@@ -82,7 +92,7 @@ def all_tasks(cls, loop=None):
8292
"use asyncio.all_tasks() instead",
8393
PendingDeprecationWarning,
8494
stacklevel=2)
85-
return all_tasks(loop)
95+
return _all_tasks_compat(loop)
8696

8797
def __init__(self, coro, *, loop=None):
8898
super().__init__(loop=loop)

Lib/test/test_asyncio/test_tasks.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,8 +1897,10 @@ def kill_me(loop):
18971897
# See http://bugs.python.org/issue29271 for details:
18981898
asyncio.set_event_loop(self.loop)
18991899
try:
1900-
self.assertEqual(asyncio.all_tasks(), {task})
1901-
self.assertEqual(asyncio.all_tasks(None), {task})
1900+
with self.assertWarns(PendingDeprecationWarning):
1901+
self.assertEqual(Task.all_tasks(), {task})
1902+
with self.assertWarns(PendingDeprecationWarning):
1903+
self.assertEqual(Task.all_tasks(None), {task})
19021904
finally:
19031905
asyncio.set_event_loop(None)
19041906

@@ -2483,6 +2485,9 @@ class TaskLike:
24832485
def _loop(self):
24842486
return loop
24852487

2488+
def done(self):
2489+
return False
2490+
24862491
task = TaskLike()
24872492
loop = mock.Mock()
24882493

@@ -2496,6 +2501,9 @@ class TaskLike:
24962501
def get_loop(self):
24972502
return loop
24982503

2504+
def done(self):
2505+
return False
2506+
24992507
task = TaskLike()
25002508
loop = mock.Mock()
25012509

@@ -2504,6 +2512,23 @@ def get_loop(self):
25042512
self.assertEqual(asyncio.all_tasks(loop), {task})
25052513
self._unregister_task(task)
25062514

2515+
def test__register_task_3(self):
2516+
class TaskLike:
2517+
def get_loop(self):
2518+
return loop
2519+
2520+
def done(self):
2521+
return True
2522+
2523+
task = TaskLike()
2524+
loop = mock.Mock()
2525+
2526+
self.assertEqual(asyncio.all_tasks(loop), set())
2527+
self._register_task(task)
2528+
self.assertEqual(asyncio.all_tasks(loop), set())
2529+
self.assertEqual(asyncio.Task.all_tasks(loop), {task})
2530+
self._unregister_task(task)
2531+
25072532
def test__enter_task(self):
25082533
task = mock.Mock()
25092534
loop = mock.Mock()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make asyncio.all_tasks() return only pending tasks.

Modules/_asynciomodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module _asyncio
1111
/* identifiers used from some functions */
1212
_Py_IDENTIFIER(__asyncio_running_event_loop__);
1313
_Py_IDENTIFIER(add_done_callback);
14-
_Py_IDENTIFIER(all_tasks);
14+
_Py_IDENTIFIER(_all_tasks_compat);
1515
_Py_IDENTIFIER(call_soon);
1616
_Py_IDENTIFIER(cancel);
1717
_Py_IDENTIFIER(current_task);
@@ -2125,7 +2125,7 @@ _asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop)
21252125
return NULL;
21262126
}
21272127

2128-
all_tasks_func = _PyObject_GetAttrId(asyncio_mod, &PyId_all_tasks);
2128+
all_tasks_func = _PyObject_GetAttrId(asyncio_mod, &PyId__all_tasks_compat);
21292129
if (all_tasks_func == NULL) {
21302130
return NULL;
21312131
}

0 commit comments

Comments
 (0)
0