10BC0 bpo-46829: Deprecate passing a message into Future.cancel() and Task.cancel() by asvetlov · Pull Request #31840 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
bpo-46829: Deprecate passing a message into Future.cancel() and Task.…
…cancel()
  • Loading branch information
asvetlov committed Mar 12, 2022
commit 3923c11294f96c7694f5fa1ac07506fa0a2384c3
6 changes: 6 additions & 0 deletions Lib/asyncio/futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import contextvars
import logging
import sys
import warnings
from types import GenericAlias

from . import base_futures
Expand Down Expand Up @@ -153,6 +154,11 @@ def cancel(self, msg=None):
change the future's state to cancelled, schedule the callbacks and
return True.
"""
if msg is not None:
warnings.warn("Passing 'msg' argument to Future.cancel() "
"is deprecated since Python 3.11, and "
"scheduled for removal in Python 3.14.",
DeprecationWarning, stacklevel=2)
self.__log_traceback = False
if self._state != _PENDING:
return False
Expand Down
5 changes: 5 additions & 0 deletions Lib/asyncio/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ def cancel(self, msg=None):

This also increases the task's count of cancellation requests.
"""
if msg is not None:
warnings.warn("Passing 'msg' argument to Task.cancel() "
"is deprecated since Python 3.11, and "
"scheduled for removal in Python 3.14.",
DeprecationWarning, stacklevel=2)
self._log_traceback = False
if self.done():
return False
Expand Down
12 changes: 10 additions & 2 deletions Lib/test/test_asyncio/test_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,22 @@ def test_future_cancel_message_getter(self):
self.assertTrue(hasattr(f, '_cancel_message'))
self.assertEqual(f._cancel_message, None)

f.cancel('my message')
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
f.cancel('my message')
with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(f)
self.assertEqual(f._cancel_message, 'my message')

def test_future_cancel_message_setter(self):
f = self._new_future(loop=self.loop)
f.cancel('my message')
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
f.cancel('my message')
f._cancel_message = 'my new message'
self.assertEqual(f._cancel_message, 'my new message')

Expand Down
12 changes: 10 additions & 2 deletions Lib/test/test_asyncio/test_taskgroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,11 @@ async def runner():
await asyncio.sleep(0.1)

self.assertFalse(r.done())
r.cancel("test")
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
r.cancel("test")
with self.assertRaises(asyncio.CancelledError) as cm:
await r

Expand Down Expand Up @@ -252,7 +256,11 @@ async def runner():
await asyncio.sleep(0.1)

self.assertFalse(r.done())
r.cancel("test")
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
r.cancel("test")
with self.assertRaises(asyncio.CancelledError) as cm:
await r

Expand Down
54 changes: 47 additions & 7 deletions Lib/test/test_asyncio/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,11 @@ async def coro():
self.assertTrue(hasattr(t, '_cancel_message'))
self.assertEqual(t._cancel_message, None)

t.cancel('my message')
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
t.cancel('my message')
self.assertEqual(t._cancel_message, 'my message')

with self.assertRaises(asyncio.CancelledError) as cm:
Expand All @@ -133,7 +137,11 @@ def test_task_cancel_message_setter(self):
async def coro():
pass
t = self.new_task(self.loop, coro())
t.cancel('my message')
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
t.cancel('my message')
t._cancel_message = 'my new message'
self.assertEqual(t._cancel_message, 'my new message')

Expand Down Expand Up @@ -590,7 +598,14 @@ async def sleep():
async def coro():
task = self.new_task(loop, sleep())
await asyncio.sleep(0)
task.cancel(*cancel_args)
if cancel_args not in ((), (None,)):
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel(*cancel_args)
else:
task.cancel(*cancel_args)
done, pending = await asyncio.wait([task])
task.result()

Expand Down Expand Up @@ -624,7 +639,14 @@ async def sleep():
async def coro():
task = self.new_task(loop, sleep())
await asyncio.sleep(0)
task.cancel(*cancel_args)
if cancel_args not in ((), (None,)):
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel(*cancel_args)
else:
task.cancel(*cancel_args)
done, pending = await asyncio.wait([task])
task.exception()

Expand All @@ -647,10 +669,17 @@ async def sleep():
fut.set_result(None)
await asyncio.sleep(10)

def cancel(task, msg):
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel(msg)

async def coro():
inner_task = self.new_task(loop, sleep())
await fut
loop.call_soon(inner_task.cancel, 'msg')
loop.call_soon(cancel, inner_task, 'msg')
try:
await inner_task
except asyncio.CancelledError as ex:
Expand All @@ -676,7 +705,11 @@ async def sleep():
async def coro():
task = self.new_task(loop, sleep())
# We deliberately leave out the sleep here.
task.cancel('my message')
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel('my message')
done, pending = await asyncio.wait([task])
task.exception()

Expand Down Expand Up @@ -2326,7 +2359,14 @@ async def test():
async def main():
qwe = self.new_task(loop, test())
await asyncio.sleep(0.2)
qwe.cancel(*cancel_args)
if cancel_args not in ((), (None,)):
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
qwe.cancel(*cancel_args)
else:
qwe.cancel(*cancel_args)
await qwe

try:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Deprecate passing a message to :meth:`asyncio.Future.cancel` and
:meth:`asyncio.Task.cancel`
20 changes: 20 additions & 0 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,16 @@ static PyObject *
_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg)
/*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/
{
if (msg != Py_None) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"Passing 'msg' argument to Future.cancel() "
"is deprecated since Python 3.11, and "
"scheduled for removal in Python 3.14.",
2))
{
return NULL;
}
}
ENSURE_FUTURE_ALIVE(self)
return future_cancel(self, msg);
}
Expand Down Expand Up @@ -2199,6 +2209,16 @@ static PyObject *
_asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg)
/*[clinic end generated code: output=c66b60d41c74f9f1 input=7bb51bf25974c783]*/
{
if (msg != Py_None) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"Passing 'msg' argument to Task.cancel() "
"is deprecated since Python 3.11, and "
"scheduled for removal in Python 3.14.",
2))
{
return NULL;
}
}
self->task_log_tb = 0;

if (self->task_state != STATE_PENDING) {
Expand Down
0