From ed0e527dbf041a025f8aaba876764948b18ea514 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Thu, 2 Mar 2017 17:34:19 -0500 Subject: [PATCH 1/3] bpo-29271: Fix Task.current_task and Task.all_tasks to accept None. --- Lib/test/test_asyncio/test_tasks.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ Modules/_asynciomodule.c | 12 ++++++------ Modules/clinic/_asynciomodule.c.h | 6 +++--- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index fdf91a36b5ecac..c26b7e03154457 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1461,6 +1461,14 @@ def test_current_task(self): def coro(loop): self.assertTrue(Task.current_task(loop=loop) is task) + # See http://bugs.python.org/issue29271 for details: + asyncio.set_event_loop(loop) + try: + self.assertTrue(Task.current_task(None) is task) + self.assertTrue(Task.current_task() is task) + finally: + asyncio.set_event_loop(None) + task = self.new_task(self.loop, coro(self.loop)) self.loop.run_until_complete(task) self.assertIsNone(Task.current_task(loop=self.loop)) @@ -1805,8 +1813,17 @@ def kill_me(loop): # schedule the task coro = kill_me(self.loop) task = asyncio.ensure_future(coro, loop=self.loop) + self.assertEqual(Task.all_tasks(loop=self.loop), {task}) + # See http://bugs.python.org/issue29271 for details: + asyncio.set_event_loop(self.loop) + try: + self.assertEqual(Task.all_tasks(), {task}) + self.assertEqual(Task.all_tasks(None), {task}) + finally: + asyncio.set_event_loop(None) + # execute the task so it waits for future self.loop._run_once() self.assertEqual(len(self.loop._ready), 0) diff --git a/Misc/NEWS b/Misc/NEWS index 9da682b38792a9..f5fe261d9dbada 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -688,6 +688,9 @@ Library - Issue #24142: Reading a corrupt config file left configparser in an invalid state. Original patch by Florian Höch. +- Issue #29271: Fix Task.current_task and Task.all_tasks to accept + None argument. + Windows ------- diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index ceac7f0039e949..220479247b0f72 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1414,7 +1414,7 @@ TaskObj_get_fut_waiter(TaskObj *task) @classmethod _asyncio.Task.current_task - loop: 'O' = NULL + loop: 'O' = None Return the currently running task in an event loop or None. @@ -1425,11 +1425,11 @@ None is returned when called not in the context of a Task. static PyObject * _asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop) -/*[clinic end generated code: output=99fbe7332c516e03 input=cd784537f02cf833]*/ +/*[clinic end generated code: output=99fbe7332c516e03 input=a0d6cdf2e3b243e1]*/ { PyObject *res; - if (loop == NULL) { + if (loop == Py_None) { loop = _PyObject_CallNoArg(asyncio_get_event_loop); if (loop == NULL) { return NULL; @@ -1501,7 +1501,7 @@ task_all_tasks(PyObject *loop) @classmethod _asyncio.Task.all_tasks - loop: 'O' = NULL + loop: 'O' = None Return a set of all tasks for an event loop. @@ -1510,11 +1510,11 @@ By default all tasks for the current event loop are returned. static PyObject * _asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop) -/*[clinic end generated code: output=11f9b20749ccca5d input=cd64aa5f88bd5c49]*/ +/*[clinic end generated code: output=11f9b20749ccca5d input=c6f5b53bd487488f]*/ { PyObject *res; - if (loop == NULL) { + if (loop == Py_None) { loop = _PyObject_CallNoArg(asyncio_get_event_loop); if (loop == NULL) { return NULL; diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index f3204fb9a944b2..94a6f8df363a20 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -278,7 +278,7 @@ _asyncio_Task_current_task(PyTypeObject *type, PyObject **args, Py_ssize_t nargs PyObject *return_value = NULL; static const char * const _keywords[] = {"loop", NULL}; static _PyArg_Parser _parser = {"|O:current_task", _keywords, 0}; - PyObject *loop = NULL; + PyObject *loop = Py_None; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &loop)) { @@ -310,7 +310,7 @@ _asyncio_Task_all_tasks(PyTypeObject *type, PyObject **args, Py_ssize_t nargs, P PyObject *return_value = NULL; static const char * const _keywords[] = {"loop", NULL}; static _PyArg_Parser _parser = {"|O:all_tasks", _keywords, 0}; - PyObject *loop = NULL; + PyObject *loop = Py_None; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &loop)) { @@ -517,4 +517,4 @@ _asyncio_Task__wakeup(TaskObj *self, PyObject **args, Py_ssize_t nargs, PyObject exit: return return_value; } -/*[clinic end generated code: output=07a15bbb28d03edc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3dfec49689cebd4c input=a9049054013a1b77]*/ From e9cb8a4d98c5fc1a98a3ff51eaf19e2a8faa37c7 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Thu, 2 Mar 2017 17:51:32 -0500 Subject: [PATCH 2/3] Address Serhiy's feedback. --- Lib/test/test_asyncio/test_tasks.py | 4 ++-- Misc/NEWS | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index c26b7e03154457..754a67519ba9d5 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1464,8 +1464,8 @@ def coro(loop): # See http://bugs.python.org/issue29271 for details: asyncio.set_event_loop(loop) try: - self.assertTrue(Task.current_task(None) is task) - self.assertTrue(Task.current_task() is task) + self.assertIs(Task.current_task(None), task) + self.assertIs(Task.current_task(), task) finally: asyncio.set_event_loop(None) diff --git a/Misc/NEWS b/Misc/NEWS index f5fe261d9dbada..bdda2d4e5cfa43 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -256,6 +256,9 @@ Extension Modules Library ------- +- Issue #29271: Fix Task.current_task and Task.all_tasks implemented in C + to accept None argument as their pure Python implementation. + - bpo-29615: SimpleXMLRPCDispatcher no longer chains KeyError (or any other exception) to exception(s) raised in the dispatched methods. Patch by Petr Motejlek. @@ -688,9 +691,6 @@ Library - Issue #24142: Reading a corrupt config file left configparser in an invalid state. Original patch by Florian Höch. -- Issue #29271: Fix Task.current_task and Task.all_tasks to accept - None argument. - Windows ------- From 3cdab395f27ea58039c45cd35ae40f8948b2f068 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Thu, 2 Mar 2017 18:11:01 -0500 Subject: [PATCH 3/3] Fix Misc/NEWS entry --- Misc/NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS b/Misc/NEWS index bdda2d4e5cfa43..b377f78a4ba3c2 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -256,7 +256,7 @@ Extension Modules Library ------- -- Issue #29271: Fix Task.current_task and Task.all_tasks implemented in C +- bpo-29271: Fix Task.current_task and Task.all_tasks implemented in C to accept None argument as their pure Python implementation. - bpo-29615: SimpleXMLRPCDispatcher no longer chains KeyError (or any other