Issue #27972: Prohibit Tasks to await on themselves.

This commit is contained in:
Yury Selivanov 2016-10-09 12:19:12 -04:00
parent 908d55dd7e
commit 4145c83806
3 changed files with 27 additions and 7 deletions

View File

@ -241,7 +241,7 @@ class Task(futures.Future):
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 @@ class Task(futures.Future):
'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,

View File

@ -92,6 +92,17 @@ class TaskTests(test_utils.TestCase):
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():

View File

@ -388,6 +388,8 @@ Library
- Issue #28399: Remove UNIX socket from FS before binding.
Patch by Коренберг Марк.
- Issue #27972: Prohibit Tasks to await on themselves.
IDLE
----