Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Commit e3fed68

Browse files
committed
Prohibit Tasks to await on themselves.
1 parent d83ef7f commit e3fed68

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

asyncio/tasks.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ def _step(self, exc=None):
241241
result = coro.throw(exc)
242242
except StopIteration as exc:
243243
self.set_result(exc.value)
244-
except futures.CancelledError as exc:
244+
except futures.CancelledError:
245245
super().cancel() # I.e., Future.cancel(self).
246246
except Exception as exc:
247247
self.set_exception(exc)
@@ -259,12 +259,19 @@ def _step(self, exc=None):
259259
'Task {!r} got Future {!r} attached to a '
260260
'different loop'.format(self, result)))
261261
elif blocking:
262-
result._asyncio_future_blocking = False
263-
result.add_done_callback(self._wakeup)
264-
self._fut_waiter = result
265-
if self._must_cancel:
266-
if self._fut_waiter.cancel():
267-
self._must_cancel = False
262+
if result is self:
263+
self._loop.call_soon(
264+
self._step,
265+
RuntimeError(
266+
'Task cannot await on itself: {!r}'.format(
267+
self)))
268+
else:
269+
result._asyncio_future_blocking = False
270+
result.add_done_callback(self._wakeup)
271+
self._fut_waiter = result
272+
if self._must_cancel:
273+
if self._fut_waiter.cancel():
274+
self._must_cancel = False
268275
else:
269276
self._loop.call_soon(
270277
self._step,

tests/test_tasks.py

+11
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ def run(fut):
9292
finally:
9393
other_loop.close()
9494

95+
def test_task_awaits_on_itself(self):
96+
@asyncio.coroutine
97+
def test():
98+
yield from task
99+
100+
task = asyncio.ensure_future(test(), loop=self.loop)
101+
102+
with self.assertRaisesRegex(RuntimeError,
103+
'Task cannot await on itself'):
104+
self.loop.run_until_complete(task)
105+
95106
def test_task_class(self):
96107
@asyncio.coroutine
97108
def notmuch():

0 commit comments

Comments
 (0)