From 336a6ced8d5ae1963787bbd3e11d4ce6b632492a Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 18:23:57 -0700 Subject: [PATCH 01/18] attempt to fix http://bugs.python.org/issue31061 --- Modules/_asynciomodule.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index b998a04e623cad..73af06d33ce92e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -962,14 +962,18 @@ FutureObj_dealloc(PyObject *self) { FutureObj *fut = (FutureObj *)self; + PyObject_GC_UnTrack(self); + if (Future_CheckExact(fut)) { /* When fut is subclass of Future, finalizer is called from * subtype_dealloc. */ + _PyObject_GC_TRACK(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } + _PyObject_GC_UNTRACK(self); } if (fut->fut_weakreflist != NULL) { @@ -1836,14 +1840,18 @@ TaskObj_dealloc(PyObject *self) { TaskObj *task = (TaskObj *)self; + PyObject_GC_UnTrack(self); + if (Task_CheckExact(self)) { /* When fut is subclass of Task, finalizer is called from * subtype_dealloc. */ + _PyObject_GC_TRACK(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } + _PyObject_GC_UNTRACK(self); } if (task->task_weakreflist != NULL) { From 4fd34a660eebe30aaba2d612e1ec093bf0ee867b Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 18:29:54 -0700 Subject: [PATCH 02/18] fix typo --- Modules/_asynciomodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 73af06d33ce92e..98613fbeec6453 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -968,12 +968,12 @@ FutureObj_dealloc(PyObject *self) /* When fut is subclass of Future, finalizer is called from * subtype_dealloc. */ - _PyObject_GC_TRACK(self); + PyObject_GC_TRACK(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - _PyObject_GC_UNTRACK(self); + PyObject_GC_UNTRACK(self); } if (fut->fut_weakreflist != NULL) { @@ -1846,12 +1846,12 @@ TaskObj_dealloc(PyObject *self) /* When fut is subclass of Task, finalizer is called from * subtype_dealloc. */ - _PyObject_GC_TRACK(self); + PyObject_GC_TRACK(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - _PyObject_GC_UNTRACK(self); + PyObject_GC_UNTRACK(self); } if (task->task_weakreflist != NULL) { From 97ccf318f4abd33b618794333c9407be6b581d6e Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 18:35:08 -0700 Subject: [PATCH 03/18] fix capitalization --- Modules/_asynciomodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 98613fbeec6453..20748eb65b188d 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -968,12 +968,12 @@ FutureObj_dealloc(PyObject *self) /* When fut is subclass of Future, finalizer is called from * subtype_dealloc. */ - PyObject_GC_TRACK(self); + PyObject_GC_Track(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - PyObject_GC_UNTRACK(self); + PyObject_GC_UnTrack(self); } if (fut->fut_weakreflist != NULL) { @@ -1846,12 +1846,12 @@ TaskObj_dealloc(PyObject *self) /* When fut is subclass of Task, finalizer is called from * subtype_dealloc. */ - PyObject_GC_TRACK(self); + PyObject_GC_Track(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - PyObject_GC_UNTRACK(self); + PyObject_GC_UnTrack(self); } if (task->task_weakreflist != NULL) { From a67847e061690f352cd8501ae0be4472026357ee Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 21:23:38 -0700 Subject: [PATCH 04/18] switch to private version --- Modules/_asynciomodule.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 20748eb65b188d..10ddf5757b3e28 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -962,18 +962,18 @@ FutureObj_dealloc(PyObject *self) { FutureObj *fut = (FutureObj *)self; - PyObject_GC_UnTrack(self); + _PyObject_GC_UNTRACK(self); if (Future_CheckExact(fut)) { /* When fut is subclass of Future, finalizer is called from * subtype_dealloc. */ - PyObject_GC_Track(self); + _PyObject_GC_TRACK(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - PyObject_GC_UnTrack(self); + _PyObject_GC_UNTRACK(self); } if (fut->fut_weakreflist != NULL) { @@ -995,7 +995,7 @@ typedef struct { static void FutureIter_dealloc(futureiterobject *it) { - PyObject_GC_UnTrack(it); + _PyObject_GC_UNTRACK(it); Py_XDECREF(it->future); PyObject_GC_Del(it); } @@ -1151,7 +1151,7 @@ future_new_iter(PyObject *fut) } Py_INCREF(fut); it->future = (FutureObj*)fut; - PyObject_GC_Track(it); + _PyObject_GC_TRACK(it); return (PyObject*)it; } @@ -1183,7 +1183,7 @@ TaskSendMethWrapper_clear(TaskSendMethWrapper *o) static void TaskSendMethWrapper_dealloc(TaskSendMethWrapper *o) { - PyObject_GC_UnTrack(o); + _PyObject_GC_UNTRACK(o); (void)TaskSendMethWrapper_clear(o); Py_TYPE(o)->tp_free(o); } @@ -1248,7 +1248,7 @@ TaskSendMethWrapper_new(TaskObj *task, PyObject *arg) Py_XINCREF(arg); o->sw_arg = arg; - PyObject_GC_Track(o); + _PyObject_GC_TRACK(o); return (PyObject*) o; } @@ -1285,7 +1285,7 @@ TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o, static void TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) { - PyObject_GC_UnTrack(o); + _PyObject_GC_UNTRACK(o); (void)TaskWakeupMethWrapper_clear(o); Py_TYPE(o)->tp_free(o); } @@ -1315,7 +1315,7 @@ TaskWakeupMethWrapper_new(TaskObj *task) Py_INCREF(task); o->ww_task = task; - PyObject_GC_Track(o); + _PyObject_GC_TRACK(o); return (PyObject*) o; } @@ -1840,18 +1840,18 @@ TaskObj_dealloc(PyObject *self) { TaskObj *task = (TaskObj *)self; - PyObject_GC_UnTrack(self); + _PyObject_GC_UNTRACK(self); if (Task_CheckExact(self)) { /* When fut is subclass of Task, finalizer is called from * subtype_dealloc. */ - PyObject_GC_Track(self); + _PyObject_GC_TRACK(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - PyObject_GC_UnTrack(self); + _PyObject_GC_UNTRACK(self); } if (task->task_weakreflist != NULL) { From e126945c55b59347cfb3da4404a1dfc32f78c827 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 21:23:54 -0700 Subject: [PATCH 05/18] undo :) --- Modules/_asynciomodule.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 10ddf5757b3e28..55cd082f247a39 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -962,18 +962,18 @@ FutureObj_dealloc(PyObject *self) { FutureObj *fut = (FutureObj *)self; - _PyObject_GC_UNTRACK(self); + PyObject_GC_UnTrack(self); if (Future_CheckExact(fut)) { /* When fut is subclass of Future, finalizer is called from * subtype_dealloc. */ - _PyObject_GC_TRACK(self); + PyObject_GC_Track(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - _PyObject_GC_UNTRACK(self); + PyObject_GC_UnTrack(self); } if (fut->fut_weakreflist != NULL) { @@ -995,7 +995,7 @@ typedef struct { static void FutureIter_dealloc(futureiterobject *it) { - _PyObject_GC_UNTRACK(it); + PyObject_GC_UnTrack(it); Py_XDECREF(it->future); PyObject_GC_Del(it); } @@ -1151,7 +1151,7 @@ future_new_iter(PyObject *fut) } Py_INCREF(fut); it->future = (FutureObj*)fut; - _PyObject_GC_TRACK(it); + PyObject_GC_Track(it); return (PyObject*)it; } @@ -1183,7 +1183,7 @@ TaskSendMethWrapper_clear(TaskSendMethWrapper *o) static void TaskSendMethWrapper_dealloc(TaskSendMethWrapper *o) { - _PyObject_GC_UNTRACK(o); + PyObject_GC_UnTrack(o); (void)TaskSendMethWrapper_clear(o); Py_TYPE(o)->tp_free(o); } @@ -1248,7 +1248,7 @@ TaskSendMethWrapper_new(TaskObj *task, PyObject *arg) Py_XINCREF(arg); o->sw_arg = arg; - _PyObject_GC_TRACK(o); + PyObject_GC_Track(o); return (PyObject*) o; } @@ -1285,7 +1285,7 @@ TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o, static void TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) { - _PyObject_GC_UNTRACK(o); + PyObject_GC_UnTrack(o); (void)TaskWakeupMethWrapper_clear(o); Py_TYPE(o)->tp_free(o); } @@ -1315,7 +1315,7 @@ TaskWakeupMethWrapper_new(TaskObj *task) Py_INCREF(task); o->ww_task = task; - _PyObject_GC_TRACK(o); + PyObject_GC_Track(o); return (PyObject*) o; } @@ -1840,18 +1840,18 @@ TaskObj_dealloc(PyObject *self) { TaskObj *task = (TaskObj *)self; - _PyObject_GC_UNTRACK(self); + PyObject_GC_UnTrack(self); if (Task_CheckExact(self)) { /* When fut is subclass of Task, finalizer is called from * subtype_dealloc. */ - _PyObject_GC_TRACK(self); + PyObject_GC_Track(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - _PyObject_GC_UNTRACK(self); + PyObject_GC_UnTrack(self); } if (task->task_weakreflist != NULL) { From de3ee0131930cea355a39de5d509571f311c4276 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 22:11:13 -0700 Subject: [PATCH 06/18] add missing untrack --- Modules/_functoolsmodule.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index da1d2e16dba746..cac247c7e3dc5e 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1074,6 +1074,8 @@ static void lru_cache_dealloc(lru_cache_object *obj) { lru_list_elem *list = lru_cache_unlink_list(obj); + PyObject_GC_UnTrack(obj); + Py_XDECREF(obj->maxsize_O); Py_XDECREF(obj->func); Py_XDECREF(obj->cache); From 6a02050ee4a73e98ffc484414366615b4fc0015d Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 23:11:53 -0700 Subject: [PATCH 07/18] revert change --- Modules/_functoolsmodule.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index cac247c7e3dc5e..da1d2e16dba746 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1074,8 +1074,6 @@ static void lru_cache_dealloc(lru_cache_object *obj) { lru_list_elem *list = lru_cache_unlink_list(obj); - PyObject_GC_UnTrack(obj); - Py_XDECREF(obj->maxsize_O); Py_XDECREF(obj->func); Py_XDECREF(obj->cache); From 503806f47a14ab8d9c0cb5b0d74d74594dd3dc95 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Mon, 31 Jul 2017 23:14:19 -0700 Subject: [PATCH 08/18] add news item --- Misc/NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Misc/NEWS b/Misc/NEWS index 38449c0409f458..43b7f3260131bf 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1? Core and Builtins ----------------- +- bpo-31061: Fixed a crash when using asyncio and threads. + - bpo-30814: Fixed a race condition when import a submodule from a package. - bpo-30736: The internal unicodedata database has been upgraded to Unicode From f90005828e9d1b05da869362a5e356aaa9157e10 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 02:05:26 -0700 Subject: [PATCH 09/18] simplify patch based on review --- Include/objimpl.h | 4 ++++ Lib/test/test_asyncio/test_futures.py | 12 ++++++++++++ Modules/_asynciomodule.c | 12 ++++-------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Include/objimpl.h b/Include/objimpl.h index 746f9c921344f7..2b6885fd9bc277 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -333,6 +333,10 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); #endif /* !Py_LIMITED_API */ PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); + +/* + See description in Doc/c-api/gcsupport.rst +*/ PyAPI_FUNC(void) PyObject_GC_Track(void *); PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); PyAPI_FUNC(void) PyObject_GC_Del(void *); diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index ce657fc1b6a058..ebedfec7fa3f5f 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -1,6 +1,7 @@ """Tests for futures.py.""" import concurrent.futures +import gc import re import sys import threading @@ -19,9 +20,11 @@ def _fakefunc(f): return f + def first_cb(): pass + def last_cb(): pass @@ -483,6 +486,15 @@ def test_future_iter_throw(self): Exception("elephant"), Exception("elephant")) self.assertRaises(TypeError, fi.throw, list) + def test_future_del_collect(self): + class Evil: + def __del__(self): + gc.collect() + + for i in range(100): + fut = self._new_future(loop=self.loop) + fut.set_result(Evil()) + @unittest.skipUnless(hasattr(futures, '_CFuture'), 'requires the C _asyncio module') diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 55cd082f247a39..d4b313480e9a10 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -962,20 +962,18 @@ FutureObj_dealloc(PyObject *self) { FutureObj *fut = (FutureObj *)self; - PyObject_GC_UnTrack(self); - if (Future_CheckExact(fut)) { /* When fut is subclass of Future, finalizer is called from * subtype_dealloc. */ - PyObject_GC_Track(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - PyObject_GC_UnTrack(self); } + PyObject_GC_UnTrack(self); + if (fut->fut_weakreflist != NULL) { PyObject_ClearWeakRefs(self); } @@ -1840,20 +1838,18 @@ TaskObj_dealloc(PyObject *self) { TaskObj *task = (TaskObj *)self; - PyObject_GC_UnTrack(self); - if (Task_CheckExact(self)) { /* When fut is subclass of Task, finalizer is called from * subtype_dealloc. */ - PyObject_GC_Track(self); if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } - PyObject_GC_UnTrack(self); } + PyObject_GC_UnTrack(self); + if (task->task_weakreflist != NULL) { PyObject_ClearWeakRefs(self); } From 483586bca5ac033b6fd434f8a1053ef9472f8477 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 09:19:13 -0700 Subject: [PATCH 10/18] remove --- Include/objimpl.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Include/objimpl.h b/Include/objimpl.h index 2b6885fd9bc277..4ac6b9e7a34548 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -334,9 +334,6 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); -/* - See description in Doc/c-api/gcsupport.rst -*/ PyAPI_FUNC(void) PyObject_GC_Track(void *); PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); PyAPI_FUNC(void) PyObject_GC_Del(void *); From b4589cebec82694d3ce53916bd2c684b73e8047a Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 09:33:35 -0700 Subject: [PATCH 11/18] add blurb --- .../NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst diff --git a/Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst b/Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst new file mode 100644 index 00000000000000..650e5f95f94567 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst @@ -0,0 +1 @@ +Fixed a crash when using asyncio and threads. From fa2b42b39e6a364c2592116968cc2a5ca07ef0f9 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 09:35:00 -0700 Subject: [PATCH 12/18] remove space --- Include/objimpl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Include/objimpl.h b/Include/objimpl.h index 4ac6b9e7a34548..746f9c921344f7 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -333,7 +333,6 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); #endif /* !Py_LIMITED_API */ PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); - PyAPI_FUNC(void) PyObject_GC_Track(void *); PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); PyAPI_FUNC(void) PyObject_GC_Del(void *); From 3ca521d13ce60403210b361c0de37712390ae757 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 09:39:21 -0700 Subject: [PATCH 13/18] revert --- Misc/NEWS | 2 -- 1 file changed, 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 43b7f3260131bf..38449c0409f458 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,8 +10,6 @@ What's New in Python 3.7.0 alpha 1? Core and Builtins ----------------- -- bpo-31061: Fixed a crash when using asyncio and threads. - - bpo-30814: Fixed a race condition when import a submodule from a package. - bpo-30736: The internal unicodedata database has been upgraded to Unicode From b0fb8e718df5d33f440c0106717bd98590b44447 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 10:32:36 -0700 Subject: [PATCH 14/18] new task test case --- Lib/test/test_asyncio/test_tasks.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 686387f4f21d85..dc8eaea87e6777 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -4,6 +4,7 @@ import contextlib import functools import io +import gc import os import re import sys @@ -91,6 +92,17 @@ def setUp(self): self.loop.set_task_factory(self.new_task) self.loop.create_future = lambda: self.new_future(self.loop) + def test_task_del_collect(self): + class Evil: + def __del__(self): + gc.collect() + + @asyncio.coroutine + def run(): + return Evil() + + yield from asyncio.gather(*[asyncio.Task(run()) for _ in range(100)]) + def test_other_loop_future(self): other_loop = asyncio.new_event_loop() fut = self.new_future(other_loop) From f32e94935cf9101c73bcbd90de80cc88125c5c3f Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 12:00:53 -0700 Subject: [PATCH 15/18] fix unittest --- Lib/test/test_asyncio/test_tasks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index dc8eaea87e6777..e32040728a3146 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -101,7 +101,9 @@ def __del__(self): def run(): return Evil() - yield from asyncio.gather(*[asyncio.Task(run()) for _ in range(100)]) + self.loop.run_until_complete( + asyncio.gather(*[ + self.new_task(self.loop, run()) for _ in range(100)])) def test_other_loop_future(self): other_loop = asyncio.new_event_loop() From 7bc0c2abb330d6e5c34374cc41307260486cbc6d Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 12:05:59 -0700 Subject: [PATCH 16/18] set the loop --- Lib/test/test_asyncio/test_tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index e32040728a3146..df39f8304c4a97 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -103,7 +103,8 @@ def run(): self.loop.run_until_complete( asyncio.gather(*[ - self.new_task(self.loop, run()) for _ in range(100)])) + self.new_task(self.loop, run()) for _ in range(100) + ]), loop=self.loop) def test_other_loop_future(self): other_loop = asyncio.new_event_loop() From 55a2eb5c0af242d7757bceefbb476e9a852d97dc Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 13:26:51 -0700 Subject: [PATCH 17/18] fix off by one paren error :) --- Lib/test/test_asyncio/test_tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index df39f8304c4a97..3e0f3fa53bd62e 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -104,7 +104,7 @@ def run(): self.loop.run_until_complete( asyncio.gather(*[ self.new_task(self.loop, run()) for _ in range(100) - ]), loop=self.loop) + ], loop=self.loop)) def test_other_loop_future(self): other_loop = asyncio.new_event_loop() From 3033b1504648ea85a667b01103ea31b8396033b8 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Tue, 1 Aug 2017 13:35:22 -0700 Subject: [PATCH 18/18] fix ordering --- Lib/test/test_asyncio/test_tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 3e0f3fa53bd62e..36082ec7c6a79a 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -3,8 +3,8 @@ import collections import contextlib import functools -import io import gc +import io import os import re import sys