GH-90985: Revert "Deprecate passing a message into cancel()" (GH-97999)

Reason: we were too hasty in deprecating this.
We shouldn't deprecate it before we have a replacement.
(cherry picked from commit 09de8d7aaf)

Co-authored-by: Guido van Rossum <guido@python.org>
This commit is contained in:
Miss Islington (bot) 2022-10-06 18:50:25 -07:00 committed by GitHub
parent c9d0a7a6bc
commit d163d5976d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 12 additions and 102 deletions

View file

@ -197,11 +197,6 @@ Future Object
.. versionchanged:: 3.9 .. versionchanged:: 3.9
Added the *msg* parameter. Added the *msg* parameter.
.. deprecated-removed:: 3.11 3.14
*msg* parameter is ambiguous when multiple :meth:`cancel`
are called with different cancellation messages.
The argument will be removed.
.. method:: exception() .. method:: exception()
Return the exception that was set on this Future. Return the exception that was set on this Future.
@ -282,8 +277,3 @@ the Future has a result::
- :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument, - :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument,
but :func:`concurrent.futures.cancel` does not. but :func:`concurrent.futures.cancel` does not.
.. deprecated-removed:: 3.11 3.14
*msg* parameter is ambiguous when multiple :meth:`cancel`
are called with different cancellation messages.
The argument will be removed.

View file

@ -1137,10 +1137,8 @@ Task Object
.. versionchanged:: 3.9 .. versionchanged:: 3.9
Added the *msg* parameter. Added the *msg* parameter.
.. deprecated-removed:: 3.11 3.14 .. versionchanged:: 3.11
*msg* parameter is ambiguous when multiple :meth:`cancel` The ``msg`` parameter is propagated from cancelled task to its awaiter.
are called with different cancellation messages.
The argument will be removed.
.. _asyncio_example_task_cancel: .. _asyncio_example_task_cancel:

View file

@ -8,7 +8,6 @@ import concurrent.futures
import contextvars import contextvars
import logging import logging
import sys import sys
import warnings
from types import GenericAlias from types import GenericAlias
from . import base_futures from . import base_futures
@ -151,11 +150,6 @@ class Future:
change the future's state to cancelled, schedule the callbacks and change the future's state to cancelled, schedule the callbacks and
return True. 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 self.__log_traceback = False
if self._state != _PENDING: if self._state != _PENDING:
return False return False

View file

@ -207,11 +207,6 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
This also increases the task's count of cancellation requests. 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 self._log_traceback = False
if self.done(): if self.done():
return False return False

View file

@ -228,22 +228,14 @@ class BaseFutureTests:
self.assertTrue(hasattr(f, '_cancel_message')) self.assertTrue(hasattr(f, '_cancel_message'))
self.assertEqual(f._cancel_message, None) self.assertEqual(f._cancel_message, None)
with self.assertWarnsRegex( f.cancel('my message')
DeprecationWarning,
"Passing 'msg' argument"
):
f.cancel('my message')
with self.assertRaises(asyncio.CancelledError): with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(f) self.loop.run_until_complete(f)
self.assertEqual(f._cancel_message, 'my message') self.assertEqual(f._cancel_message, 'my message')
def test_future_cancel_message_setter(self): def test_future_cancel_message_setter(self):
f = self._new_future(loop=self.loop) f = self._new_future(loop=self.loop)
with self.assertWarnsRegex( f.cancel('my message')
DeprecationWarning,
"Passing 'msg' argument"
):
f.cancel('my message')
f._cancel_message = 'my new message' f._cancel_message = 'my new message'
self.assertEqual(f._cancel_message, 'my new message') self.assertEqual(f._cancel_message, 'my new message')

View file

@ -113,11 +113,7 @@ class BaseTaskTests:
self.assertTrue(hasattr(t, '_cancel_message')) self.assertTrue(hasattr(t, '_cancel_message'))
self.assertEqual(t._cancel_message, None) self.assertEqual(t._cancel_message, None)
with self.assertWarnsRegex( t.cancel('my message')
DeprecationWarning,
"Passing 'msg' argument"
):
t.cancel('my message')
self.assertEqual(t._cancel_message, 'my message') self.assertEqual(t._cancel_message, 'my message')
with self.assertRaises(asyncio.CancelledError) as cm: with self.assertRaises(asyncio.CancelledError) as cm:
@ -129,11 +125,7 @@ class BaseTaskTests:
async def coro(): async def coro():
pass pass
t = self.new_task(self.loop, coro()) t = self.new_task(self.loop, coro())
with self.assertWarnsRegex( t.cancel('my message')
DeprecationWarning,
"Passing 'msg' argument"
):
t.cancel('my message')
t._cancel_message = 'my new message' t._cancel_message = 'my new message'
self.assertEqual(t._cancel_message, 'my new message') self.assertEqual(t._cancel_message, 'my new message')
@ -710,14 +702,7 @@ class BaseTaskTests:
async def coro(): async def coro():
task = self.new_task(loop, sleep()) task = self.new_task(loop, sleep())
await asyncio.sleep(0) await asyncio.sleep(0)
if cancel_args not in ((), (None,)): task.cancel(*cancel_args)
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel(*cancel_args)
else:
task.cancel(*cancel_args)
done, pending = await asyncio.wait([task]) done, pending = await asyncio.wait([task])
task.result() task.result()
@ -751,14 +736,7 @@ class BaseTaskTests:
async def coro(): async def coro():
task = self.new_task(loop, sleep()) task = self.new_task(loop, sleep())
await asyncio.sleep(0) await asyncio.sleep(0)
if cancel_args not in ((), (None,)): task.cancel(*cancel_args)
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel(*cancel_args)
else:
task.cancel(*cancel_args)
done, pending = await asyncio.wait([task]) done, pending = await asyncio.wait([task])
task.exception() task.exception()
@ -781,17 +759,10 @@ class BaseTaskTests:
fut.set_result(None) fut.set_result(None)
await asyncio.sleep(10) await asyncio.sleep(10)
def cancel(task, msg):
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel(msg)
async def coro(): async def coro():
inner_task = self.new_task(loop, sleep()) inner_task = self.new_task(loop, sleep())
await fut await fut
loop.call_soon(cancel, inner_task, 'msg') loop.call_soon(inner_task.cancel, 'msg')
try: try:
await inner_task await inner_task
except asyncio.CancelledError as ex: except asyncio.CancelledError as ex:
@ -817,11 +788,7 @@ class BaseTaskTests:
async def coro(): async def coro():
task = self.new_task(loop, sleep()) task = self.new_task(loop, sleep())
# We deliberately leave out the sleep here. # We deliberately leave out the sleep here.
with self.assertWarnsRegex( task.cancel('my message')
DeprecationWarning,
"Passing 'msg' argument"
):
task.cancel('my message')
done, pending = await asyncio.wait([task]) done, pending = await asyncio.wait([task])
task.exception() task.exception()
@ -2183,14 +2150,7 @@ class BaseTaskTests:
async def main(): async def main():
qwe = self.new_task(loop, test()) qwe = self.new_task(loop, test())
await asyncio.sleep(0.2) await asyncio.sleep(0.2)
if cancel_args not in ((), (None,)): qwe.cancel(*cancel_args)
with self.assertWarnsRegex(
DeprecationWarning,
"Passing 'msg' argument"
):
qwe.cancel(*cancel_args)
else:
qwe.cancel(*cancel_args)
await qwe await qwe
try: try:

View file

@ -0,0 +1 @@
Earlier in 3.11 we deprecated ``asyncio.Task.cancel("message")``. We realized we were too harsh, and have undeprecated it.

View file

@ -1116,16 +1116,6 @@ static PyObject *
_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg) _asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg)
/*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/ /*[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) ENSURE_FUTURE_ALIVE(self)
return future_cancel(self, msg); return future_cancel(self, msg);
} }
@ -2206,16 +2196,6 @@ static PyObject *
_asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg)
/*[clinic end generated code: output=c66b60d41c74f9f1 input=7bb51bf25974c783]*/ /*[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; self->task_log_tb = 0;
if (self->task_state != STATE_PENDING) { if (self->task_state != STATE_PENDING) {