[Python-checkins] cpython (merge 3.5 -> 3.6): Merge 3.5 (issue #27972)

yury.selivanov python-checkins at python.org
Sun Oct 9 12:21:24 EDT 2016


https://hg.python.org/cpython/rev/41c4f535b5c0
changeset:   104418:41c4f535b5c0
branch:      3.6
parent:      104415:019c5c2f1239
parent:      104417:8d877876aa89
user:        Yury Selivanov <yury at magic.io>
date:        Sun Oct 09 12:20:44 2016 -0400
summary:
  Merge 3.5 (issue #27972)

files:
  Lib/asyncio/tasks.py                |  21 +++++++++++-----
  Lib/test/test_asyncio/test_tasks.py |  11 ++++++++
  Misc/NEWS                           |   2 +
  3 files changed, 27 insertions(+), 7 deletions(-)


diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -241,7 +241,7 @@
                 result = coro.throw(exc)
         except StopIteration as exc:
             self.set_result(exc.value)
-        except futures.CancelledError as exc:
+        except futures.CancelledError:
             super().cancel()  # I.e., Future.cancel(self).
         except Exception as exc:
             self.set_exception(exc)
@@ -259,12 +259,19 @@
                             'Task {!r} got Future {!r} attached to a '
                             'different loop'.format(self, result)))
                 elif blocking:
-                    result._asyncio_future_blocking = False
-                    result.add_done_callback(self._wakeup)
-                    self._fut_waiter = result
-                    if self._must_cancel:
-                        if self._fut_waiter.cancel():
-                            self._must_cancel = False
+                    if result is self:
+                        self._loop.call_soon(
+                            self._step,
+                            RuntimeError(
+                                'Task cannot await on itself: {!r}'.format(
+                                    self)))
+                    else:
+                        result._asyncio_future_blocking = False
+                        result.add_done_callback(self._wakeup)
+                        self._fut_waiter = result
+                        if self._must_cancel:
+                            if self._fut_waiter.cancel():
+                                self._must_cancel = False
                 else:
                     self._loop.call_soon(
                         self._step,
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -92,6 +92,17 @@
         finally:
             other_loop.close()
 
+    def test_task_awaits_on_itself(self):
+        @asyncio.coroutine
+        def test():
+            yield from task
+
+        task = asyncio.ensure_future(test(), loop=self.loop)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'Task cannot await on itself'):
+            self.loop.run_until_complete(task)
+
     def test_task_class(self):
         @asyncio.coroutine
         def notmuch():
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -219,6 +219,8 @@
 - Issue #28399: Remove UNIX socket from FS before binding.
   Patch by Коренберг Марк.
 
+- Issue #27972: Prohibit Tasks to await on themselves.
+
 Windows
 -------
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list